File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/static/KRSK_WorkSheets/js/create_vacancy.js"
```
// window.addEventListener('DOMContentLoaded', function() {
//     const create_form_button = document.getElementById('create_form_button');
//     create_form_button.addEventListener('click', count_cash_input) });


var WORKERS;
var SHOPS;
var GROUPS;


window.addEventListener('DOMContentLoaded', function() {
    let get_workers_promise = get_data(URL_GET_WORKERS, function(data) {WORKERS = data}, function(){alert('ERROR GET WORKERS')});
    let get_groups_promise  = get_data(URL_GET_GROUPS,  function(data) {GROUPS = data; createSelectingNumberOfEmployers(data);}, function(){alert('ERROR GET GROUPS'  )});
    Promise.all([get_workers_promise, get_groups_promise]).then(() => {
        if (!GROUPS.includes("Администраторы сети Командор")) { get_data(URL_GET_SHOPS,function(data) {appendShops(data)}, function(){alert('ERROR GET SHOPS'  )});}}).catch(error => {console.error("Error in afterLoadHTML promises:", error);});})


function appendShops(shops_list) {
    SHOPS = shops_list;
    document.getElementById("shop_block").removeAttribute("hidden");
    let shop_select = document.getElementById("shop_select");
    shop_select.innerHTML = '<option value="">Выберите магазин</option>';
    for (let shop of shops_list) {
        let o = document.createElement('option');
        [o.value, o.innerText] = [shop[0], shop[0]];
        shop_select.appendChild(o);}}


function showTypeOfWorkBlock() {
    document.getElementById('type_of_work_block').hidden = false;
    document.getElementById('send_button'       ).hidden = false;}


function createBlock(count_input) {
    let num_cash = Number(count_input.value);
    let type_of_work = count_input.dataset.type;
    let type_of_work_label;
    switch (type_of_work) {
        case 'cash'               : type_of_work_label = 'Касса ';                      break;
        case 'spreader'           : type_of_work_label = 'Выкладка ';                   break;
        case 'loader'             : type_of_work_label = 'Грузчик ' ;                   break;
        case 'departament_worker' : type_of_work_label = 'Гастроном ';                  break;
        case 'foreman'            : type_of_work_label = 'Бригадир ';                   break;    
        case 'mobile_cash'        : type_of_work_label = 'Мобильный продавец ';           break;
        case 'mobile_loader'      : type_of_work_label = 'Мобильный грузчик ';          break;
        
        case 'security_service'   : type_of_work_label = 'Менеджер Службы Контроля ';   break;
        case 'cart_assembler'     : type_of_work_label = 'Сборщик тележек ';            break;
        
        case 'universal_cash'     : type_of_work_label = 'Продавец-Универсал ';         break;
}

    for (let count = 1; count < num_cash + 1; count++) {
        let start_work_time_field = document.createElement("input");
            start_work_time_field.setAttribute("type", "time");
            start_work_time_field.classList.add('inputWorkerCellShort', 'start_work_time_field')
        let start_work_time_div = document.createElement('div');
            start_work_time_div.classList.add('start_work_time', 'divWorkerCellShort', 'col-2');
            start_work_time_div.appendChild(start_work_time_field);

        let end_work_time_field = document.createElement("input");
            end_work_time_field.setAttribute("type", "time");
            end_work_time_field.classList.add('inputWorkerCellShort', 'end_work_time_field')
        let end_work_time_div = document.createElement('div');
            end_work_time_div.classList.add('end_work_time', 'divWorkerCellShort', 'col-2');
            end_work_time_div.appendChild(end_work_time_field);

        let tab_no_select = document.createElement("input"); // FIXME
            // FIXME TYPE AND MIN\MAX
            tab_no_select.classList.add('inputWorkerCellShort', 'start_work_time_field')
            tab_no_select.addEventListener('change', function() {showWorkerName(this)})
        let tab_no_select_div = document.createElement('div');
            tab_no_select_div.classList.add('tab_no_select', 'divWorkerCellShort', 'col-2');
            tab_no_select_div.appendChild(tab_no_select);

        let note_field =    document.createElement("input");
            note_field.classList.add('inputWorkerCellLong', 'note_field')
        let note_field_div = document.createElement('div');
            note_field_div.classList.add('tab_no_select', 'divWorkerCellLong', 'col-6');
            note_field_div.appendChild(note_field);

        let input_div = document.createElement('div');
            input_div.classList.add('row')
            input_div.dataset.type  = type_of_work;    
            input_div.dataset.count = count; //FIXME
            input_div.appendChild(start_work_time_div);
            input_div.appendChild(  end_work_time_div);
            input_div.appendChild(tab_no_select_div);
            input_div.appendChild(note_field_div);

        let head = document.createElement('div');
        let titleH4 = `<h4 class="workerTitle">` + type_of_work_label + count + `</h4>`; //FIXME
        let workerRow = `
            <div class="workerRow worker row">
                <div class="divWorkerCellShort col-2">Время начала работы</div>
                <div class="divWorkerCellShort col-2">Время конца работы</div>
                <div class="divWorkerCellShort col-2">Табельный номер</div>
                <div class="divWorkerCellLong col-6">Уточнение по видам работ</div>
            </div>`
        head.innerHTML = titleH4 + '\n' + workerRow; // FIXME

        let form = document.createElement('form');
        form.classList.add('worker_form')
        form.name = type_of_work_label + count; // FIXME
        form.appendChild(head);
        form.appendChild(input_div);

        let block = document.getElementById('dynamicWorker');
        block.classList.add('container')
        block.appendChild(form);    }
    count_input.disabled = true;}


function send_all_data() {
    let forms = document.querySelectorAll('form.worker_form');
    let date = document.getElementById('date_input').value;
    for (let i = 0; i < forms.length; i++) {
        let payload = { 'date'  : date,
                        'type'  : forms[i].elements[0].parentElement.parentElement.dataset.type,
                        'start' : forms[i].elements[0].value,
                          'end' : forms[i].elements[1].value,
                        'worker': forms[i].elements[2].value,
                        'note'  : forms[i].elements[3].value};
        if (!GROUPS.includes("Администраторы сети Командор")) { // FIXME BAD CODE
            let shop_select = document.getElementById("shop_select");
            payload['shop'] = shop_select.options[shop_select.selectedIndex].value;}
        send_data(URL_SEND_APP, payload, drawVacancy, forms[i]);    }
    document.getElementById('send_button').setAttribute('disabled', "disabled");}


function drawVacancy(data, form) {
    if (data['message'] == 'Success') { form.classList.add('verifed'); }
    else                              { form.classList.add('error');   }
    if (data['show_message']) alert(data['show_message']);}


function showWorkerName(html_element) {
    let worker_id = html_element.value;
    // console.log(WORKERS[worker_id])
    let full_name_worker_label;
    if (html_element.parentElement.querySelector('div.worker_name_label')) {
            full_name_worker_label = html_element.parentElement.querySelector('div.worker_name_label');}
    else {  full_name_worker_label = document.createElement('div');
            html_element.parentElement.appendChild(full_name_worker_label);}
    full_name_worker_label.classList.add('worker_name_label');
    full_name_worker_label.innerText = (WORKERS[worker_id]) ? (WORKERS[worker_id][2]) ? "УВОЛЕН" : WORKERS[worker_id][0] : "Нет в базе";}


function createSelectingNumberOfEmployers(departament) {
    const root_div = document.querySelector('#type_of_work_block');
    if (  departament.includes('Отдел обслуживания')) { root_div.innerHTML = DEPARTAMENT_SERVICE_SELECTING_NUMBER_OF_EMPLOYERS_HTML;   }
    if (  departament.includes('Служба Контроля'))    { root_div.innerHTML =    SECURITY_SERVICE_SELECTING_NUMBER_OF_EMPLOYERS_HTML;   } 
    if (  departament.includes('Разгуляй'))           { root_div.innerHTML =    RAZGULAY_SELECTING_NUMBER_OF_EMPLOYERS_HTML;   }   }


DEPARTAMENT_SERVICE_SELECTING_NUMBER_OF_EMPLOYERS_HTML = `
        <div class="changeWorkersLabelRow row">
            <div class="changeWorkersCell changeWorkerLabel col">Касса кол-во</div>
            <div class="changeWorkersCell changeWorkerLabel col">Выкладка кол-во</div>
            <div class="changeWorkersCell changeWorkerLabel col">Грузчик кол-во</div>
            <div class="changeWorkersCell changeWorkerLabel col">Гастроном кол-во</div>
            <div class="changeWorkersCell changeWorkerLabel col">Бригадир кол-во</div>
            <div class="changeWorkersCell changeWorkerLabel col">Мобильный продавец кол-во</div>
            <div class="changeWorkersCell changeWorkerLabel col">Мобильный грузчик кол-во</div>
        </div>
        <div class="changeWorkersoptionRow row">
            <div class="changeWorkersCell col">
                <input type="text" name="numberCash" id="numberCash" data-type="cash"
                class="numberCash changeWorkersInput"
                onchange="createBlock(this);" 
                min="0" step="1" value="0" pattern="^[0-9]+$" required>
<!--                <option class="btn btn-primary changeWorkerBtn" type="button" value="ok">-->
            </div>
            <div class="changeWorkersCell col">
                <input type="text" name="numberSpreader" id="numberSpreader" data-type="spreader"
                class="numberSpreader changeWorkersInput"
                onchange="createBlock(this);" 
                min="0" step="1" value="0" pattern="^[0-9]+$" required>
<!--                <input class="btn btn-primary changeWorkerBtn" type="button" value="ok">-->
            </div>
            <div class="changeWorkersCell col">
                <input type="text" name="numberLoader" id="numberLoader" data-type="loader"
                class="numberLoader changeWorkersInput"
                onchange="createBlock(this);" 
                min="0" step="1" value="0" pattern="^[0-9]+$" required>
<!--                <input type="button" class="btn btn-primary changeWorkerBtn" value="ok">-->
            </div>
            <div class="changeWorkersCell col">
                <input type="text" name="numberDepartamentWorker" id="numberDepartamentWorker" data-type="departament_worker"
                class="numberDepartamentWorker changeWorkersInput"
                onchange="createBlock(this);" 
                min="0" step="1" value="0" pattern="^[0-9]+$" required>
<!--                <input type="button" class="btn btn-primary changeWorkerBtn" value="ok">-->
            </div>
            <div class="changeWorkersCell col">
                <input type="text" name="numberForeman" id="numberForeman" data-type="foreman"
                class="numberForeman changeWorkersInput"
                onchange="createBlock(this);" 
                min="0" step="1" value="0" pattern="^[0-9]+$" required>
<!--                <input type="button" class="btn btn-primary changeWorkerBtn" value="ok">-->
            </div>
            <div class="changeWorkersCell col">
                <input type="text" name="numberMobileCash" id="numberMobileCash" data-type="mobile_cash"
                class="numberMobileCash changeWorkersInput"
                onchange="createBlock(this);" 
                min="0" step="1" value="0" pattern="^[0-9]+$" required>
<!--                <input type="button" class="btn btn-primary changeWorkerBtn" value="ok">-->
            </div>
            <div class="changeWorkersCell col">
                <input type="text" name="numberMobileLoader" id="numberMobileLoader" data-type="mobile_loader"
                class="numberMobileWorker changeWorkersInput"
                onchange="createBlock(this);" 
                min="0" step="1" value="0" pattern="^[0-9]+$" required>
<!--                <input type="button" class="btn btn-primary changeWorkerBtn" value="ok">-->
            </div>
        </div>
        <div class="changeWorkersButtonRow row">
            <div class="col-12 dChangeWorkerBtn">
                <input type="button" class="btn btn-primary bChangeWorkerBtn" value="Ok" id="create_form_button">
            </div>
        </div>`

SECURITY_SERVICE_SELECTING_NUMBER_OF_EMPLOYERS_HTML = `
        <div class="changeWorkersLabelRow row">
            <div class="changeWorkersCell changeWorkerLabel col">Менеджер Службы Контроля</div>
            <div class="changeWorkersCell changeWorkerLabel col">Сборщик тележек</div>
        </div>
        <div class="changeWorkersoptionRow row">
            <div class="changeWorkersCell col">
                <input type="text" name="security_service" id="security_service" data-type="security_service"
                class="security_service changeWorkersInput"
                onchange="createBlock(this);" 
                min="0" step="1" value="0" pattern="^[0-9]+$" required>
<!--                <option class="btn btn-primary changeWorkerBtn" type="button" value="ok" id="buttonCash">-->
            </div>
            <div class="changeWorkersCell col">
                <input type="text" name="cart_assembler" id="cart_assembler" data-type="cart_assembler"
                class="cart_assembler changeWorkersInput"
                onchange="createBlock(this);" 
                min="0" step="1" value="0" pattern="^[0-9]+$" required>
<!--                <input class="btn btn-primary changeWorkerBtn" type="button" value="ok" id="buttonSpreader">-->
            </div>
        </div>
        <div class="changeWorkersButtonRow row">
            <div class="col-12 dChangeWorkerBtn">
                <input type="button" class="btn btn-primary bChangeWorkerBtn" value="Ok" id="create_form_button">
            </div>
        </div>`

RAZGULAY_SELECTING_NUMBER_OF_EMPLOYERS_HTML = `
        <div class="changeWorkersLabelRow row">
            <div class="changeWorkersCell changeWorkerLabel col">Продавец-Универсал</div>
        </div>
        <div class="changeWorkersoptionRow row">
            <div class="changeWorkersCell col">
                <input type="text" name="universal_cash" id="universal_cash" data-type="universal_cash"
                class="universal_cash changeWorkersInput"
                onchange="createBlock(this);" 
                min="0" step="1" value="0" pattern="^[0-9]+$" required>
<!--                <option class="btn btn-primary changeWorkerBtn" type="button" value="ok" id="universal_cash">-->
            </div>
        </div>
        <div class="changeWorkersButtonRow row">
            <div class="col-12 dChangeWorkerBtn">
                <input type="button" class="btn btn-primary bChangeWorkerBtn" value="Ok" id="create_form_button">
            </div>
        </div>`
```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/static/KRSK_WorkSheets/js/FF_LUVR.js"
```
// var ROLE          = [];
let ROLES = []; 
let SR_MANAGER = false;
let SSR_MANAGER = false;
let KO_ANALYST = false;
let KO_MANAGER = false;
let SELL_SERVICE = false;
let SECURITY_SERVICE = false;
let RAZGULAY = false;
let WORKERS;
let READY = {"WORKERS": false, "HEAD": false, "TIMER_HANDLER": null}; 
let OPTIONS_LOCAL_DATETIME = {  year: 'numeric',
								month: 'long',
								day: 'numeric',
								timezone: 'GMT+7',
								hour: 'numeric',
								minute: 'numeric',
								second: 'numeric',};
let OPTIONS_LOCAL_DATE = {  year: 'numeric',
							month: 'long',
							day: 'numeric',
							timezone: 'GMT+7',};


window.addEventListener('DOMContentLoaded', function() {
	let get_workers_promise = get_data(URL_GET_WORKERS, function(data) {WORKERS = data; READY['WORKERS'] = true;}, function(){alert('НЕ УДАЛОСЬ ПОЛУЧИТЬ АКТУАЛЬНЫЙ СПИСОК СОТРУДНИКОВ\nПерезагрузите страницу')});
	let get_head_promise = send_data(URL_GET_HEAD, {'status': 'START'}, createHead, function(error) {alert(error)});
	Promise.all([get_workers_promise, get_head_promise]).then(() => {
		getTestTable(getExcel = false, reset_filter = 'OLD',);}).catch(error => {console.error("Error in afterLoadHTML promises:", error);});	});





```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/static/KRSK_WorkSheets/js/FF_LUVR_Filter_Block.js"
```
// ""  NEED USE STRICT

function TEST_getFilterData() {
    let FILTERS_DATA = {};
    let filters_block_list = document.querySelectorAll('.filter_block');
    for (let i = 0; i < filters_block_list.length; i++) {
        let column_name = filters_block_list[i].dataset.filter_block;
        let select = filters_block_list[i].querySelector('div.filter_select'); 
        let checked_options = select.querySelectorAll('input[type="checkbox"]:checked');
        if (!(  checked_options.length == 0 || checked_options.length == select.children.length)) {
            FILTERS_DATA[column_name] = [];
            checked_options.forEach(input => {FILTERS_DATA[column_name].push((input.value !== '' ? input.value : 'null'));});}  }
    FILTERS_DATA['shop_code__shop_region__id'] = getLocations();
    select_quantium_wave_worker = document.getElementById('select_quantuim_worker');
    if (SR_MANAGER) {
    FILTERS_DATA["quantium_wave_worker"] = [];
    for (let j = select_quantium_wave_worker.selectedOptions.length - 1; j >= 0; j--) {
            FILTERS_DATA["quantium_wave_worker"].push(select_quantium_wave_worker.selectedOptions[j].value);}  }   
    return FILTERS_DATA}


function createSortAndFilterBlock(filter_data, block_id, sort_func) {
    // let start_perf_time = new Date();
    let block_div = document.createElement('div');
        block_div.dataset.filter_block = block_id; 
        block_div.classList.add('filter_block', 'hidden_filter_block');

    let sort_div = document.createElement('div');
        sort_div.classList.add('sort');
    let sort_up_button   = document.createElement('button');
        sort_up_button.innerText = 'Сортировать А..Я';
        sort_up_button.classList.add('btn', 'btn-outline-primary');
        sort_up_button.dataset.sort_field = block_id;
        sort_up_button.dataset.sortDirection = '';
        sort_up_button.addEventListener('click', sort_func);
    let sort_down_button = document.createElement('button');
        sort_down_button.innerText = 'Сортировать Я..А';
        sort_down_button.classList.add('btn', 'btn-outline-primary');
        sort_down_button.dataset.sort_field = block_id;
        sort_down_button.dataset.sortDirection = '-';
        sort_down_button.addEventListener('click', sort_func);
        sort_div.appendChild(sort_up_button);
        sort_div.appendChild(sort_down_button);

    let filter_div = document.createElement('div');
        filter_div.classList.add('filter');

    let [check_all_button, uncheck_all_button] = [document.createElement('button'), document.createElement('button')];
        [check_all_button.innerText, uncheck_all_button.innerText] = ['Выбрать все', 'Отменить все'];
        [check_all_button.dataset.check_all_action, uncheck_all_button.dataset.check_all_action] = ['CHECK', 'UNCHECK'];
          check_all_button.addEventListener('click', function() {checkAllOptions(this);});
        uncheck_all_button.addEventListener('click', function() {checkAllOptions(this);});
        filter_div.appendChild(check_all_button);
        filter_div.appendChild(uncheck_all_button);

    let filter_select = document.createElement('div');
        filter_select.classList.add('filter_select', block_id);
        filter_select.id = `filter_select_${block_id}`;
    let filter_input_for_select = document.createElement("input");
        filter_input_for_select.addEventListener('input', function(){hideInappropriateOptions(this);} );
        [filter_input_for_select.id, filter_input_for_select.list] = [`filter_input_for_select_${block_id}`, filter_select.id];

    if (filter_data) {
        for (let i = 0; i < filter_data.length; i++) {
            let checked;
            if (OLD_SORT_AND_FILTER_DATA['filter'][block_id] !== undefined) {checked = (OLD_SORT_AND_FILTER_DATA['filter'][block_id].includes(filter_data[i])) ? 'checked' : null; } 
            else {checked = 'checked';}
            let filter_option_div = document.createElement('div');
                filter_option_div.classList.add('filter_option');
            let filter_option_input = document.createElement('input');
                [filter_option_input.type, filter_option_input.value, filter_option_input.checked, ] = 
                ["checkbox",               filter_data[i],            checked,                     ];
            let filter_option_label = document.createElement('label');
                filter_option_label.innerText = (filter_data[i] !== null) ? filter_data[i] : "Пусто";

            filter_option_div.appendChild(filter_option_input);
            filter_option_div.appendChild(filter_option_label);
            filter_select.appendChild(filter_option_div);

            // filter_select.innerHTML += `<div class="filter_option"><input type="checkbox" value="${filter_data[i]}" ${checked}  />${(filter_data[i] !== null) ? filter_data[i] : "Пусто"}</div>`;
            }    }


    let get_table_button = document.createElement('button');
        get_table_button.classList.add('filter_button');
        get_table_button.innerText = 'Показать';
        get_table_button.addEventListener('click', function() {getTestTable(getExcel = false, reset_filter = 'SAVE',)});

    filter_div.appendChild(filter_select);
    filter_div.appendChild(filter_input_for_select);

    block_div.appendChild(sort_div);
    block_div.appendChild(filter_div);
    block_div.appendChild(get_table_button);
    // console.log(`${block_id} = ${new Date() - start_perf_time}ms`);
    return block_div;}


function isFieldInSort(button) {
    let butt_field = button.dataset.sort_field;
    // console.log('butt_field')
    // console.log(butt_field)
    let butt_direction = button.dataset.sortDirection;
    let position = Math.max(PRIORITY_SORT.indexOf(butt_field), PRIORITY_SORT.indexOf(`-${butt_field}`))
    if (position > -1 ) {
        let sort_field = (PRIORITY_SORT[position][0] == '-') ? PRIORITY_SORT[position].slice(0,1) : PRIORITY_SORT[position];
        let sort_direction = (PRIORITY_SORT[position][0] == '-') ? '-' : '';
        // console.log(`butt_direction = '${butt_direction}'  ||  sort_direction = '${sort_direction}'`);
        if (sort_direction === butt_direction) { // IF sort in sort_list THEN remove THIS sort
            deactivateAllSortButtonInFilterBlock(button); 
            // console.log(`Exist in sort: position = ${position}`);
            PRIORITY_SORT.splice(position, 1); }
        else { // IF reversed sort in sort list THEN change THIS sort
            deactivateAllSortButtonInFilterBlock(button); 
            if (sort_direction == '-') {
                PRIORITY_SORT[position] = butt_field;       
                // console.log('Second Thread');
                activateSortButton(button.parentElement.children[0]); }
            else                       {
            PRIORITY_SORT[position] = `-${butt_field}`; 
            // console.log('Third Thread');
            activateSortButton(button.parentElement.children[1]); }}}
    else {
        PRIORITY_SORT.push(butt_direction + butt_field); 
        deactivateAllSortButtonInFilterBlock(button); 
        // console.log('fourth Thread');
        activateSortButton(button); }    }


function head_cell_func_onClick() {     isFieldInSort(this);} // FIXME!!!!


function activateSortButton(button) {
    button.classList.remove('btn-outline-primary');
    button.classList.add('btn-primary');}


function deactivateAllSortButtonInFilterBlock(button) { 
    button.parentElement.children[0].classList.add('btn-outline-primary');
    button.parentElement.children[1].classList.add('btn-outline-primary');
    button.parentElement.children[0].classList.remove('btn-primary');
    button.parentElement.children[1].classList.remove('btn-primary');}


function resetFilterAndSort() {
    let filters_block_list = document.querySelectorAll('.filter_block');
    for (filter_block of filters_block_list) {
        deactivateAllSortButtonInFilterBlock(filter_block.querySelector('div.sort > button'));
        checkAllOptions(filter_block.querySelector('button[data-check_all_action="CHECK"]'));    }
    PRIORITY_SORT = [];}


function getLocations() {
    let locations = [];
    let locations_select = document.getElementById('locations_select');
    if (!locations_select || locations_select.options.length == locations_select.selectedOptions.length || locations_select.selectedOptions.length == 0) return undefined;
    for (let i of locations_select.selectedOptions) { locations.push(i.value); }
    return locations }


function hideInappropriateOptions(input) {
    let options_list = input.parentElement.querySelectorAll('div.filter_select input[type="checkbox"]');
    // console.log(options_list);
    // const filterValue = filterInput.value.toLowerCase();
    for (let option of options_list)  {
        if (option.value.toLowerCase().includes(input.value.toLowerCase())) { option.parentElement.style.display = ''; } else { option.parentElement.style.display = 'none';}}}


function checkAllOptions(button) {
    let filter_select = button.parentElement.querySelector('div.filter_select');
    for (let option of filter_select.querySelectorAll('input')) { option.checked = (button.dataset.check_all_action === 'CHECK') ? true : false; }}
```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/static/KRSK_WorkSheets/js/FF_LUVR_Send_Functions.js"
```
function getTestTable(getExcel = false, reset_filter = 'OLD', ) {
    let body = document.querySelector('body');
    body.classList.add('working');
    window.loading_page.showModal();
    let filters = (reset_filter === 'RESET') ? {} : TEST_getFilterData();
    payload = {'filters': filters, 'sorts': PRIORITY_SORT, 'getExcel': getExcel, 'reset_filter': reset_filter};
    // console.log(payload);
    const handleSuccess = (response) => {drawTable(response);body.classList.remove('working');window.loading_page.close();};
    if (getExcel !== false)   {send_data_return_file(URL_GET_TABLE, payload) } 
    else                      {send_data(            URL_GET_TABLE, payload, handleSuccess, );                               }    }


function changeWorkDate(html_element) {
    let tr = findRow(html_element);
    payload = { "payload" : {   "worksheet_id": tr.dataset.rowid,
                                "work_date": html_element.value},
                "action": "CHANGE_WORKSHEET_WORK_DATE" }
    send_data(CHANGE_FIELD, payload, drawIfSucsessElseAlert , html_element);}


function changeWorksheetWorkerId(html_element) {
    let tr = findRow(html_element);
    let row_in_TABLE;
    for (let row in TABLE) {if (Number(TABLE[row][0]) === Number(tr.dataset.rowid)) {row_in_TABLE = row;}}  // PLEASE FIX ME!!!
    payload = { "payload" : {   "worksheet_id" : tr.dataset.rowid,
                                "old_worker_id": TABLE[row_in_TABLE][10],
                                "worker_id"    : html_element.value},
                "action": "CHANGE_WORKSHEET_WORKER_ID" }
    send_data(CHANGE_FIELD, payload, drawIfSucsessElseAlert, html_element);}


function drawIfSucsessElseAlert(response, html_element) {
    if (response['message'] == 'Success') { html_element.classList.add("sr_note_append");
                                            html_element.disabled = true;
                                            let tr = findRow(html_element);
                                            tr.classList.add('confirmed')
                                            change_worker_modal.close();}
    else {alert(response['show_message'])}
}


function changeTypeOfWork(html_element) {
    let tr = findRow(html_element);
    payload = { "payload" : {   "worksheet_id": tr.dataset.rowid,
                                "type_of_work": html_element.selectedOptions[0].value},
                "action": "CHANGE_TYPE_OF_WORK" }
    send_data(CHANGE_TYPE_OF_WORK_URL, payload, drawKomandorsNote, html_element);}



function changeKomandorsNote(html_element) {
    // without check old value!!!
    let payload = {"worksheet_id"  : html_element.parentElement.parentElement.dataset.rowid,
                   "note"          : html_element.value};
    send_data(CHANGE_KOMANDORs_NOTE_URL, payload, drawKomandorsNote, html_element);}


function drawKomandorsNote(response, html_element) {
    if (response['message'] == 'Success') {html_element.classList.add("sr_note_append");}}


function changeSRNote(html_element) {
    // without check old value!!!
    let payload = {"worksheet_id"  : html_element.parentElement.parentElement.dataset.rowid,
                   "note"          : html_element.value};
    send_data(CHANGE_SR_NOTE_URL, payload, drawKomandorsNote, html_element);}


function changeCancelApp(html_element) {
    let tr = findRow(html_element);
    // without check old value!!!
    let payload = {"worksheet_id"  : tr.dataset.rowid,
                   "is_cancel"     : (tr.cells[19].firstElementChild === null) ? true : tr.cells[19].firstElementChild.checked,};
    send_data(CHANGE_CANCEL_APP_URL, payload, drawCancelApp, html_element);}


function drawCancelApp(response, html_element) {
    switch (response['message']) {
        case 'Success':
            {let tr = findRow(html_element);
            tr.classList.add("canceled"); // FIXME CANCEL APP!!!
            blockRow(tr);                                break;}
        case 'SHOW_MESSAGE':
            {alert(response['show_message']);            break;}
        default:
            alert( "Неизвестная ошибка" );               break;}}


function sendTimesheet(html_element) {
    // html element can be send_luvr_button or is_worker_skip_work_button
	let tr = findRow(html_element);
    let worker_id = tr.cells[10].firstElementChild.value;
    if (!WORKERS[worker_id]) {alert("ВВЕДИТЕ ВЕРНЫЙ ТАБЕЛЬНЫЙ НОМЕР!"); return}
    if (tr.cells[16].firstElementChild.checked) {
            let payload = {"worksheet_id"        : tr.dataset.rowid,
                           "worker_id"           : tr.cells[10].firstElementChild.value,
                           "is_worker_skip_work" : tr.cells[16].firstElementChild.checked};
            send_data(CHANGE_WORKER_SKIP_WORK_URL, payload, drawTimeSheet, html_element);} 
    else {  
    if (tr.cells[15].firstElementChild.selectedOptions[0].value === '') {alert("Выберите оценку!"); return}
        let [shh, smm] = tr.cells[11].firstElementChild.value.match(/\d\d/g);
        let sms = shh * 3600000 + smm * 60000;          
        let [ehh, emm] = tr.cells[12].firstElementChild.value.match(/\d\d/g);
        let ems = ehh * 3600000 + emm * 60000;
        let payload = { "worksheet_id"  : tr.dataset.rowid,
                            "worker_id"     : tr.cells[10].firstElementChild.value,
                            "startTime"     : sms,
                              "endTime"     : ems,
                            "grade"         : tr.cells[15].firstElementChild.selectedOptions[0].value, 
                            "is_worker_skip_work" : tr.cells[16].firstElementChild.checked,};  // FIXME GRADE!!!
        send_data(SEND_TIMESHEET_URL, payload, drawTimeSheet, html_element);}}


function drawTimeSheet(response, html_element) {
    // console.log(`response['message'] = ${response['message']}`)
    switch (response['message']) {
        case 'Success':
            // FIXME NEED CHECK THAT WORKER SKIP WORK, COLORIZE ROW IN RED AND CLOSE MODAL!!!
            {html_element.parentElement.parentElement.classList.add("sr_note_append");
            blockRow(html_element);                          break;}
        case 'BAD_TIME':
            alert( 'НЕ ВРЕМЯ!!!' );                          break;
        case 'AFTER_RECONCILIATION_ERROR':
            alert( response['show_message'] );               break;
        case 'DB_EROOR':
            alert( 'НЕ СОХРАНЯТЬ!' );                        break;
        case 'DUPPLICATE':
            alert( response['show_message'] );               break;
        default:
            alert( "НЕ ПОНИМАЮ, КАК? КАК ТАКОЕ ВОЗМОЖНО?" ); break;}}


// function changeWorkerSkipWork(html_element) {
// 	let tr = findRow(html_element);
//     let worker_id = tr.cells[10].firstElementChild.value;
//     if (!workers[worker_id]) {alert("ВВЕДИТЕ ТАБЕЛЬНЫЙ НОМЕР!"); return}
//     let payload = {"worksheet_id"     : html_element.parentElement.parentElement.dataset.rowid,
//                    "worker_id"        : html_element.parentElement.parentElement.cells[10].firstElementChild.value,
//                    "worker_skip_work" : html_element.checked};
//                    console.log('SEND CHANGE_WORKER_SKIP_WORK_URL')
//     send_data(CHANGE_WORKER_SKIP_WORK_URL, payload, drawWorkerSkipWork, html_element);}


function drawWorkerSkipWork(response, html_element) {
    // console.log('DRAW is_worker_skip_work')
    if (response['message'] == 'Success') { send_worker_skip_work_modal.close();
                                            findRow(html_element).classList.add("worker_skip_work");
                                            blockRow(html_element); }}


function changeConformationApp(html_element) {
    // without check old value!!!
	let tr = findRow(html_element);
    let worker_id = tr.cells[10].firstElementChild.value;
    if (!WORKERS[worker_id] && !SR_MANAGER) {alert("ВВЕДИТЕ ТАБЕЛЬНЫЙ НОМЕР!"); return}
    let row_in_TABLE ;
    for (row in TABLE) {if (Number(TABLE[row][0]) === Number(tr.dataset.rowid)) {row_in_TABLE = row;}}
    let payload = {"worksheet_id"     : tr.dataset.rowid,
                   "worker_id"        : tr.cells[10].firstElementChild.value,
                   "old_worker_id"    : TABLE[row_in_TABLE][10],};
    if (SR_MANAGER) {payload["confirmation_app"] = !TABLE[row_in_TABLE][20]; TABLE[row_in_TABLE][20] = payload["confirmation_app"];} else {payload["confirmation_app"] = true}
    
    // console.log('SEND CHANGE_CONFORMATION_APP_URL')
    send_data(CHANGE_CONFORMATION_APP_URL, payload, drawConformationApp, html_element);}


function drawConformationApp(response, html_element) {
    if (response['message'] == 'Success') {
        let tr = findRow(html_element);
        let row_in_TABLE ;
        for (row in TABLE) {if (Number(TABLE[row][0]) === Number(tr.dataset.rowid)) {row_in_TABLE = row;}}
        html_element.classList.add("sr_note_append"); // FIXME CANCEL APP!!!
        tr.classList.toggle('confirmed');
        TABLE[row_in_TABLE][20] = !TABLE[row_in_TABLE][20];
        if (!SR_MANAGER) {tr.cells[10].children[0].disabled = true;}    }}


function blockRow(html_element) {
    let tr = findRow(html_element);
    let action_elements = tr.querySelectorAll('input, button, textarea:not(.workplace_note)');   // workplace_note
    for (let e of action_elements) {e.disabled = true;}
    // for (let i = tr.cells.length - 1; i >= 0; i--) {
    //     // FIXME PLEASE: children can not exist or children can be more than one!
    //     if (tr.cells[i].children[0].tagName === "INPUT" || tr.cells[i].children[0].tagName === "BUTTON") {
    //         tr.cells[i].children[0].disabled = true;}    }
        }


function removeApp(html_element) {
    // without check old value!!!
    let tr = findRow(html_element);
    let payload = {"action" : html_element.dataset.action,
                   "payload" : {"worksheet_id"     : tr.dataset.rowid,},                    };
    send_data(REMOVE_APP_URL, payload, drawRemoveApp, html_element);}


function drawRemoveApp(response, html_element) {
    if (response['message'] == 'APP_REMOVED') {
        let tr = findRow(html_element);
        tr.parentElement.removeChild(tr);}
    else alert(response['message']);}


function changeExportToExcel(html_element) {
    // without check old value!!!
    let tr = findRow(html_element);
    let payload = {"action" : html_element.dataset.action,
                   "payload" : {"worksheet_id"     : tr.dataset.rowid, 
                                "exported" : tr.cells[23].children[0].checked, },  };
    send_data(REMOVE_APP_URL, payload, drawRemoveApp, html_element);}
```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/static/KRSK_WorkSheets/js/FF_LUVR_Table.js"
```
// 'use strict'             // !IMPOTANT!

let PRIORITY_SORT = [];
let INDEX_FIELD = {};
let FIELD_INDEX = {};
let EVENTS = [];
let LAST_ROW = 0;
let ROW_HEIGHT = 75;
let NUM_ROWS = 30;
let VIRTUAL_SCROLLER = null;
let TYPES_OF_WORK; // FIXME GET IT FROM SERVER!!!
let TABLE;
let CHANGE_WORKER_ID_FIELD; // FIXME BAD USE!!!
let OLD_SORT_AND_FILTER_DATA;


function createHead(data) { 
    let table = document.getElementById("table");
    // console.log("HEAD DATA")
    // console.log(data['ROLE'])
    OLD_SORT_AND_FILTER_DATA = data['OLD_SORT_AND_FILTER_DATA'];
    for (let role of data['ROLE']) {
        for (r of role) {
            if (r === 'Администраторы сети Командор') {KO_MANAGER = true;}
            if (r === 'Аналитики Командора')          {KO_ANALYST = true;}
            if (r === 'Менеджеры Спецресурса')        {SR_MANAGER = true;}
            if (r === 'СуперМенеджеры Спецресурса')   {SSR_MANAGER = true;}
            if (r === 'Разгуляй')                     {RAZGULAY = true;         TYPES_OF_WORK = ['Продавец-Универсал'];}
            if (r === 'Служба Контроля')              {SECURITY_SERVICE = true; TYPES_OF_WORK = ['Менеджер Службы Контроля', 'Сборщик тележек'];}
            if (r === 'Отдел обслуживания')           {SELL_SERVICE = true;     TYPES_OF_WORK = ['Кассир', 'Выкладка', 'Грузчик', 'Гастроном', 'Бригадир', 'Мобильный продавец', 'Мобильный грузчик'];}  
        }}
    ROLES = {'KO_MANAGER': KO_MANAGER, 'KO_ANALYST': KO_ANALYST, 'SR_MANAGER': SR_MANAGER, 'SSR_MANAGER': SSR_MANAGER, 'SECURITY_SERVICE': SECURITY_SERVICE, 'SELL_SERVICE': SELL_SERVICE, 'RAZGULAY': RAZGULAY,}

    getFields(data);

    let get_buttons_block = document.querySelector('.get_buttons_block');
    let span_with_buttons;
    if (document.getElementById('span_with_buttons')) {span_with_buttons = document.getElementById('span_with_buttons'); span_with_buttons.innerHTML = '';} 
    else {span_with_buttons = document.createElement('span');}
    span_with_buttons.id = 'span_with_buttons';
    let get_table_button = document.createElement('button');
        [get_table_button.id, get_table_button.type, get_table_button.innerText] = ['button_get_table', 'button', 'ПОВТОРИТЬ ФИЛЬТР'];
        get_table_button.classList.add('btn', 'btn-primary', 'temp-btn-4show-table');
        get_table_button.addEventListener('click', function() {getTestTable(getExcel = false, reset_filter = 'SAVE',)});
        span_with_buttons.appendChild(get_table_button);
    let get_table_button_without_filter = document.createElement('button');
        [get_table_button_without_filter.id, get_table_button_without_filter.type, get_table_button_without_filter.innerText] = ['button_get_table_without_filter', 'button', 'СБРОСИТЬ ФИЛЬТР И ПОКАЗАТЬ ТАБЛИЦУ'];
        get_table_button_without_filter.classList.add('btn', 'btn-primary', 'temp-btn-4show-table');
        get_table_button_without_filter.addEventListener('click', function() {resetFilterAndSort(); getTestTable(getExcel = false, reset_filter = 'RESET',);});
        span_with_buttons.appendChild(get_table_button_without_filter);

    if (SR_MANAGER || KO_ANALYST) {
        let getExcelButton = document.createElement('button');
            getExcelButton.classList.add('btn', 'btn-primary',  'temp-btn-4show-table');
            getExcelButton.addEventListener('click', function() {getTestTable(getExcel = {'head': 'BASE_LIST', 'toCheckExport': false})});
            getExcelButton.innerText = "Скачать EXCEL";
            span_with_buttons.appendChild(getExcelButton);
    if (SR_MANAGER) {
        let getExcelAndSetExportToExcelButton = document.createElement('button');
            getExcelAndSetExportToExcelButton.classList.add('btn', 'btn-primary',  'temp-btn-4show-table');
            getExcelAndSetExportToExcelButton.addEventListener('click', function() {getTestTable(getExcel = {'head': 'BASE_LIST', 'toCheckExport': true})});
            getExcelAndSetExportToExcelButton.innerText = "Скачать EXCEL и подтвердить выгрузку";
            span_with_buttons.appendChild(getExcelAndSetExportToExcelButton);

        let adminBridgeButton = document.createElement('button');
            adminBridgeButton.classList.add('btn', 'btn-primary',  'temp-btn-4show-table');
            adminBridgeButton.innerText = "Мост в таблицы";
        let adminBridgeLink = document.createElement('a'); 
            adminBridgeLink.setAttribute('href', '/bridge_to_GoogleSheets');
            adminBridgeLink.appendChild(adminBridgeButton);
            span_with_buttons.appendChild(adminBridgeLink);}
        }

    if (SR_MANAGER || KO_ANALYST) {
        let LOCATIONS_INDEX = {'id': 0, 'location': 1,};
        let INDEX_LOCATIONS = { 0: 'id', 1:'location',};
        let locations_select = document.createElement('select');
            [locations_select.id, locations_select.multiple] = ['locations_select', 'multiple'];
            for (location_list of data['LOCATIONS']) {
                let o = document.createElement('option');
                [ o.value, o.innerText,] = [location_list[LOCATIONS_INDEX['id']], location_list[LOCATIONS_INDEX['location']]];
                if ( 'OLD_LOCATIONS' in data && data['OLD_LOCATIONS'].length > 0 ) {o.selected = (data['OLD_LOCATIONS'].includes(String(location_list[LOCATIONS_INDEX['id']]))) ? true : false; } 
                else {o.selected = true;}
                locations_select.appendChild(o);            }
            locations_select.addEventListener('change', () => {
                send_data(URL_GET_HEAD, {'shop_code__shop_region__id': getLocations()}, createHead, function(error) {alert(error)});            });
        span_with_buttons.appendChild(locations_select);    }
    get_buttons_block.appendChild(span_with_buttons);

    if (document.getElementById("table_head")) {  document.getElementById("table_head").remove();}

    let thead = document.createElement('thead');
    thead.classList.add( 'table_head');
    thead.id = 'table_head'; 

    thead.appendChild(createHeadCell_LUVR('created',             'created',                                 'Время создания заявки',           head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['created']]));
    thead.appendChild(createHeadCell_LUVR('date_for_work',       'date_for_work',                           'Дата заявки',                     head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['date_for_work']]));
    thead.appendChild(createHeadCell_LUVR('shop_code',           'shop_code__shop_code',                    'Код ТТ',                          head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['shop_code__shop_code']]));
    thead.appendChild(createHeadCell_LUVR('shop_type',           'shop_code__shop_type',                    'Формат ТТ',                       head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['shop_code__shop_type']]));
    thead.appendChild(createHeadCell_LUVR('workplace_address',   'shop_code__workplace_address',            'Адрес ТТ',                        head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['shop_code__workplace_address']]));
    thead.appendChild(createHeadCell_LUVR('type_of_work',        'work_type__type_of_work',                 'Вид работы',                      head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['work_type__type_of_work']]));
    thead.appendChild(createHeadCell_LUVR('workplace_app_note',  'workplace_app_note',                      'Уточнение по видам работ',        head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['workplace_app_note']]));
    thead.appendChild(createHeadCell_LUVR('start_work',          'start_work',                              'Запланир. время нач. заявки',     head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['start_work']]));
    thead.appendChild(createHeadCell_LUVR('end_work',            'end_work',                                'Запланир. время окончан. заявки', head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['end_work']]));
    // thead.appendChild(createHeadCell_LUVR('amount_work_time',     NaN,                                   'Запланир. время заявки',          head_cell_func_onClick, ));  # THIS FIELD DOES NOT EXIST
    thead.appendChild(createHeadCell_LUVR('worker_id',           'lying_worker_id',                         'ТБ из заявки',                    head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['lying_worker_id']]));
    thead.appendChild(createHeadCell_LUVR('worker_id',           'timesheets__worker_id__worker_id',        'ТБ по факту',                     head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['timesheets__worker_id__worker_id']]));
    thead.appendChild(createHeadCell_LUVR('start_work',          'timesheets__start_work',                  'Начало заявки по факту',          head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['timesheets__start_work']]));
    thead.appendChild(createHeadCell_LUVR('end_work',            'timesheets__end_work',                    'Конец заявки по факту',           head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['timesheets__end_work']]));
    thead.appendChild(createHeadCell_LUVR('amount_of_work_time', 'timesheets__amount_of_work_time',         'Итоговое время по факту',         undefined)); //head_cell_func_onClick, data['FILTER_DATA'][14]));
    thead.appendChild(createHeadCell_LUVR('worker_full_name',    'timesheets__worker_id__worker_full_name', 'Ф.И.О.',                          head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['timesheets__worker_id__worker_full_name']]));
    thead.appendChild(createHeadCell_LUVR('grade',               'timesheets__grade__grade_num',            'Оценка оказанных услуг',          head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['timesheets__grade__grade_num']]));
    thead.appendChild(createHeadCell_LUVR('skip_work',           'timesheets__is_worker_skip_work',         'Сотрудник не вышел',              head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['timesheets__is_worker_skip_work']]));
    thead.appendChild(createHeadCell_LUVR('workplace_note',      'workplace_note',                          'Примечание от ТТ',                head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['workplace_note']]));
    thead.appendChild(createHeadCell_LUVR('note_from_SR',        'note_from_SR',                            'Примечание от КА',                head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['note_from_SR']]));
    thead.appendChild(createHeadCell_LUVR('cancel_app',          'is_cancel',                               'Отмена заявки',                   head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['is_cancel']])); // #### FIXME NEED CANCEL APP IN DB
    // thead.appendChild(createHeadCell_LUVR('worker_service',       NaN,                                      '% уровня сервиса сотрудника',     head_cell_func_onClick));     
    // thead.appendChild(createHeadCell_LUVR('SR_service',           NaN,                                      '% уровня сервиса КА',             head_cell_func_onClick));
    thead.appendChild(createHeadCell_LUVR('cancel_app_button',    undefined,                                'Отмена заявки'));
    thead.appendChild(createHeadCell_LUVR('confirmation_app',     undefined,                                'Подтверждение заявки'));
    thead.appendChild(createHeadCell_LUVR('send_LUVR_button',     undefined,                                'Подтверждение ЛУВРа'));
    thead.appendChild(createHeadCell_LUVR('exported',              'timesheets__export4payment__is_exported', 'Выгружено',                     head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['timesheets__export4payment__is_exported']]));

    if (SR_MANAGER) {
        thead.appendChild(createHeadCell_LUVR('selfemployed',          'timesheets__worker_id__payment_type__payment_type', 'Устройство',          head_cell_func_onClick, data['FILTER_DATA'][FIELD_INDEX['timesheets__worker_id__payment_type__payment_type']]));   

        
        const select_quantuim_worker = document.createElement("select");
        [select_quantuim_worker.id, select_quantuim_worker.multiple, select_quantuim_worker.style.height] = ['select_quantuim_worker', 'multiple', '50px'];
        const [to, fo] = [document.createElement("option"), document.createElement("option")];
        [to.value,    to.innerText, to.selected] = [true, 'Фиолетовые', true];
        [fo.value,    fo.innerText, fo.selected] = [false, "Обычные",   true];
        select_quantuim_worker.appendChild(to);    select_quantuim_worker.appendChild(fo);

        let show_lying_workers_button = thead.querySelector('div[data-filter_block="lying_worker_id"] button.filter_button');
        show_lying_workers_button.parentNode.insertBefore(select_quantuim_worker, show_lying_workers_button); }

    table.appendChild(thead);
    return thead;}


function createHeadCell_LUVR(cell_class, cell_dataset_type, cell_text, cell_func_onClick = undefined, filter_data = undefined) { 
    // FIXME BAD CHANGE CELL_DATASET_TYPE: NEED SEND DATASET AS WORDLIST
    
    let worksheets_table_cell = document.createElement("th");
        worksheets_table_cell.classList.add(cell_class);
        worksheets_table_cell.dataset.type = cell_dataset_type;

    let cool_visible_div = document.createElement('div');
        cool_visible_div.classList.add('cool');
    worksheets_table_cell.appendChild(cool_visible_div);

    let col_name_div = document.createElement('div');
        col_name_div.classList.add('col_name')
        col_name_div.innerHTML = cell_text;

    cool_visible_div.appendChild(col_name_div);

    if (cell_func_onClick) {
        let show_filter_and_sort_block_button = document.createElement('button');
            show_filter_and_sort_block_button.innerText = "Фильтр";
            show_filter_and_sort_block_button.dataset.data_type = cell_dataset_type;
            show_filter_and_sort_block_button.addEventListener('click', 
                function(event) {
                    event.stopPropagation(); //  Останавливаем всплытие, чтобы документ не получал событие сразу же.
                    let data_type = event.target.dataset.data_type;
                    let filter_block = document.querySelector(`div[data-filter_block="${data_type}"]`);
                        filter_block.classList.toggle('hidden_filter_block');

                    function toggleFilterBlock(event) {
                        // event.stopPropagation(); //  Останавливаем всплытие, чтобы документ не получал событие сразу же.

                        if (!filter_block.contains(event.target)) {
                            filter_block.classList.toggle('hidden_filter_block');
                            document.removeEventListener('click', toggleFilterBlock);}}
                    // event.stopPropagation(); //  Останавливаем всплытие, чтобы документ не получал событие сразу же.
                    document.addEventListener('click', toggleFilterBlock);})

        cool_visible_div.appendChild(show_filter_and_sort_block_button);
        worksheets_table_cell.appendChild(createSortAndFilterBlock(filter_data, cell_dataset_type, cell_func_onClick));}

    return worksheets_table_cell;}





function drawTable(data) {
    TABLE = data['table_data'];
    let body = document.getElementById('table_body');

    clearTableBody();
    getFields(data);
    let start_perf_time = new Date();

    // const height_list = new Array(TABLE.length).fill(0).map(() => { return 75; });  // FIXME NEED GENERATOR
    let summ_amount_of_work_time_row = Array(2);
    [summ_amount_of_work_time_row[0], summ_amount_of_work_time_row[1], summ_amount_of_work_time_row[2]] = ['AMOUNT_OF_WORK_TIME_ROW', TABLE.length, data['summ_amount_of_work_time']];
    TABLE.push(summ_amount_of_work_time_row);
    
    VIRTUAL_SCROLLER = new VirtualScroller(body, TABLE, getRow,   );
    // VIRTUAL_SCROLLER.stop();
    // { itemSize: { width: 2905, height: 75 } }
    // VIRTUAL_SCROLLER.setItemHeight(() => 75);
    // console.log(VIRTUAL_SCROLLER.setItemHeight)
    // VIRTUAL_SCROLLER.setItemWidth(() => 2905);

    // Now use scroller to render your items
    // VIRTUAL_SCROLLER.setItems(TABLE);
    // VIRTUAL_SCROLLER.start();
    // let end_trow = body.insertRow(-1);
    // for (; end_trow.cells.length <= 13; end_trow.insertCell(-1)) {};
    // // end_trow.style.height = ROW_HEIGHT + 'px';
    // end_trow.cells[13].innerText = data['summ_amount_of_work_time'];
    end_perf_time = new Date();
    // console.log(`rows created at ${end_perf_time - start_perf_time}`);
}


function getRow(drow, index) {
    // console.log(drow)
    let trow = document.createElement('tr');
    trow.setAttribute('data-rowid', drow[FIELD_INDEX['id']]); 
    trow.style.height = ROW_HEIGHT+'px';

    if (drow[0] === 'AMOUNT_OF_WORK_TIME_ROW') {
        // console.log('IN summ_amount_of_work_time_row!');
        for (; trow.cells.length <= 13; trow.insertCell(-1)) {};
        trow.style.height = ROW_HEIGHT + 'px';
        [trow.cells[0].innerText, trow.cells[13].innerText] = [drow[1], drow[2]];
        // console.log(trow);
        return trow;
    }

    let closed_luvr         = (drow[FIELD_INDEX['timesheets__amount_of_work_time']]) ? true : false;
    let canceled_app        = (drow[FIELD_INDEX['is_cancel']]) ? true : false;
    let is_worker_skip_work = (drow[FIELD_INDEX['timesheets__is_worker_skip_work']]) ? true : false;
    let confirmed_app       = (drow[FIELD_INDEX['confirmation_app']]) ? true : false; 

    let unwritable_row = (closed_luvr || canceled_app || is_worker_skip_work || KO_ANALYST) ? true : false; // FIXME PLEASE MORNING!!!
    unwritable_row = (SR_MANAGER) ? false : unwritable_row;
    
    if (closed_luvr)   {trow.classList.add('verifed');}
    if (confirmed_app) {trow.classList.add('confirmed');}
    if (canceled_app)  {trow.classList.add('canceled');}
    if (is_worker_skip_work)  {trow.classList.add('worker_skip_work');}

    let created_cell = trow.insertCell(-1);
        created_cell.classList.add("created");
        created_time = new Date(1000 * Number(drow[FIELD_INDEX['created_unix']]));
        created_cell.innerHTML  = created_time.toLocaleString("ru", OPTIONS_LOCAL_DATETIME);
        created_cell.dataset.created_unixtime = Number(drow[FIELD_INDEX['created_unix']]);
    
    let work_date_cell = trow.insertCell(-1);
        work_date_cell.classList.add("date_for_work");
        work_date_cell.dataset.work_date = drow[FIELD_INDEX['date_for_work_unix']];
        work_date_time = new Date(1000 * Number(drow[FIELD_INDEX['date_for_work_unix']]));
        if ( SSR_MANAGER ) {
            let work_date_input = document.createElement('input');
               [work_date_input.type, work_date_input.value] = ['date', work_date_time.toISOString().substr(0, 10)];
                work_date_input.addEventListener(...saveEventListner('change', function(){changeWorkDate(this);}))
                work_date_cell.appendChild(work_date_input); }
        else {  work_date_cell.innerText = work_date_time.toLocaleString("ru", OPTIONS_LOCAL_DATE); }
         

    let shop_code_cell = trow.insertCell(-1);
        shop_code_cell.classList.add("shop_code");
        shop_code_cell.innerHTML  = drow[FIELD_INDEX['shop_code__shop_code']]; 

    let shop_type_cell = trow.insertCell(-1);
        shop_type_cell.classList.add("shop_type");
        shop_type_cell.innerHTML  = drow[FIELD_INDEX['shop_code__shop_type']]; 

    let workplace_address_cell = trow.insertCell(-1);
        workplace_address_cell.classList.add("workplace_address");
        workplace_address_cell.innerHTML  = drow[FIELD_INDEX['shop_code__workplace_address']]; 

    let type_of_work_cell = trow.insertCell(-1);
        type_of_work_cell.classList.add("type_of_work");
        if (SR_MANAGER) {
                let type_of_work_select = document.createElement('select');
                    for (let itow in TYPES_OF_WORK) {
                        let o = document.createElement('option');
                        [o.value, o.innerText] = [TYPES_OF_WORK[itow], TYPES_OF_WORK[itow]];
                        type_of_work_select.appendChild(o);
                        if (TYPES_OF_WORK[itow] == drow[FIELD_INDEX['work_type__type_of_work']]) {type_of_work_select.selectedIndex = itow;}}
                type_of_work_select.addEventListener(...saveEventListner('change', function() {changeTypeOfWork(this);}));
                type_of_work_cell.appendChild(type_of_work_select);

        } 
        else {  type_of_work_cell.innerHTML  = drow[FIELD_INDEX['work_type__type_of_work']];}
    
    let workplace_app_note_cell = trow.insertCell(-1);
        workplace_app_note_cell.classList.add("workplace_app_note");
        workplace_app_note_cell.innerHTML  = drow[FIELD_INDEX['workplace_app_note']]; 

    let start_work_cell = trow.insertCell(-1);
        start_work_cell.classList.add("start_work");
        start_work_cell.innerHTML  = drow[FIELD_INDEX['start_work']]; //temp_date.toLocaleDateString(); // FIXME!!!
    
    let   end_work_cell = trow.insertCell(-1);
          end_work_cell.classList.add("end_work");
          end_work_cell.innerHTML  = drow[FIELD_INDEX['end_work']]; //temp_date.toLocaleDateString(); // FIXME!!!

    let worker_id_cell = trow.insertCell(-1);
        worker_id_cell.classList.add("worker_id");
    if (drow[FIELD_INDEX['quantium_wave_worker']]) {worker_id_cell.classList.add('purple_cell'); }
    let worker_id_input = document.createElement('input');
        worker_id_input.value  = drow[FIELD_INDEX['lying_worker_id']]; 
        worker_id_input.classList.add("worker_id");
        worker_id_input.addEventListener(...saveEventListner('change',function(){ if (WORKERS[this.value]) {CHANGE_WORKER_ID_FIELD = this; change_worker_modal.showModal();}}) );
        if (!SR_MANAGER && (unwritable_row || confirmed_app)) {worker_id_input.disabled = true;};
        worker_id_cell.appendChild(worker_id_input);
    
    let t_worker_id_cell = trow.insertCell(-1);
        t_worker_id_cell.classList.add("worker_id");
    let t_worker_id_input = document.createElement("input");
        t_worker_id_input.classList.add('worker_id');
        t_worker_id_input.setAttribute('type', 'text');
        t_worker_id_input.setAttribute('pattern', '\\d{0,6}');
        t_worker_id_input.addEventListener(...saveEventListner("change",function() {showFullName(this)})); //, is_need_to_send_data=false
        t_worker_id_input.addEventListener(...saveEventListner("focus", function() {old_worker_number = this.value}) )
    let t_worker_id = (canceled_app) ? "ОТМЕНА" : (drow[FIELD_INDEX['timesheets__worker_id__worker_id']]) ? drow[FIELD_INDEX['timesheets__worker_id__worker_id']] : drow[FIELD_INDEX['lying_worker_id']];
        t_worker_id_input.value = t_worker_id;
        if (!SR_MANAGER && (unwritable_row || confirmed_app)) {t_worker_id_input.disabled = true;};
        t_worker_id_cell.appendChild(t_worker_id_input);

    let t_start_work_cell = trow.insertCell(-1);
        t_start_work_cell.classList.add("start_work");
    let t_start_time = (canceled_app) ? "ОТМЕНА" : (drow[FIELD_INDEX['timesheets__start_work']]) ? drow[FIELD_INDEX['timesheets__start_work']] : drow[FIELD_INDEX['start_work']];
    let t_start_work_input = document.createElement("input");            
        t_start_work_input.classList.add('work_time');
        t_start_work_input.setAttribute('type', 'time');
        t_start_work_input.value = t_start_time;
    let startM = Number(t_start_time.split(':')[0])*60 + Number(t_start_time.split(':')[1]);
        t_start_work_input.addEventListener(...saveEventListner('input', function() {changeAmountOfWorkTime(this)})); //FIXME WORK
        if (unwritable_row) {t_start_work_input.disabled = true;};
        t_start_work_cell.appendChild(t_start_work_input);

    let t_end_work_cell = trow.insertCell(-1);
        t_end_work_cell.classList.add("start_work");
    let t_end_time = (canceled_app) ? "ОТМЕНА" : (drow[FIELD_INDEX['timesheets__end_work']]) ? drow[FIELD_INDEX['timesheets__end_work']] : drow[FIELD_INDEX['end_work']];
    let t_end_work_input = document.createElement("input");
        t_end_work_input.classList.add('work_time');
        t_end_work_input.setAttribute('type', 'time');
        t_end_work_input.value = t_end_time;
    let endM = Number(t_end_time.split(':')[0])*60+Number(t_end_time.split(':')[1]);
        t_end_work_input.addEventListener(...saveEventListner('change', function() {changeAmountOfWorkTime(this)}));
        if (unwritable_row) {t_end_work_input.disabled = true;};
        t_end_work_cell.appendChild(t_end_work_input);

    let t_amount_of_work_time_cell = trow.insertCell(-1);
        t_amount_of_work_time_cell.classList.add('amount_of_work_time');
        t_amount_of_work_time_cell.innerText = (canceled_app) ? "ОТМЕНА" : (drow[FIELD_INDEX['timesheets__amount_of_work_time']] !== null) ? drow[FIELD_INDEX['timesheets__amount_of_work_time']] : Math.trunc(getWorkTimeWithOutLanch(startM, endM)/6)/10;

    let t_worker_full_name_cell = trow.insertCell(-1);
        t_worker_full_name_cell.classList.add('worker_full_name');
        t_worker_full_name_cell.innerText = (t_worker_id) ? (WORKERS[t_worker_id]) ? (WORKERS[t_worker_id][2]) ? "УВОЛЕН" : WORKERS[t_worker_id][0] : "Сотрудник не найден" : "Сотрудник не назначен"; // FIXME NOW !!!

    let grade_num_cell = trow.insertCell(-1);
        grade_num_cell.classList.add("grade");
    let grade_num_input = document.createElement("select");
        let o0 = document.createElement('option');
            [o0.value, o0.innerText]  = ['', 'Выберите оценку'];
            grade_num_input.appendChild(o0);
        for (let count = 1; count < 6; count++ ) {
            let o = document.createElement('option');
            [o.value, o.innerText]  = [count, count];
            grade_num_input.appendChild(o);}
        grade_num_input.classList.add('grade')
        // grade_num_input.setAttribute('type', 'number');
        grade_num_input.selectedIndex = (drow[FIELD_INDEX['timesheets__grade__grade_num']]) ? drow[FIELD_INDEX['timesheets__grade__grade_num']] : 0;
        if (unwritable_row) {grade_num_input.disabled = true;};
        grade_num_cell.appendChild(grade_num_input);

    let is_worker_skip_work_cell = trow.insertCell(-1);
        is_worker_skip_work_cell.classList.add('skip_work');
    let is_worker_skip_work_checkbox = document.createElement("input");
        is_worker_skip_work_checkbox.type = 'checkbox';
        is_worker_skip_work_checkbox.checked = drow[FIELD_INDEX['timesheets__is_worker_skip_work']];
        if (unwritable_row) {is_worker_skip_work_checkbox.disabled = true;};
        is_worker_skip_work_cell.appendChild(is_worker_skip_work_checkbox);
    if (KO_MANAGER) {
        is_worker_skip_work_checkbox.hidden = true;
    let is_worker_skip_work_button = document.createElement('button');
        is_worker_skip_work_button.innerText = 'Прогул';
        if (unwritable_row) {is_worker_skip_work_button.disabled = true;};
        is_worker_skip_work_button.addEventListener(...saveEventListner('click', 
            function() {CHANGE_WORKER_ID_FIELD = this; send_worker_skip_work_modal.showModal();}));
        is_worker_skip_work_cell.appendChild(is_worker_skip_work_button);}

    let workplace_note_cell = trow.insertCell(-1);
        workplace_note_cell.classList.add('workplace_note');
    if (SR_MANAGER) {workplace_note_cell.innerText = drow[FIELD_INDEX['workplace_note']];}
    else {
    let workplace_note_textarea = document.createElement('textarea');
        workplace_note_textarea.classList.add('workplace_note')
        workplace_note_textarea.value = drow[FIELD_INDEX['workplace_note']];
        workplace_note_textarea.addEventListener(...saveEventListner('change', function() {changeKomandorsNote(this);}));
        workplace_note_textarea.disabled = (drow[FIELD_INDEX['workplace_note']]) ? true : false;
        workplace_note_cell.appendChild(workplace_note_textarea);}

    let note_from_SR_cell = trow.insertCell(-1);
        note_from_SR_cell.classList.add('note_from_SR');
    if (SR_MANAGER) {
        note_from_SR_textArea = document.createElement('textarea');
        note_from_SR_textArea.classList.add('note_from_SR');
        note_from_SR_textArea.value = drow[FIELD_INDEX['note_from_SR']];
        note_from_SR_textArea.addEventListener(...saveEventListner('change',  function() {changeSRNote(this);}));
        note_from_SR_cell.appendChild(note_from_SR_textArea);            } 
    else {note_from_SR_cell.innerText = drow[FIELD_INDEX['note_from_SR']];} 
        

    let cancel_app_text_cell = trow.insertCell(-1);
        cancel_app_text_cell.classList.add("cancel_app");
    if (SR_MANAGER) {
    let cancel_app_input = document.createElement('input');
        cancel_app_input.type = 'checkbox';
        cancel_app_input.checked = drow[FIELD_INDEX['is_cancel']];
        cancel_app_text_cell.appendChild(cancel_app_input);}
    else {if (drow[FIELD_INDEX['is_cancel']]) {cancel_app_text_cell.innerText = "Заявка отменена"}}

    let cancel_app_button_cell = trow.insertCell(-1);
        cancel_app_button_cell.classList.add("cancel_app");
    let cancel_app_button = document.createElement('button');
        cancel_app_button.innerText = "Отменить заявку";
        cancel_app_button.addEventListener(...saveEventListner('click', function() {changeCancelApp(this);})); 
        if (unwritable_row) {cancel_app_button.disabled = true;}
        cancel_app_button_cell.appendChild(cancel_app_button);

    let confirmation_app_cell = trow.insertCell(-1);
        confirmation_app_cell.classList.add("confirmation_app");
    let confirmation_app_button = document.createElement('button');
        confirmation_app_button.innerText = "Подтверждение заявки";
        confirmation_app_button.addEventListener(...saveEventListner('click', function() {changeConformationApp(this);})); 
        if (unwritable_row || (confirmed_app && !SR_MANAGER)) {confirmation_app_button.disabled = true;}
        confirmation_app_cell.appendChild(confirmation_app_button);

    let send_LUVR_button_cell = trow.insertCell(-1);
        send_LUVR_button_cell.classList.add("send_LUVR_button");
    let send_LUVR_button = document.createElement('button');
        send_LUVR_button.innerText = "Отправить ЛУВР"
        send_LUVR_button.addEventListener(...saveEventListner('click', function() {sendTimesheet(this);})); 
        if (unwritable_row) {send_LUVR_button.disabled = true;}
        send_LUVR_button_cell.appendChild(send_LUVR_button);   
    if (SR_MANAGER) {
        let remove_LUVR_button = document.createElement('button');
            remove_LUVR_button.dataset.action = 'removeLUVR';
            remove_LUVR_button.innerText = 'Удалить ЛУВР';
            remove_LUVR_button.addEventListener(...saveEventListner('click', function() {removeApp(this)}));
        let remove_APP_button = document.createElement('button');
            remove_APP_button.dataset.action = 'removeAPP';
            remove_APP_button.innerText = 'Удалить заявку';
            remove_APP_button.addEventListener(...saveEventListner('click', function() {removeApp(this)}));
        send_LUVR_button_cell.appendChild(remove_LUVR_button);
        send_LUVR_button_cell.appendChild(remove_APP_button);

        // let date_exported_cell = trow.insertCell(-1);
        //     date_exported_cell.innerText = drow[FIELD_INDEX['timesheets__worker_id__payment_type__payment_type']];        
                    }
            
    let is_exported_cell = trow.insertCell(-1);
    let is_exported_input = document.createElement('input');
        if (SSR_MANAGER) {is_exported_input.addEventListener(...saveEventListner('change', function() {changeExportToExcel(this)}))} else {is_exported_input.disabled = true;}
        is_exported_input.type = 'checkbox';
        is_exported_input.checked = drow[FIELD_INDEX['timesheets__export4payment__is_exported']];
        is_exported_input.dataset.action = 'changeExportedToExcel';
        is_exported_cell.appendChild(is_exported_input);        
    if (SR_MANAGER) {
        let selfemployed_cell = trow.insertCell(-1);
            selfemployed_cell.classList.add("selfemployed");
            selfemployed_cell.innerHTML  = drow[FIELD_INDEX['timesheets__worker_id__payment_type__payment_type']]; //temp_date.toLocaleDateString(); // FIXME!!!
    }
    return trow}


function changeAmountOfWorkTime(input) {
    let startM_value = input.parentElement.parentElement.cells[11].firstElementChild.value;
    let   endM_value = input.parentElement.parentElement.cells[12].firstElementChild.value;
    let startM = Number(startM_value.split(':')[0])*60+Number(startM_value.split(':')[1]);
    let   endM = Number(  endM_value.split(':')[0])*60+Number(  endM_value.split(':')[1]);
    let amount_of_work_time_cell = input.parentElement.parentElement.cells[13];
    amount_of_work_time_cell.innerText = Math.trunc(getWorkTimeWithOutLanch(startM, endM)/6)/10;}


function showFullName(workerInput, is_need_to_send_data=true) {
    let row = workerInput.parentElement.parentElement;
    row.cells[14].innerText = (WORKERS[workerInput.value]) ? (WORKERS[workerInput.value][2]) ? "УВОЛЕН" : WORKERS[workerInput.value][0] : "Сотрудник не найден";    }


function showWorkerSkipWorkConfirmation(html_element) {
    let modal = document.createElement('dialog');
        modal.setAttribute('id', 'worker_skip_work_modal');
    let str = ``}


function getFields(data) {
    [INDEX_FIELD, FIELD_INDEX] = [{}, {}]
    for (let i = 0; i < data['FIELDS'].length; i++) {
        INDEX_FIELD[i] = data['FIELDS'][i];
        FIELD_INDEX[data['FIELDS'][i]] = i;    }}


function saveEventListner(event, event_listner) {EVENTS.push([event, event_listner]); return [event, event_listner]}


function clearTableBody() {
    if (VIRTUAL_SCROLLER) {VIRTUAL_SCROLLER.stop();}
    EVENTS.forEach((e, ie, all_e) => {removeEventListener(...e); e = undefined;}); EVENTS = [];
    let body = document.getElementById('table_body');
    while (body.firstChild) { body.firstChild.remove();  } 
}


    // SUMM ALL WORKTIME ON FRONTEND
// function summHours() {
//     let table_body = document.getElementById('table_body');
//     let summ = 0;
//     for (let row of table_body.rows) {
//         if (row.classList.contains('verifed')) {summ = summ + Number(row.cells[13].innerText);}}
//     let end_row = table_body.rows[table_body.rows.length - 1];
//     if (end_row.cells.length <= 13) {for (; end_row.cells.length <= 13; end_row.insertCell(-1)) {}}
//     end_row.cells[13].innerText = summ;}
    // let first_cell_in_end_row = end_trow.insertCell(-1);
    // let end_button = document.createElement('button');
    //     end_button.innerText = 'Просуммировать часы';
    //     end_button.addEventListener('click', summHours)
    //     first_cell_in_end_row.appendChild(end_button);
// console.log((new Date() - start_perf_time))


    // let bot_div = document.createElement('div');
    // bot_div.id = 'observer_bot_div';
    // bot_div.style.height = `${(TABLE.length - Number(LAST_ROW))* ROW_HEIGHT}px`;
    // body.appendChild(bot_div);


// function addObservers() {
//     const [top_div, bot_div] = [document.getElementById('observer_top_div'), document.getElementById('observer_bot_div')];
//     let options = { root: null, rootMargin: `${5*Number(ROW_HEIGHT)}px`,   threshold: 0.01, }
//     // let callback_top = function(entries, observer){ console.log('TOP'); console.log(entries); }
//     let callback_bot = function(entries, observer){ 
//         console.log('BOT'); console.log(entries);  
//         // let bot_div = document.getElementById('observer_bot_div');
//         let body = document.getElementById('table_body');
//         for (let i = 0; i < 10; i++) {
//             LAST_ROW = Number(LAST_ROW) + 1;
//             // bot_div.style.height = `${(TABLE.length - Number(LAST_ROW))* ROW_HEIGHT}px`;
//             // top_div.style.height = `${(TABLE.length + Number(LAST_ROW) - Number(NUM_ROWS))* ROW_HEIGHT}px`;
//             body.insertBefore(getRow(TABLE[Number(LAST_ROW)]), bot_div);
//             // body.appendChild(getRow(TABLE[Number(LAST_ROW)]));        
//         }}
//     // let top_observer = new IntersectionObserver(callback_top, options)
//     let bot_observer = new IntersectionObserver(callback_bot, options)

//     // top_observer.observe(top_div);
//     bot_observer.observe(bot_div);
//     cancelAnimationFrame(HANDLE_ANIMATION_FRAME_WITH_ADD_OBSERVERS);
// }
    // HANDLE_ANIMATION_FRAME_WITH_ADD_OBSERVERS = requestAnimationFrame(addObservers);

```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/static/KRSK_WorkSheets/js/helpers.js"
```
// HELPERS CONSTANTS
const csrftoken = document.getElementsByName("csrfmiddlewaretoken")[0].value;  // Создание объекта с данными для отправки на сервер
const PYTHON_ORDINAL_TO_JS_DATE_NORMALIZATION_CONSTANT = 719163;
const MICROSECONDS_IN_DAY = 24 * 3600 * 1000;


// HELPERS FUNCTIONS
// function need_reload() {
//     new bootstrap.Modal(document.getElementById('reload_modal')).show();}
function handleCriticalError(error) { document.querySelector('#critical_error_modal > div').innerText = error + '\nОшибка сети'; window.critical_error_modal.showModal(); };
    
   

function getItemsFromSelect(select) {
    let items = [];
    for (const item of select.options) { items.push(item.value) };
    return items}


function send_data(url, data, result_function, object_4_result_function //, error_function = function error_function(){console.log('SEND_ERROR');}  // FIXME ERROR!!!
    ) {
    return fetch(window.location.origin + url, { 
        method: 'POST',
        body: JSON.stringify(data),
        headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': csrftoken}})
        .then(response => response.json())
        .then(data => {result_function(data, object_4_result_function);})
        .catch(error => {
            console.log(error); // FIXME ERROR!!!
            handleCriticalError(error);
            // error_function(error, object_4_function)
        });}



function send_data_return_file(url, data, xlfilename = 'file.xlsx') {
    return fetch(window.location.origin + url, { 
        method: 'POST',
        body: JSON.stringify(data),
        headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': csrftoken}})
        .then((response) => response.blob())
        .then((blob) => {
            let link = document.createElement('a');
            link.download =  'file.xlsx' // FIXME! WTF? WHY I CANT USE VARRIBLE THERE? 
            link.href = URL.createObjectURL(blob);
            link.click();
            URL.revokeObjectURL(link.href);})
        .catch(error => {
            console.log(error); 
            handleCriticalError(error);}    );  }


function get_data(url, result_function, error_function) {
    // console.log(`get data\nurl=${url}`)  // FIXME DEL THIS ROW!
    return fetch(window.location.origin + url).then(response => response.json())
            .then(data => result_function(data))
            .catch(error => error_function(error)); //FIXME !!!
}


function error_send_data(error) {
    // FIXME SEND ERROR ON SERVER
    console.log(error);
    // need_reload(); // FIXME NEED NEW MODAL
}


function getWorkTimeWithOutLanch(startM, endM) {
    // INPUT AND OUTPUT IN MINUTES
    let subtractM = ((endM - startM) > 0) ? (endM - startM) : (endM + 1440 - startM) ;

    if (subtractM > 390 && subtractM < 540)   subtractM-= 30;
    if (subtractM >= 540 && subtractM < 750)   subtractM-= 60; 
    if (subtractM >= 750)  subtractM-= 90;
    return subtractM}


function appendColumnInSort(header_cell) {
    let attr = header_cell.dataset.type;
    // console.log(attr)
    if (PRIORITY_SORT.length > 0) {
        // If attr last in PRIORITY_SORT then change directing (and break from func)
        if (attr in PRIORITY_SORT[PRIORITY_SORT.length - 1]) {
            PRIORITY_SORT[PRIORITY_SORT.length - 1][attr] = '-'; return;}
        // If attr exist in PRIORITY_SORT then clear PRIORITY_SORT and add attr (and break from func)
        for (let i = 0; i < PRIORITY_SORT.length - 1; i++) {
            if (attr in PRIORITY_SORT[i]) {
                PRIORITY_SORT = [{[`${attr}`]:'+'}]; return;}}}
    // if attr not exist in PRIORITY_SORT then append attr
    PRIORITY_SORT.push({[`${attr}`]:'+'});} 


function isColumnInSortList(column, sort_list) {
    for (let i = 0; i < sort_list.length; i++) {
        if (column in sort_list[i]) {return i;}}}


function createHeadCell(cell_class, cell_dataset_type, cell_text, cell_func_onClick) {
    // FIXME BAD CHANGE CELL_DATASET_TYPE: NEED SEND DATASET AS WORDLIST
    let worksheets_table_cell = document.createElement("th");
    worksheets_table_cell.classList.add(cell_class);
    worksheets_table_cell.dataset.type=cell_dataset_type;
    let index_word_list_in_sort_list = isColumnInSortList(cell_dataset_type, PRIORITY_SORT);
    let arrow_text;
    let inner_html = cell_text;
    if (index_word_list_in_sort_list !== undefined) {
        if (PRIORITY_SORT[index_word_list_in_sort_list][cell_dataset_type] === "+") {arrow_text = "&UpArrow;"}
        else                                                                        {arrow_text = "&DownArrow;"}
        inner_html += `&nbsp;<span class="icon-arrow">${arrow_text}</span>`;}
    worksheets_table_cell.innerHTML = inner_html;
    // FIXME are you REALY need to make a request to the server after EACH CLICK on sorting? (del getSortTable(...) because server )
    worksheets_table_cell.addEventListener('click', cell_func_onClick);
    return worksheets_table_cell;}


function findRow(html_element) {
    let tr = html_element;
    while (tr.tagName !== 'TR') {
        tr = tr.parentElement;}
    return tr  }




```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/templates/KRSK_WorkSheets/create_vacancy.html"
```
{% extends "KRSK_WorkSheets/skeleton.html" %}

{% block CONTENT %}
{% load static %}

<!-- Include base CSS (optional) -->
<!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/base.min.css"/> -->

<!-- Include Choices CSS -->
<!-- <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/choices.min.css"/> -->

<link rel="stylesheet" type="text/css" href="{% static 'KRSK_WorkSheets/css/create_vacancy.css' %}?v=2409240425">

<div class="container-fluid">
    <div class="page_header text-center">
        {% for group in request.user.groups.all %}
            {% if group.name == "Отдел обслуживания" %}
                <img class="small_logo" src="{% static 'KRSK_WorkSheets/img/small_Komandor_logo.webp' %}" alt="Маленький логотип ТС КОМАНДОР">
                <img class="wide_small_logo" src="{% static 'KRSK_WorkSheets/img/extra_small_wide_Komandor_logo.png' %}" alt="ОЧЕНЬ Маленький и широкий логотип ТС КОМАНДОР">
            {% elif group.name == "Служба Контроля" %}
                <img class="small_logo" src="{% static 'KRSK_WorkSheets/img/small_SS_Komandor_logo.jpg' %}" alt="Маленький логотип ТС КОМАНДОР">
                <img class="wide_small_logo" src="{% static 'KRSK_WorkSheets/img/extra_small_wide_Komandor_logo.png' %}" alt="ОЧЕНЬ Маленький и широкий логотип ТС КОМАНДОР">
            {% elif group.name == "Разгуляй" %}
                <img class="small_logo" src="{% static 'KRSK_WorkSheets/img/small_Razgulay_logo.png' %}" alt="Маленький логотип ТС РАЗГУЛЯЙ" style="border-radius: 15px;">
                <img class="wide_small_logo" src="{% static 'KRSK_WorkSheets/img/wide_Razgulay_logo.jpg' %}" alt="ОЧЕНЬ Маленький и широкий логотип ТС РАЗГУЛЯЙ" style="border-radius: 15px;">
            {% endif %}
        {% endfor %}
        <img class="wide_small_logo" src="{% static 'KRSK_WorkSheets/img/extra_small_wide_Komandor_logo.png' %}" alt="ОЧЕНЬ Маленький и широкий логотип ТС КОМАНДОР">
        <h1> {{title}} </h1></div>
    <div class="text-center date_filter">
        <div class="dateAndLocationRow row">
            <div class="dateCell col-6">Дата</div>
            <div class="dateCell col-6 date_backlight">
                <input  type="date" id="date_input"
                        onchange="showTypeOfWorkBlock();" 
                        placeholder="yyyy-mm-dd"
                        pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}"
                        min="2023-01-01"
                        max="2038-01-01"
                        required
                        onfocus="this.parentElement.classList.remove('date_backlight');"/>
                        <!-- FIXME THIS onfocus MUST BE REMOVED AFTER TRIGGER -->
            </div>
        </div>
        <div id="shop_block" class="dateAndLocationRow row" hidden="true">
            <div class="shopCell dateCell col-6">Магазин</div>
            <div class="shopCell dateCell col-6"><select id="shop_select"></select></div>
        </div>

<br> <!-- FIXME !!! -->
    <div class="changeWorkersTable container" id="type_of_work_block" hidden="true"></div>
    
    <div class="dinamycWorker container" id="dynamicWorker"></div>    
        <div class="vacancy_block" id="vacancy_block">
            <!-- <div class="cash_block" id="cash_block"></div> -->
        </div>

        <br> <!-- FIXME !!! -->

        <button class="btn btn-primary justify-content-center" onclick="send_all_data();" id="send_button" hidden="true">Отправить</button>
        <a href="{% url 'FF_LUVR' %}"><button class="btn btn-primary justify-content-center" id="toLUVRs">К ЛУВРам</button></a>

    </div>
      
      <!--  JUST REWRITE IT ALL!!! -->
        
</div>
{% csrf_token %}
<script type="text/javascript" src="{% static 'KRSK_WorkSheets/js/helpers.js' %}?v=2409240425"></script>
<script type="text/javascript">
const URL_SEND_APP                           = "{% url 'create_vacancy_page' %}";
const URL_GET_WORKERS                        = "{% url 'getAllWorkers'       %}";
const URL_GET_SHOPS                          = "{% url 'getAllShops'         %}";
const URL_GET_GROUPS                         = "{% url 'getUserGroups'       %}";
</script>
<script type="text/javascript" src="{% static 'KRSK_WorkSheets/js/create_vacancy.js' %}?v=2409240425"></script>
{% endblock %}

```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/templates/KRSK_WorkSheets/FF_LUVR.html"
```
{% extends "KRSK_WorkSheets/skeleton.html" %}

{% block CONTENT %}
{% load static %}
{% csrf_token %}

<link rel="stylesheet" type="text/css" href="{% static 'KRSK_WorkSheets/css/FF_LUVR.css' %}?v=2409240425">

<div class="container-fluid">
	<div class="page_header">
	    {% for group in request.user.groups.all %}
	        {% if group.name == "Отдел обслуживания" %}
				<img class="small_logo" src="{% static 'KRSK_WorkSheets/img/small_Komandor_logo.webp' %}" alt="Маленький логотип ТС КОМАНДОР">
				<img class="wide_small_logo" src="{% static 'KRSK_WorkSheets/img/extra_small_wide_Komandor_logo.png' %}" alt="ОЧЕНЬ Маленький и широкий логотип ТС КОМАНДОР">
	        {% elif group.name == "Служба Контроля" %}
				<img class="small_logo" src="{% static 'KRSK_WorkSheets/img/small_SS_Komandor_logo.jpg' %}" alt="Маленький логотип ТС КОМАНДОР">
				<img class="wide_small_logo" src="{% static 'KRSK_WorkSheets/img/extra_small_wide_Komandor_logo.png' %}" alt="ОЧЕНЬ Маленький и широкий логотип ТС КОМАНДОР">
			{% elif group.name == "Разгуляй" %}
				<img class="small_logo" src="{% static 'KRSK_WorkSheets/img/small_Razgulay_logo.png' %}" alt="Маленький логотип ТС РАЗГУЛЯЙ" style="border-radius: 15px;">
				<img class="wide_small_logo" src="{% static 'KRSK_WorkSheets/img/wide_Razgulay_logo.jpg' %}" alt="ОЧЕНЬ Маленький и широкий логотип ТС РАЗГУЛЯЙ" style="border-radius: 15px;">
	        {% endif %}
	    {% endfor %}

		<h1 class="text-center"> {{title}} </h1></div>
</div>
<div class="get_buttons_block">
	<a href="{% url 'create_vacancy_page' %}"><button type="button" class="btn btn-outline-success temp-btn-to-create-app">Создание заявок</button></a></div>
	
	<div class="test_virtual_scroll" id="test_virtual_scroll"></div>

<div class="table_block">
	<table class="worksheets_table " id="table">
		<thead class="table_head" id="table_head"></thead>
		<!--  JUST REWRITE IT ALL!!! -->
		<tbody class="smallest-text worksheets_table_body" id="table_body"></tbody>
	</table>
</div>


<dialog id="change_worker_modal">Подтвердить заявку?<button onclick="changeWorksheetWorkerId(CHANGE_WORKER_ID_FIELD);">Да</button><button onclick="change_worker_modal.close();">Нет</button></dialog>
<dialog id="send_worker_skip_work_modal">Отправить ЛУВР с прогулом?<button onclick="CHANGE_WORKER_ID_FIELD.parentElement.firstElementChild.checked = true;sendTimesheet(CHANGE_WORKER_ID_FIELD);">Да</button><button onclick="send_worker_skip_work_modal.close();">Нет</button></dialog>
<dialog id="loading_page"><h2>Загрузка</h2></dialog>
<dialog id="critical_error_modal">
	<h3>Что-то пошло не так</h3>
	<div></div>
	<button onclick="location.reload();">Перезагрузить страницу</button></dialog>

<script type="text/javascript">
const URL_GET_TABLE 						 = "{% url 'FF_LUVR_getTable' %}"
const URL_GET_HEAD 							 = "{% url 'FF_LUVR_getHead'     %}"
const URL_GET_WORKERS 						 = "{% url 'getAllWorkers'     %}"
const GET_ALL_GRADES_URL 					 = "{% url 'getAllGrades' %}";
const CHANGE_TYPE_OF_WORK_URL				 = "{% url 'FF_LUVR_changeTypeOfWork' %}";
const CHANGE_KOMANDORs_NOTE_URL				 = "{% url 'FF_LUVR_change_komandor_note' %}";
const CHANGE_SR_NOTE_URL					 = "{% url 'FF_LUVR_change_sr_note' %}";
const CHANGE_CANCEL_APP_URL					 = "{% url 'FF_LUVR_changeCancelApp' %}";
const CHANGE_WORKER_SKIP_WORK_URL			 = "{% url 'FF_changeWorkerSkipWork' %}";
const CHANGE_CONFORMATION_APP_URL			 = "{% url 'FF_changeConformationApp' %}";
const CHANGE_FIELD							 = "{% url 'FF_changeField' %}"
const REMOVE_APP_URL						 = "{% url 'FF_removeApp' %}";


const SEND_TIMESHEET_URL					 = "{% url 'FF_saveLUVR' %}";  
</script>
<script type="text/javascript" src="{% static 'KRSK_WorkSheets/js/virtual-scroller-dom.js' %}?v=2409240425"></script>
<script type="text/javascript" src="{% static 'KRSK_WorkSheets/js/helpers.js' %}?v=2409240425"></script>
<script type="text/javascript" src="{% static 'KRSK_WorkSheets/js/FF_LUVR.js' %}?v=2409240425_P"></script>
<script type="text/javascript" src="{% static 'KRSK_WorkSheets/js/FF_LUVR_Table.js' %}?v=2409240425_P"></script>
<script type="text/javascript" src="{% static 'KRSK_WorkSheets/js/FF_LUVR_Send_Functions.js' %}?v=2409240425"></script>
<script type="text/javascript" src="{% static 'KRSK_WorkSheets/js/FF_LUVR_Filter_Block.js' %}?v=2409240425"></script>

{% endblock %}

```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/base_models.py"
```
import datetime as dtLib

from django.db import models
from django.contrib.auth import get_user_model


User = get_user_model()


class TrackableDateModel(models.Model):
    """Abstract model to Track the creation/updated date for a model."""
    # Ask https://stackoverflow.com/questions/78263861/can-i-declare-two-foreignkey-to-the-same-table-in-one-django-orm-abstract-model
    create_date = models.DateTimeField(auto_now_add=True, help_text="Время создания", verbose_name="Созданно", null=True, blank=True)
    create_user = models.ForeignKey(User, related_name="create_user_%(app_label)s_%(class)s_related", on_delete=models.CASCADE, help_text="Кто создал", verbose_name="Автор", null=True, blank=True)
    update_date = models.DateTimeField(auto_now=True, help_text="Время изменения", verbose_name="Изменено", null=True, blank=True)
    update_user = models.ForeignKey(User, related_name="update_user_%(app_label)s_%(class)s_related", on_delete=models.CASCADE, help_text="Кто изменял", verbose_name="Автор изменений", null=True, blank=True)

    class Meta:
        abstract = True


class BaseShop(models.Model):
    '''Модель (ДЛЯ ПАРСЕРА ТОЛЬКО?) магазинов'''
   
    # class ShopType(models.TextChoices):
    #     '''Model for choice shop'''
    #     DISCAUNTER  = 'D', _('Дискаунтер') # 'D'
    #     FRESHMARKET = 'F', _('Фрешмаркет')  # 'F'
    #     SUPERSTOR   = 'S', _('Суперстор' )  # 'S'
    #     UNKNOWN     = 'U', _('НЕТ ДАННЫХ')
        # SHOP_TYPES = [(DISCAUNTER, 'Дискаунтер'), (FRESHMARKET, 'Фрешмаркет'), (SUPERSTOR, 'Суперстор'),] # FIXME USE DICT WHEN UPDATE TO DJANGO 5.2

        # @staticmethod
        # def getShopType(shop_type: str):
        #     '''Return ShopTypeType from str'''
        #     for s in Shops.ShopType.choices:
        #         if s[0] == shop_type:
        #              return s[0]

    sheet_row_idx = models.IntegerField(help_text="Номер строки в таблице", verbose_name="Номер строки", unique=True, null=True) # DEPRECATED
    shop_index = models.IntegerField(help_text="Порядковый номер магазина", verbose_name="SN", unique=True, null=True)           # DEPRECATED
    shop_code = models.CharField(max_length=50, help_text="Код Торговой Точки", verbose_name="Код ТТ", unique=True, null=True, blank=True)
    shop_type = models.CharField(max_length=50, null=True, blank=True, help_text="Формат Торговой Точки", verbose_name="Формат",) #, choices=ShopType.choices, # FIXME LENGHT MUST BE 1 !!! #  models.CharField(max_length=1, choices=SHOP_TYPES,  null=True, blank=True, )
    shop_director = models.CharField(max_length=500, help_text="Данные директора магазина", null=True, blank=True, verbose_name="Директор")
    workplace_address = models.CharField(max_length=500, help_text="Адрес Торговой Точки", null=True, blank=True, verbose_name="Адрес ТТ")
    priority = models.BooleanField(help_text="Приоритетная ТТ?", verbose_name="Приоритет", default=False)
    shop_region = models.ForeignKey('Locations', on_delete = models.PROTECT, help_text="Направление обслуживания", verbose_name="Регион", null=True, blank=True)
    # user = models.OneToOneField(User, on_delete=models.PROTECT, help_text="Связь с аккаунтом", null=True, blank=True) #### FIXME NOW null must be false

    class Meta:
        ordering = ["shop_code"]
        abstract = True

    def __unicode__(self):
        return self.shop_code

    def __str__(self):
        return self.shop_code


class BaseShopUser(models.Model):
    user = models.OneToOneField(User, on_delete=models.PROTECT, unique=True)

    class Meta:
        abstract = True


class BaseWorkSheets(TrackableDateModel): 
    created = models.DateTimeField(auto_now_add=True, null=True,  # FIXME
        help_text="Дата создания заявки", verbose_name="TimeStamp") # DEPRECATED FIXME NEED DELETE
    date_for_work = models.DateField(auto_now=False,  default=dtLib.date(1970, 1, 1),  # null=True,  # FIXME
        help_text="Дата начала работы", verbose_name="Дата заявки")
    lying_worker_id = models.IntegerField(help_text="Табельный номер сотрудника в заявке", verbose_name="Табельный номер", null=True, blank=True) #default=Workers.get_default_pk()) # FIXME
    start_work = models.TimeField(auto_now=False,    default=dtLib.time(0,0,0),   # null=True,  # FIXME
        help_text="Время начала заявки", verbose_name="Начало заявки")
    end_work = models.TimeField(auto_now=False,   default=dtLib.time(0,0,0),  # null=True,  # FIXME
        help_text="Время окончиания заявки", verbose_name="Конец заявки")
    confirmation_app = models.BooleanField(help_text="Подтверждение заявки магазином", verbose_name="Подтверждение заявки", default=False) #CharField(max_length=50, help_text="Подтверждение заявки", null=True, blank=True, verbose_name="Подтверждение") # FIXME IS NEED IT ME HERE OR 121 IN ANOTHER TABLE?
    workplace_app_note = models.CharField(max_length=1000, help_text="Пояснение по видам работ", null=True, blank=True, verbose_name="Пояснение работы")
    workplace_note = models.CharField(max_length=1000, help_text="Примечание от ТТ", null=True, blank=True, verbose_name="Примечание") # ALL NOTE MUST BE OneToOne!!!
    time_last_change_note_by_shop = models.DateTimeField(auto_now=False, null=True, blank=True, help_text="Время последнего изменения комментария", verbose_name="Время коментария магазина")  # ALL NOTE MUST BE OneToOne!!!
    note_from_SR = models.CharField(max_length=500, help_text="Ответ от контрагента", null=True, blank=True, verbose_name="Ответ для ТТ") # ALL NOTE MUST BE OneToOne!!!
    is_cancel = models.BooleanField(help_text="Отмена заявки магазином", verbose_name="Отмена заявки", default=False)

    class Meta:
        ordering = ["date_for_work"]
        abstract = True

        # FIX IT PLEASE!!!
        indexes = [ models.Index(fields=['lying_worker_id']), 
                    models.Index(fields=['date_for_work']),
                    models.Index(fields=['date_for_work', 'shop_code']),
                    models.Index(fields=['shop_code']),
                    models.Index(fields=['created']),
                    ]

    def __str__(self):
        return f'id={self.id} {self.date_for_work} на {self.shop_code} с {self.start_work} по {self.end_work} для {self.lying_worker_id}' 


class BaseTimeSheets(TrackableDateModel):
    '''#### FIXME'''
    timestamp = models.DateTimeField(auto_now_add=True,  null=True,  # FIXME
        help_text="Дата создания ЛУВРа", verbose_name="TimeStamp", ) # DEPRECATED FIXME NEED DELETE
    start_work = models.TimeField(auto_now=False,  default=dtLib.time(0,0,0),  #### FIXME
        help_text="Время начала работы", verbose_name="Время, в которое работник приступил к выполнению работы")
    end_work = models.TimeField(auto_now=False,  default=dtLib.time(0,0,0),    #### FIXME
        help_text="Время окончиания заявки", verbose_name="Время, в которое работник окончил выполнение работы")
    # Actual paid time. AutoGenerated. # FIXME Need to find out how it is rounded
    amount_of_work_time = models.DecimalField(help_text="Количество оплачиваемых часов", verbose_name="Часы работы",
                                              max_digits=3, decimal_places=1, default=0) # DEFAULT = 0 (???) # FIXME
    grade = models.ForeignKey('Grades', on_delete = models.PROTECT,  null=True,  # FIXME
        help_text="Оценка выполненной работы", verbose_name="Оценка") 
    is_worker_skip_work = models.BooleanField(help_text="Сотрудник не вышел на работу", verbose_name="Прогул?", null=True, blank=True)
    
    class Meta:
        abstract = True
        # FIXME ARE YOU REALY NEED THIS INDEXES?
        indexes = [ models.Index(fields=['worker_id']), 
                    models.Index(fields=['grade']),]
  

class BaseExport4Payment(TrackableDateModel):
    date_exported_to_excel = models.DateTimeField(auto_now_add=True, help_text="Дата Выгрузки", verbose_name="Дата выгрузки в excel", null=True, blank=True) # DEPRECATED FIXME NEED DELETE
    is_exported = models.BooleanField(help_text="Выгружено?", verbose_name="Выгружено?", default=False)
    
    class Meta:
        abstract = True


class BaseWorkers(TrackableDateModel):    
    """    Parse Google Sheets Table with work employee     """
    sheet_row_idx = models.IntegerField(help_text="Номер строки в таблице", verbose_name="Номер строки", unique=True, null=True)
    worker_id = models.IntegerField(help_text="Табельный номер сотрудника", verbose_name="Табельный номер", unique=True) 
    worker_full_name = models.CharField(max_length=500, help_text="ФИО сотрудника", verbose_name="ФИО")
    # workerPhone = models.CharField(max_length=50, help_text="Номер телефона сотрудника", null=True, blank=True, verbose_name="Номер телефона") # FIXME INTEGERFIELD
    # workerPhoneFormula = models.CharField(max_length=200, null=True, blank=True,
    #             help_text="Формула для звонка сотруднику (заполняется автоматически)",
    #             verbose_name="Формула номера телефона") # FIXME (Что-то придумать тут)
    # workerBirthDate = models.DateTimeField(auto_now=False, auto_now_add=False, null=True, blank=True, 
    #                                        help_text="Дата рождения сотрудника", verbose_name="Дата Рождения")
    # workerPassportRegistration = models.CharField(max_length=500, help_text="Прописка сотрудника", null=True, blank=True, verbose_name="Прописка")
    # noteAboutWorker = models.CharField(max_length=1000, help_text="Примечание", null=True, blank=True, verbose_name="Примечание")
    # avaibleWorkForWorkers =  models.CharField(max_length=500, help_text="Профессия сотрудника", null=True, blank=True, verbose_name="Должности")
    # workerPassportNumber = models.CharField(max_length=50, help_text="Серия и номер пасспорта сотрудника", null=True, blank=True, verbose_name="Серия Номер пасспорта")    # FIXME?
    # placeOfIsseOfTheWorkersPassport = models.CharField(max_length=1000, help_text="Место выдчи пасспорта", null=True, blank=True, verbose_name="Пасспорт выдан")
    # idPlaceOfIsseOfTheWorkersPassport = models.CharField(max_length=1000, help_text="Код подразделения", null=True, blank=True, verbose_name="Код подразделения")
    # workersHireDate = models.DateTimeField(auto_now=False, auto_now_add=False, null=True, blank=True, 
    #                                        help_text="Дата найма сотрудника", verbose_name="Нанят")
    # workerLivePlace = models.CharField(max_length=500, help_text="Приоритетный район для поиска работы", null=True, blank=True, verbose_name="Район проживания") # FIXME FK TO LOCALS?
    # workersBankDetails = models.CharField(max_length=500, help_text="Платежные реквизиты сотрудника", null=True, blank=True, verbose_name="Банковские реквизиты")
    date_Of_Dismissal = models.DateTimeField(auto_now=False, auto_now_add=False, null=True, blank=True, help_text="Дата увольнения сотрудника", verbose_name="Дата увольнения")
    payment_type = models.ForeignKey('PaymentType', on_delete = models.PROTECT, help_text="Кто оплачивает", verbose_name="Оплата", null=True, blank=True)
    INN = models.CharField(max_length=200, help_text="ИНН Сотрудника", null=True, blank=True, verbose_name="ИНН") # FIXME INTEGER?
    # countWorkerIDFromGSheets = models.CharField(max_length=2, help_text="Количество повторов табельного номера", null=True, blank=True, verbose_name="Количество повторов табельного номера") # FIXME MUST AUTOCOUNT

    class Meta:
        abstract = True
        indexes = [ models.Index(fields=['worker_id']), 
                    models.Index(fields=['worker_full_name']),]
    # @classmethod
    # def get_default_pk(cls):
    #     worker, created = cls.objects.get_or_create(worker_id=0, defaults={'workerFullName': 'Несуществующий сотрудник', 'rawRowIdx' : 0},)
    #     return worker.pk

    # def get_absolute_url(self):
    #      return reverse('model-detail-view', args=[str(self.worker_id)])

    def __str__(self):
        return f"{self.worker_id}: {self.worker_full_name}"


### TABLE 4 RELATIONS
class BaseTypeOfWork(models.Model):
    type_of_work = models.CharField(help_text="Название вакансии", verbose_name="Тип", 
                                  max_length=500, unique=True, default="FIXME!")
    location = models.ForeignKey('Locations', on_delete = models.SET_NULL, blank=True, null=True)

    class Meta:
        abstract = True
        ordering = ["id"]

    def __unicode__(self):
        return str(self.type_of_work)

    def __str__(self):
        return str(self.type_of_work)

```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/create_vacancy_View.py"
```
import json

import datetime as dt

from django.contrib.auth            import get_user_model # DEPRECATED?
# from django.contrib.auth.decorators import permission_required
from django.contrib.auth.decorators     import user_passes_test
from django.shortcuts               import render
from django.views.decorators.http   import require_http_methods
from django.http                    import JsonResponse # ,HttpResponseRedirect
from django.db.models               import Q

from .helpers                       import has_any_permissions, getSheetByGroup
from .helpers                       import VIEW_PERMISSIONS, CHANGE_PERMISSIONS, DELETE_PERMISSIONS

# from .models                        import Shops

from myconfig.config                import PERIOD_RECONCILIATION_OF_RESULTS

User = get_user_model()


TYPE_OF_WORK_RELATION = { # "site_json"          : "models.TypeOfWork.type_of_work",
                            "cash"               : "Кассир",
                            "spreader"           : "Выкладка",
                            "loader"             : "Грузчик",
                            "departament_worker" : "Гастроном",
                            "foreman"            : "Бригадир",
                            "mobile_worker"      : "Мобильный работник",                    
                            "mobile_cash"        : "Мобильный продавец",
                            "mobile_loader"      : "Мобильный грузчик",

                            "security_service"   : "Менеджер Службы Контроля",
                            "cart_assembler"     : "Сборщик тележек",

                            "universal_cash" : "Продавец-Универсал",}
                                


@user_passes_test(lambda user: has_any_permissions(user, VIEW_PERMISSIONS))  # FIXME
def create_vacancy_page(request):
    if request.method == 'GET':
        response = render(request, 'KRSK_WorkSheets/create_vacancy.html', context={'title':'Электронная заявка на вывод персонала'})
        return response
    elif request.method == 'POST':
        # print(request.body)
        data = json.loads(request.body)
        # print(dir(request.user))
        # print(request.user)
        return save_vacancy(data, request.user) # FIXME BAD STYLE
    else:
        return 403 # FIXME!!!


def save_vacancy(data, user):
    """#### FIXME """
    raw_worker = data.get('worker', None)
    worker_id = None if (raw_worker in ['', None]) or not (raw_worker.isnumeric()) else int(data['worker'])

    if isinstance(WorkSheets := getSheetByGroup(user, 'WorkSheets'), JsonResponse):
        return WorkSheets
    if isinstance(Workers    := getSheetByGroup(user, 'Workers'   ), JsonResponse):
        return Workers
    if isinstance(TypeOfWork := getSheetByGroup(user, 'TypeOfWork'), JsonResponse):
        return TypeOfWork
    if isinstance(Shops       := getSheetByGroup(user,       'Shops'), JsonResponse):
        return Shops
    # if isinstance(ShopUser    := getSheetByGroup(user,       'ShopUser'), JsonResponse):
    #     return ShopUser


    if user.groups.filter(name='Администраторы сети Командор'):
        if user.groups.filter(Q(name='Отдел обслуживания') | Q(name='Служба Контроля')):
            tmpWorkPlace  = user.kshopuser.shop
        elif user.groups.filter(name='Разгуляй'):
            tmpWorkPlace  = user.razgulayshopuser.shop
        else:
            return JsonResponse({'message': 'OK'}) #400 #### FIXME 400??? NEED LOGGER
    else:
        try:
            tmpWorkPlace  = Shops.objects.get(shop_code=data.get('shop'))
        except:
            return JsonResponse({'message': 'OK'}) #400 #### FIXME 400??? NEED LOGGER
    try:
        tmpTypeOfWork = TypeOfWork.objects.get(type_of_work=str(TYPE_OF_WORK_RELATION[data['type']]))
        work_date     = dt.date.fromisoformat(data['date'])

        if work_date <= PERIOD_RECONCILIATION_OF_RESULTS[0].date():
            return JsonResponse({'message': 'OK',  'show_message': f'''Невозможно создать заявку на {str(work_date)}.\nCверка до {str(PERIOD_RECONCILIATION_OF_RESULTS[0].date())} завершена {str(PERIOD_RECONCILIATION_OF_RESULTS[1])}.\nДля регистрации данной заявки необходимо написать письмо менеджерам компании "СПЕЦРЕСУРС'''})
        
        start_work_time = dt.time.fromisoformat(data['start'])
        start_work_datetime = dt.datetime.combine(work_date, start_work_time)

        confirmation_app = True if worker_id and Workers.objects.filter(worker_id=worker_id).exists() else False

        work = WorkSheets.objects.create(
            lying_worker_id     = worker_id,
            created             = dt.datetime.now(), 
            date_for_work       = work_date, # FIXME FIRST DENY 0023 YEAR!!!
            work_type           = tmpTypeOfWork, 
            start_work          = start_work_time,
            end_work            = dt.time.fromisoformat(data['end']),
            shop_code           = tmpWorkPlace,
            workplace_app_note  = data['note'],
            confirmation_app    = confirmation_app,
            create_user         = User.objects.get(username=user.username),
            note_from_SR        = 'Заявка создана менее, чем за 24 часа до начала смены. Закрытие согласно приоритету' if (start_work_datetime - dt.datetime.now()) < dt.timedelta(hours=24) else None,)

        return JsonResponse({'message': 'Success'})
    except BaseException as e:
        print(f"Error add app\n{e}")
        return JsonResponse({'message': 'OK'}) #400 #### FIXME 400??? NEED LOGGER


```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/FF_LUVR.py"
```
import json
import time
import datetime as dtLib
import pandas   as pd
import numpy    as np

from decimal import Decimal, getcontext
getcontext().prec = 1

# from django.conf                        import settings
# from django.contrib.auth.decorators     import permission_required
from django.contrib.auth.decorators     import user_passes_test
# from django.contrib.auth.models         import User # FIXME USE User from User = get_user_model()
from django.contrib.auth                import get_user_model
from django.contrib.postgres.aggregates import ArrayAgg
from django.shortcuts                   import render
from django.views.decorators.http       import require_http_methods
from django.http                        import JsonResponse, HttpResponse# ,HttpResponseRedirect
from django.db.models                   import Q, F, Func, Sum, DecimalField, Exists, OuterRef,  Case, Value, When, BooleanField, CharField
from django.db.models.functions         import Concat

from .models                            import Grades, ExtendAccount, Locations
from .helpers                           import getWorkingHours, getSheetByGroup, has_any_permissions, originalizeField, userizeField, userizeDictKeys
from .helpers                           import VIEW_PERMISSIONS, CHANGE_PERMISSIONS, DELETE_PERMISSIONS
from .FF_LUVR_filter                    import deserializeSortAndFilter, getSortAndFilter
from myconfig.config                    import PERIOD_RECONCILIATION_OF_RESULTS


ORIGINAL_WORKSHEET_LIST_FIELDS  =  ['id', 'created', 'date_for_work',  'shop_code__shop_code', 'shop_code__shop_type', 'shop_code__workplace_address', 'work_type__type_of_work', 'workplace_app_note', 'start_work', 'end_work', 'lying_worker_id', 'timesheets__worker_id__worker_id',   'timesheets__start_work',  'timesheets__end_work',  'timesheets__amount_of_work_time',  'timesheets__worker_id__worker_full_name',  'timesheets__grade__grade_num',  'timesheets__is_worker_skip_work', 'workplace_note', 'note_from_SR', 'confirmation_app', 'is_cancel',   'timesheets__export4payment__is_exported',  'timesheets__worker_id__payment_type__payment_type', 'shop_code__shop_region__id',  'timesheets__worker_id__payment_type__id']
# HEAD_WORKSHEET_LIST_FIELDS =  ['id', 'created', 'date_for_work',  'shop_code',  'workplace_app_note', 'start_work', 'end_work', 'lying_worker_id', 'timesheets__worker_id__worker_id', 'timesheets__start_work', 'timesheets__end_work', 'timesheets__amount_of_work_time', 'timesheets__worker_id__worker_full_name', 'timesheets__grade__grade_num', 'timesheets__is_worker_skip_work', 'workplace_note', 'note_from_SR', 'confirmation_app', 'is_cancel', 'timesheets__export4payment__is_exported', 'timesheets__worker_id__payment_type__payment_type', 'shop_code__shop_region__id', 'timesheets__worker_id__payment_type__id']
# SHOPS_FIELDS = ['id', 'shop_code__shop_code', 'shop_code__shop_type', 'shop_code__workplace_address', 'work_type__type_of_work',]
DEBUG_THIS_FUNC = False
# USER = settings.AUTH_USER_MODEL
User = get_user_model()


class UnixTimestamp(Func):
    # Функция для преобразования datetime в unixtime
    function = 'EXTRACT'
    template = "%(function)s('epoch' FROM %(expressions)s)"


@require_http_methods("GET")
@user_passes_test(lambda user: has_any_permissions(user, VIEW_PERMISSIONS))  # FIXME
def FF_LUVR_View(request):
    '''JUST GET MAIN PAGE'''
    response = render(request, 'KRSK_WorkSheets/FF_LUVR.html', context={'title':'ЛУВРЫ'})
    return response


@require_http_methods("GET")
@user_passes_test(lambda user: has_any_permissions(user, CHANGE_PERMISSIONS))  # FIXME
def FF_Exporting_page_View(request):
    '''JUST GET MAIN PAGE'''
    response = render(request, 'KRSK_WorkSheets/FF_Exporting_page.html', context={'title':'ЛУВРЫ'})
    return response


@require_http_methods("POST")
@user_passes_test(lambda user: has_any_permissions(user, VIEW_PERMISSIONS))  # FIXME
def FF_LUVR_getHead(request):
    '''DATA FOR FILTERS:
    input: #FIXME DOC
    output: #FIXME DOC'''

    # perf = time.perf_counter_ns()
    json_reqest = json.loads(request.body)
    location = json_reqest.get('shop_code__shop_region__id', []) 
    location_filter_data = { 'shop_code__shop_region__id': location }

    if isinstance(WorkSheets := getSheetByGroup(request.user, 'WorkSheets'), JsonResponse):
        return WorkSheets
    USER_WORKSHEET_LIST_FIELDS = [userizeField(request.user, field) for field in ORIGINAL_WORKSHEET_LIST_FIELDS]

    data_for_extended_account = {'last_filter_data': {**location_filter_data}, 'last_sort_data': []}
    ea, is_ea_created = ExtendAccount.objects.get_or_create( user=request.user, 
                                                             defaults=data_for_extended_account)
    
    if ea.last_filter_data.get('shop_code__shop_region__id') != location and json_reqest.get("status") != 'START':
        ea.last_filter_data = location_filter_data
        ea.save()

    result_data_for_filter = ea.last_filter_data if not is_ea_created else {}
    result_sort_data       = ea.last_sort_data   if not is_ea_created else []

    sort_list, filter_kwargs, q_objects, list_fields = deserializeSortAndFilter(
        raw_sort    = None, 
        raw_filter  = location_filter_data, # ea.last_filter_data, # json_reqest.get('FILTER_DATA'), 
        user        = request.user, 
        list_fields = ORIGINAL_WORKSHEET_LIST_FIELDS[:],)
    filter_kwargs, list_fields = userizeDictKeys(request.user, filter_kwargs), [userizeField(request.user, field) for field in list_fields]
    # print(f"FILTER = {filter_kwargs}\nFilter = {BASE_WORKSHEET_LIST_FIELDS[:]}")

    qs = WorkSheets.objects.all()
    qs = qs.filter(*q_objects, **filter_kwargs)
    # print(f"list_fields = {list_fields}")
    qs = qs.aggregate(**{f'values_{ff}': ArrayAgg(ff, distinct=True) for ff in list_fields})
    qs2 = [qs[f'values_{ff}'] for ff in list_fields] # не помню, почему не могу values_list здесь....

    payload = { 'ROLE' : list(request.user.groups.values_list('name')),  # FIXME bad data
                'FILTER_DATA' : list(qs2),
                'OLD_SORT_AND_FILTER_DATA': {'sort': result_sort_data, 'filter': result_data_for_filter},
                'LOCATIONS' : list(Locations.objects.all().values_list('id', 'location')),
                'OLD_LOCATIONS' : ea.last_filter_data.get('shop_code__shop_region__id', []),
                'FIELDS': [originalizeField(field) for field in list_fields],                }

    response = JsonResponse(payload, safe=False)

    # end_perf = time.perf_counter_ns()
    # print(f"HEAD CREATED IN {(end_perf - perf)/ 10**9}s")

    return response


@require_http_methods("POST")
@user_passes_test(lambda user: has_any_permissions(user, VIEW_PERMISSIONS))  # FIXME
def FF_LUVR_getTable(request):
    '''DATA FOR TABLE
    # FIXME DOC '''

    # perf = time.perf_counter_ns()

    json_reqest   = json.loads(request.body)
    user          = request.user
    need_excel    = json_reqest.get('getExcel', False)
    reset_filter  = json_reqest.get('reset_filter', 'OLD')
    filter_data   = json_reqest.get('filters', {})
    sort_data     = json_reqest.get('sorts', [])


    if isinstance(WorkSheets := getSheetByGroup(user, 'WorkSheets'), JsonResponse):
        return WorkSheets
    if isinstance(TimeSheets := getSheetByGroup(request.user, 'TimeSheets'), JsonResponse):
        return TimeSheets  
    if isinstance(Export4Payment := getSheetByGroup(request.user, 'Export4Payment'), JsonResponse):
        return Export4Payment  

    # print(f"\n\n============================================================\n=== json_reqest = {json_reqest}\n============================================================\n\n")
    if reset_filter == 'SAVE':
        ea, is_ea_created = ExtendAccount.objects.update_or_create( user=user, 
                                                                    defaults={'last_filter_data': filter_data, 'last_sort_data': sort_data})
        result_data_for_filter, result_sort_data = filter_data, sort_data   
        # print(f"\n\nSAVE || user = {user} || is_ea_created = {is_ea_created} || ea.last_filter_data = {ea.last_filter_data}\n\n")
    elif reset_filter == 'OLD':
        ea, is_ea_created = ExtendAccount.objects.get_or_create(    user=user, 
                                                                    defaults={'last_filter_data': filter_data, 'last_sort_data': sort_data})
        result_data_for_filter = ea.last_filter_data if not is_ea_created else filter_data
        result_sort_data       = ea.last_sort_data   if not is_ea_created else sort_data
        # print(f"\n\nOLD || user = {user} || is_ea_created = {is_ea_created} || ea.last_filter_data = {ea.last_filter_data}\n\n")
    elif reset_filter == 'RESET':
        ea, is_ea_created = ExtendAccount.objects.update_or_create( user=user, 
                                                                    defaults={'last_filter_data': {}, 'last_sort_data': []})
        result_data_for_filter = ea.last_filter_data if not is_ea_created else {}
        result_sort_data       = ea.last_sort_data   if not is_ea_created else {}
    elif reset_filter == 'NOTHINK':
        result_data_for_filter = filter_data
        result_sort_data       = sort_data
    else:
        return JsonResponse({'message': "OK"}) # IMPOSSIBLE INPUT DATA
    LIST_FIELDS = ORIGINAL_WORKSHEET_LIST_FIELDS[:]
    if request.user.groups.filter(name='Менеджеры Спецресурса').exists():
        LIST_FIELDS.append('quantium_wave_worker')
    LIST_FIELDS.append('payment_type_of_work')

    filter_kwargs, list_fields, result_sort_data = userizeDictKeys(request.user, result_data_for_filter), [userizeField(request.user, field) for field in LIST_FIELDS[:]], [userizeField(request.user, field) for field in result_sort_data]  # FIXME ADD USERIZE SORT!!!

    print(f"\n\n============================================================\n=== sort_list = {result_sort_data}\n=== filter_kwargs = {filter_kwargs}\n=== LIST_FIELDS = {list_fields}\n============================================================\n\n")

    sort_list, filter_kwargs, q_objects, LIST_FIELDS = deserializeSortAndFilter(
        raw_sort    = result_sort_data, 
        raw_filter  = filter_kwargs, 
        user        = request.user, 
        list_fields = list_fields,)
    sort_list.append('date_for_work')

    # sort_and_filter_work = time.perf_counter_ns()

    print(f"\n\n============================================================\n=== sort_list = {sort_list}\n=== filter_kwargs = {filter_kwargs}\n=== q_objects = {q_objects}\n=== LIST_FIELDS = {list_fields}\n============================================================\n\n")
    # print(f"reset_filter = {reset_filter}\nfilter_data = {filter_data}\nresult_data_for_filter = {result_data_for_filter}\nfilter_kwargs = {filter_kwargs}\nneed_excel = {need_excel}") # \nea.last_filter_data = {ea.last_filter_data}
    worksheets = WorkSheets.objects.all()
    ### FIXME FIRST!!!
    ### Multiple filters can create duplicates!!!
    # https://docs.djangoproject.com/en/5.0/topics/db/queries/#spanning-multi-valued-relationships 
    # See Note
    ### FIXME IT FIRST!!!
    # for q in q_objects:
    #     worksheets = worksheets.filter(q)
    # print(f"\n\n============================================================\n=== need_excel = {need_excel}\n============================================================\n\n")
    worksheets = worksheets.annotate( quantium_wave_worker=Exists(worksheets.filter(~Q(pk=OuterRef('pk')), Q(**{k: OuterRef(k) for k in ['lying_worker_id', 'date_for_work']}))),)
    worksheets = worksheets.filter(*q_objects, **filter_kwargs)
    # https://stackoverflow.com/questions/78267710/how-to-add-a-duplicate-column-to-a-table
    # Very Thanks willeM_ Van Onsem ....
    worksheets = worksheets.order_by(*sort_list) 
    # print(f"\n\nworkSheet count  = {worksheets.count()}")

    if need_excel == False:
        worksheets = worksheets.annotate(  
                                            created_unix=UnixTimestamp(F('created')), 
                                            date_for_work_unix=UnixTimestamp(F('date_for_work')),
                                            payment_type_of_work=Concat(F('shop_code__shop_region__payment_prefix'), Value('+'), F('work_type__type_of_work'))
                                            )
        total_sum  = worksheets.aggregate(total=Sum(userizeField(user, 'timesheets__amount_of_work_time'), output_field=DecimalField()))['total']
        list_fields[1], list_fields[2] = 'created_unix', 'date_for_work_unix'
        table_data = list(worksheets.values_list(*list_fields))
        list_fields = [originalizeField(field) for field in list_fields]
        response = JsonResponse({'table_data': table_data, 'summ_amount_of_work_time': total_sum, 'FIELDS': list_fields,}, safe=False)

        # end_perf = time.perf_counter_ns()
        # print(f"BODY CREATED IN {(end_perf - perf)/ 10**9}s  ||  FILTER_WORK IN {(sort_and_filter_work - perf) / 10**9}s")

        return response
    # IF NEED EXCEL
    else:
        excel = returnExcel(worksheets, need_excel.get('head', 'BASE_LIST'), head_list = need_excel.get('head_list', None), user=user)
        if need_excel.get('toCheckExport', False) in [True, 'True', 'true', '1', 1, 'ok', 'OK', 'Ok']:
            if request.user.groups.filter(name='СуперМенеджеры Спецресурса').exists():
                # export4payments = [Export4Payment(timesheet=ws.timesheets, is_exported=True, create_user=user) for ws in worksheets]
                export4payments = [Export4Payment(**{'timesheet': TimeSheets.objects.get(workSheet__id=ws.id), 'is_exported': True, 'create_user': user,}) for ws in worksheets]
                # export4payments = []
                # for ws in worksheets:
                #     filter_kwargs = userizeDictKeys(user, {'timesheet__id': ws.id, 'is_exported': True, 'create_user': user,})
                #     export4payments.append(Export4Payment(**filter_kwargs))
                Export4Payment.objects.bulk_create(export4payments)
            else:
                return JsonResponse({'message': "OK"}) # Only SR SUPER Managers can export
        return excel
    return JsonResponse({'message': "OK"}) # IMPOSSIBLE OUTPUT


@require_http_methods("POST")
@user_passes_test(lambda user: has_any_permissions(user, CHANGE_PERMISSIONS))  # FIXME
def changeTypeOfWork(request):
    # FIXME DOC
    DEBUG_THIS_FUNC = False
    payload = json.loads(request.body)
    if payload['action'] == 'CHANGE_TYPE_OF_WORK':
        payload = payload['payload']
        if isinstance(WorkSheets := getSheetByGroup(request.user, 'WorkSheets'), JsonResponse):
            return WorkSheets
        if isinstance(TypeOfWork := getSheetByGroup(request.user, 'TypeOfWork'), JsonResponse):
            return TypeOfWork
        try:
            WorkSheets.objects.filter(id=int(payload['worksheet_id'])
                             ).update(work_type=TypeOfWork.objects.get(type_of_work=payload['type_of_work']), 
                                      update_user=request.user) 
            # if  'DEBUG_THIS_FUNC' in locals() and DEBUG_THIS_FUNC :
            #     print('All Ok')
            return JsonResponse({'message': 'Success'})
        except BaseException as e:
            if  'DEBUG_THIS_FUNC' in locals() and DEBUG_THIS_FUNC :
                raise BaseException( e )
            return JsonResponse({'message': "OK"})
    else:
        return JsonResponse({'message': "OK"}) # IMPOSSIBLE ERROR
    return JsonResponse({'message': "OK"}) # IMPOSSIBLE ERROR


@require_http_methods("POST")
@user_passes_test(lambda user: has_any_permissions(user, CHANGE_PERMISSIONS))  # FIXME
def changeKomandorsNote(request):
    # FIXME DOC
    payload = json.loads(request.body) # {'worksheet_id': id, 'note': note}
    if isinstance(WorkSheets := getSheetByGroup(request.user, 'WorkSheets'), JsonResponse):
        return WorkSheets
    WorkSheets.objects.filter(id=payload['worksheet_id']).update(workplace_note=payload['note'], time_last_change_note_by_shop=dtLib.datetime.now()) 
    # print('NOTE UPDATED!!!')
    return JsonResponse({'message': 'Success'})


@require_http_methods("POST")
@user_passes_test(lambda user: has_any_permissions(user, CHANGE_PERMISSIONS))  # FIXME
def changeSRNote(request):
    # FIXME DOC
    payload = json.loads(request.body) # {'worksheet_id': id, 'note': note}
    if isinstance(WorkSheets := getSheetByGroup(request.user, 'WorkSheets'), JsonResponse):
        return WorkSheets
    WorkSheets.objects.filter(id=payload['worksheet_id']).update(note_from_SR=payload['note']) 
    # print('NOTE UPDATED!!!')
    return JsonResponse({'message': 'Success'})


@require_http_methods("POST")
@user_passes_test(lambda user: has_any_permissions(user, CHANGE_PERMISSIONS))  # FIXME
def changeCancelApp(request):
    # FIXME DOC
    # FIXME NEED TRY AND RETURN ERROR CODE
    payload = json.loads(request.body) # {'worksheet_id': id, }
    # print(f"\n\npayload = {payload}\n\n")
    try: # take ws object if it exist and alone
        if isinstance(WorkSheets := getSheetByGroup(request.user, 'WorkSheets'), JsonResponse):
            return WorkSheets
        if isinstance(TimeSheets := getSheetByGroup(request.user, 'TimeSheets'), JsonResponse):
            return TimeSheets
        ws = WorkSheets.objects.get(id=int(payload['worksheet_id']))
    except BaseException as e:
        print(f"""ERROR changeCancelApp() when get workSheet!!!\npayload = {payload}\nerror = {e}\nerror.args = {e.args}\nerror.__traceback__.tb_frame = {e.__traceback__.tb_frame}""")
        return JsonResponse({'message': 'SHOW_MESSAGE', 'show_message': 'Не найдена заявка. Обновите таблицу'})
 
    td = dtLib.datetime.combine(ws.date_for_work, ws.start_work) - dtLib.datetime.now()
    # print(f"TimeDelta = {td}\ntd.days = {td.days}\nShop_exist = {Shops.objects.filter(shop_code=request.user.username).exists()}\n")
    if td.days <= 0 and request.user.groups.filter(name__in=['Администраторы сети Командор', 'Аналитики Командора']).exists(): 
        return JsonResponse({'message': 'SHOW_MESSAGE', 'show_message': 'До отменяемой заявки должно оставаться больше суток.', })

    try:
        # ws.is_cancel= True if payload.get('is_cancel', None) in ['', 'true', True, 1, '1', 'y', 'yes', 'True'] else False
        # ws.update_user = User.objects.get(username=request.user.username)
        # ws.save()
        if  TimeSheets.objects.filter(workSheet_id=ws.id).exists():
            TimeSheets.objects.filter(workSheet_id=ws.id).delete()
        ws.delete()
        return JsonResponse({'message': 'Success'})
    except Exception as e:
        print(f"""ERROR changeCancelApp() when update workSheet!!!\npayload = {payload}\nerror = {e}\nerror.args = {e.args}\nerror.__traceback__.tb_frame = {e.__traceback__.tb_frame}""")
        return JsonResponse({'message': 'SHOW_MESSAGE', 'show_message': 'Невозможно удалить заявку. Возможно по данной заявке прошла выплата'}) # Fixme


@require_http_methods("POST")
@user_passes_test(lambda user: has_any_permissions(user, CHANGE_PERMISSIONS))  # FIXME
def changeField(request):
    # FIXME DOC
    # FIXME NEED TRY AND RETURN ERROR CODE
    # DEBUG_THIS_FUNC = True
    data = json.loads(request.body)
    action = data.get('action', None)
    user = User.objects.get(username=request.user.username)
    if action == 'CHANGE_WORKSHEET_WORKER_ID':
        try:
            if isinstance(WorkSheets := getSheetByGroup(user, 'WorkSheets'), JsonResponse):
                return WorkSheets
            if isinstance(Workers := getSheetByGroup(user, 'Workers'), JsonResponse):
                return Workers
            if isinstance(Shops       := getSheetByGroup(user,       'Shops'), JsonResponse):
                return Shops
            ws = WorkSheets.objects.get(id=int(data['payload']['worksheet_id']))
            if ws.lying_worker_id != data['payload']['old_worker_id']:
                return JsonResponse({'message': 'OK',  'show_message': 'Сотрудник не назначен. Данные устарели. Обновите таблицу.'})
            td = dtLib.datetime.combine(ws.date_for_work, ws.start_work) - dtLib.datetime.now()
                # FIXME change Shops..... to request.user.groups.filter(name_in='Менеджеры KOMANDOR').exists()
            if td.days <= 0 and Shops.objects.filter(shop_code=request.user.username).exists() and Workers.objects.filter(worker_id=ws.lying_worker_id).exists():
                return JsonResponse({'message': 'OK',  'show_message': 'До начала изменяемой заявки должно оставаться больше суток.'})
            ws.lying_worker_id=int(data['payload']['worker_id'])
            ws.update_user = user
            ws.confirmation_app = True
            ws.save()
            return JsonResponse({'message': 'Success', })
        except BaseException as e:
            print(f"""ERROR changeField() when CHANGE_WORKSHEET_WORKER_ID!!!\npayload = {data}\nerror = {e}\nerror.args = {e.args}\nerror.__traceback__.tb_frame = {e.__traceback__.tb_frame}""")
            return JsonResponse({'message': 'OK', 'show_message': 'Что-то не так в данных'})
    
    elif action == "CHANGE_WORKSHEET_WORK_DATE":
        try:
            if request.user.groups.filter(name='СуперМенеджеры Спецресурса').exists():
                if isinstance(WorkSheets := getSheetByGroup(user, 'WorkSheets'), JsonResponse):
                    return WorkSheets
                ws = WorkSheets.objects.get(id=int(data['payload']['worksheet_id']))
                ws.date_for_work = dtLib.date.fromisoformat(data['payload']['work_date'])
                ws.update_user = user
                ws.save()
                return JsonResponse({'message': 'Success', })
            # print(f"""ERROR changeField() when CHANGE_WORKSHEET_WORK_DATE!!!\npayload = {data}\n""")
        except BaseException as e:
            print(f"""ERROR changeField() when CHANGE_WORKSHEET_WORK_DATE!!!\npayload = {data}\nerror = {e}\nerror.args = {e.args}\nerror.__traceback__.tb_frame = {e.__traceback__.tb_frame}""")
            return JsonResponse({'message': 'OK', 'show_message': 'Что-то не так в данных'})
    
    else:
        print(f"""ERROR changeField() when CHANGE_WORKSHEET_WORKER_ID!!!\npayload = {data}""")
        return JsonResponse({'message': 'OK', 'show_message': 'Что-то не так в данных'})


@require_http_methods("POST")
@user_passes_test(lambda user: has_any_permissions(user, CHANGE_PERMISSIONS))  # FIXME
def changeConformationApp(request):
    # FIXME DOC
    # FIXME NEED TRY AND RETURN ERROR CODE
    # DEBUG_THIS_FUNC = True

    payload = json.loads(request.body)

    if isinstance(WorkSheets := getSheetByGroup(request.user, 'WorkSheets'), JsonResponse):
        return WorkSheets
    if isinstance(Workers := getSheetByGroup(request.user, 'Workers'), JsonResponse):
        return Workers

    if request.user.groups.filter(name='Менеджеры Спецресурса').exists() or Workers.objects.filter(worker_id=int(payload['worker_id'])).exists():

        WorkSheets.objects.filter(id=payload['worksheet_id']).update(
            confirmation_app=True if payload['confirmation_app'] in ['true', True, 1, '1', 'y', 'yes', 'True'] else False,
            lying_worker_id = int(payload['worker_id']) if payload['worker_id'].isnumeric() else None,
            update_user = request.user.id)
        # if 'DEBUG_THIS_FUNC' in locals() and DEBUG_THIS_FUNC:
        #     print(f"Conformation_app => {payload['worksheet_id']} = {payload['confirmation_app']} | {True if payload['confirmation_app'] in ['true', True, 1, '1', 'y', 'yes', 'True'] else False} ")
        return JsonResponse({'message': 'Success'})
    else:
        return JsonResponse({'message': 'Не существующий работник'}) # FIXME


@require_http_methods("POST")
@user_passes_test(lambda user: has_any_permissions(user, CHANGE_PERMISSIONS))  # FIXME
def changeWorkerSkipWork(request):
    '''  # FIXME DOC'''
    DEBUG_THIS_FUNC = True
    payload = json.loads(request.body) # {'worksheet_id': id, }
    # try:
    null_time = dtLib.datetime.strptime('00:00:00', '%H:%M:%S').time()
    if 'DEBUG_THIS_FUNC' in locals() and DEBUG_THIS_FUNC:
        print(f"payload = {payload}")

    if isinstance(WorkSheets := getSheetByGroup(request.user, 'WorkSheets'), JsonResponse):
        return WorkSheets
    if isinstance(Workers := getSheetByGroup(request.user, 'Workers'), JsonResponse):
        return Workers
    if isinstance(TimeSheets := getSheetByGroup(request.user, 'TimeSheets'), JsonResponse):
        return TimeSheets

    work_date = WorkSheets.objects.get(id=int(payload['worksheet_id'])).date_for_work
    if work_date <= PERIOD_RECONCILIATION_OF_RESULTS[0].date():
        return JsonResponse({'message': 'AFTER_RECONCILIATION_ERROR',  'show_message': f'''Невозможно создать заявку на {str(work_date)}.\nCверка до {str(PERIOD_RECONCILIATION_OF_RESULTS[0].date())} завершена {str(PERIOD_RECONCILIATION_OF_RESULTS[1])}.\nДля регистрации данной заявки необходимо написать письмо менеджерам компании "СПЕЦРЕСУРС'''})

    values_for_update={ "grade":                Grades.objects.get(grade_num=2) if payload['is_worker_skip_work'] in ['true', True, 1, '1', 'y', 'yes', 'True'] else None, 
                        "amount_of_work_time" : Decimal(0) if payload['is_worker_skip_work'] in ['true', True, 1, '1', 'y', 'yes', 'True'] else None,
                        "start_work"          : null_time if payload['is_worker_skip_work'] in ['true', True, 1, '1', 'y', 'yes', 'True'] else None,
                          "end_work"          : null_time if payload['is_worker_skip_work'] in ['true', True, 1, '1', 'y', 'yes', 'True'] else None,
                        "worker_id"           : Workers.objects.get(worker_id=int(payload['worker_id'])) if payload['is_worker_skip_work'] in ['true', True, 1, '1', 'y', 'yes', 'True'] else None,
                        "is_worker_skip_work" : True if payload['is_worker_skip_work'] in ['true', True, 1, '1', 'y', 'yes', 'True'] else False  ,  }
    ts, is_created = TimeSheets.objects.update_or_create(workSheet_id=payload['worksheet_id'], defaults = values_for_update)
    
    if is_created: 
        ts.create_user = User.objects.get(username=request.user.username)
    else:
        ts.update_user = User.objects.get(username=request.user.username)
    ts.save()
    # except BaseException as e:
    #     print(f"Не удалось сохранить лувр \n{e}\npayload = {payload}") # FIXME LOGGER ERROR 
    #     add_to_db_error = True
    #     return JsonResponse({'message': 'DB_EROOR'})

    # if 'DEBUG_THIS_FUNC' in locals() and DEBUG_THIS_FUNC:
    #     print(f"worker_id = {payload['worker_id']}")
    #     print(f"APP {payload['worksheet_id']} is_worker_skip_work changed")
    #     w = WorkSheets.objects.get(id=payload['worksheet_id'])
        # print(f"ts = {ts}")
        # print(f"w.timesheets.is_worker_skip_work = {w.timesheets}")

    return JsonResponse({'message': 'Success'})


@require_http_methods("POST")
@user_passes_test(lambda user: has_any_permissions(user, CHANGE_PERMISSIONS))  # FIXME
def FF_saveLUVR(request):
    payload = json.loads(request.body)

    if isinstance(WorkSheets := getSheetByGroup(request.user, 'WorkSheets'), JsonResponse):
        return WorkSheets
    if isinstance(Workers := getSheetByGroup(request.user, 'Workers'), JsonResponse):
        return Workers
    if isinstance(TimeSheets := getSheetByGroup(request.user, 'TimeSheets'), JsonResponse):
        return TimeSheets

    try:
        start_time = dtLib.datetime.fromtimestamp(int(payload['startTime'])/1000, tz=dtLib.timezone.utc).time()
        end_time   = dtLib.datetime.fromtimestamp(int(payload['endTime'])  /1000, tz=dtLib.timezone.utc).time()
        amountOfWorkTime = Decimal(getWorkingHours(start_time, end_time) / 60)
        worksheet = WorkSheets.objects.get(id=int(payload['worksheet_id']))
        worker = Workers.objects.get(worker_id=int(payload['worker_id']))
    except BaseException as e:
        print(f"CANT READ TIME\n{e}\npayload={payload}") #### FIXME LOGGER ERROR
        return JsonResponse({'message': 'BAD_TIME'})
        # raise ValueError("CANT READ TIME") #### FIXME LOGGER ERROR

    work_date = worksheet.date_for_work
    if work_date <= PERIOD_RECONCILIATION_OF_RESULTS[0].date():
        return JsonResponse({'message': 'AFTER_RECONCILIATION_ERROR',  'show_message': f'''Невозможно создать заявку на {str(work_date)}.\nCверка до {str(PERIOD_RECONCILIATION_OF_RESULTS[0].date())} завершена {str(PERIOD_RECONCILIATION_OF_RESULTS[1])}.\nДля регистрации данной заявки необходимо написать письмо менеджерам компании "СПЕЦРЕСУРС'''})

    ### FIXIT PLEASE!!!
    if (request.user.groups.filter(name='Администраторы сети Командор').exists() and 
        isinstance(r := findDuplicate_LUVRS(worksheet, start_time, end_time, worker, request.user), JsonResponse)):
            return r

    try:
        values_for_update={     "worker_id"           : worker,
                                "start_work"          : start_time,
                                  "end_work"          : end_time,
                                "amount_of_work_time" : amountOfWorkTime,
                                "grade"               : Grades.objects.get(grade_num=int(payload['grade'])), 
                                "is_worker_skip_work" : True if payload['is_worker_skip_work'] in ['true', True, 1, '1', 'y', 'yes', 'True'] else False, 
                                }
        ts, is_created = TimeSheets.objects.update_or_create(workSheet = worksheet, defaults = values_for_update)
        if is_created:
            ts.create_user = User.objects.get(username=request.user.username)
        else:
            ts.update_user = User.objects.get(username=request.user.username)
        ts.save()
    except BaseException as e:
        print(f"Не удалось сохранить лувр \n{e}\npayload = {payload}") # FIXME LOGGER ERROR 
        return JsonResponse({'message': 'DB_EROOR'})
    return JsonResponse({'message': 'Success'})


@require_http_methods("POST")
@user_passes_test(lambda user: has_any_permissions(user, DELETE_PERMISSIONS))  # FIXME
# FIXME ALL NOW!!!
# JUST REWRITE ALL!!!
# IT NOW WORK LIKE THAT!!!
def removeApp(request):
    if isinstance(WorkSheets := getSheetByGroup(request.user, 'WorkSheets'), JsonResponse):
        return WorkSheets
    if isinstance(TimeSheets := getSheetByGroup(request.user, 'TimeSheets'), JsonResponse):
        return TimeSheets
    if isinstance(Export4Payment := getSheetByGroup(request.user, 'Export4Payment'), JsonResponse):
        return Export4Payment
    payload = json.loads(request.body)
    print(payload)
    action = payload.get('action', 'None')
    if action == 'removeLUVR':
        TimeSheets.objects.filter(workSheet_id=payload['payload']['worksheet_id']).delete()
        return JsonResponse({'message': 'TIMESHEET_REMOVED'})
    elif action == 'removeAPP':
        WorkSheets.objects.filter(id=payload['payload']['worksheet_id']).delete()
        return JsonResponse({'message': 'APP_REMOVED'})
    elif action == 'changeExportedToExcel' and request.user.groups.filter(name='СуперМенеджеры Спецресурса').exists(): # ONLY SR_Managers can change Export!
        if payload['payload']['exported'] in ['true', True, 1, '1', 'y', 'yes', 'True']:
            # try:
                filter_kwargs = {   'timesheet'     : TimeSheets.objects.get(workSheet__id=int(payload['payload']['worksheet_id'])),
                                    'is_exported'   : True, 
                                    'create_user'   : request.user, }

                Export4Payment.objects.create( **userizeDictKeys(request.user, filter_kwargs) )
                return JsonResponse({'message': 'CREATED_EXPORT'})
            # except BaseException as e:
            #     return JsonResponse({'message': 'OK'})
        else: # if payload['payload']['exported'] not exported!
            # try:
                filter_kwargs = {'timesheet' : TimeSheets.objects.get(workSheet__id=int(payload['payload']['worksheet_id']))}
                Export4Payment.objects.get(**userizeDictKeys(request.user, filter_kwargs)).delete()
                return JsonResponse({'message': 'REMOVED_EXPORT'})
            # except BaseException as e:
            #     return JsonResponse({'message': 'OK'})

    else:
        return JsonResponse({'message': "ACTION UNDERSTUDN'T"})
    return JsonResponse({'message': "IMPOSSIBLE ERROR"})


def returnExcel(data, head: str, head_list = None, user = None):
    '''# FIXME
    input:  data -- sorted&filterd QuerySet 
            head -- head preset
            head_list -- optional, custon head if head = LIST
    output: HttpResponce with excel'''
    
    ENGINE = 'xlsxwriter'
    # ENGINE = 'openpyxl' # MAYBE NEED DELETE?
    HEADS = {
        'BASE_LIST'     : { 'FIELDS' : ['id', 'created', 'date_for_work',  'shop_code__shop_code', 'shop_code__shop_type', 'shop_code__workplace_address', 'work_type__type_of_work', 'workplace_app_note', 'start_work', 'end_work', 'lying_worker_id', 'timesheets__worker_id__worker_id', 'timesheets__start_work', 'timesheets__end_work', 'timesheets__amount_of_work_time', 'timesheets__worker_id__worker_full_name', 'timesheets__grade__grade_num', 'timesheets__is_worker_skip_work', 'workplace_note', 'note_from_SR', 'confirmation_app', 'is_cancel', 'timesheets__export4payment__is_exported',], # 'timesheets__export4payment__date_exported_to_excel', ] #### FIXME NEED TAKE IT FROM REQUEST
                            'HEAD'   : ['Номер заявки в базе данных', 'Время создания заявки', 'Дата работы',  'Код ТТ', 'Тип ТТ', 'Адрес ТТ', 'Вид работ', 'Примечание к заявке', 'Время наччала работы в заявке', 'Время окончания работы в заявке', 'Табельный номер сотрудника из заявки', 'Табельный номер сотрудника по факту', 'Время наччала работы по факту', 'Время окончания работы по факту', 'Фактическое время работы', 'ФИО Сотрудника', 'Оценка работы', 'Сотрудник не вышел', 'Примечание от магазина', 'Ответ от контрагента', 'Подтверждение заявки', 'Заявка отменена', 'Выгружено', ],}, #'Когда выгружено впервые'] #### FIXME FIX THIS SHIT PLEASE
        'exPAY'         : { 'FIELDS' : ['date_for_work', 'shop_code__shop_code', 'shop_code__shop_type', 'timesheets__worker_id__worker_id',    'work_type__type_of_work', 'timesheets__start_work',        'timesheets__end_work',            'timesheets__amount_of_work_time', 'timesheets__worker_id__date_Of_Dismissal', 'timesheets__grade__grade_num', 'workplace_note',         'timesheets__is_worker_skip_work', 'timesheets__worker_id__payment_type__payment_type'        ], 
                            'HEAD'   : ['Дата работы',   'Код ТТ',               'Тип ТТ',               'Табельный номер сотрудника',          'Вид работ',               'Время наччала работы по факту', 'Время окончания работы по факту', 'Фактическое время работы',        'Статус',                                   'Оценка',                       'Примечание от магазина', 'Прогул',                          'Устройство'      ],},    
        'RECONCILIATION': { 'FIELDS' : ['date_for_work',  'shop_code__shop_code', 'shop_code__shop_type', 'shop_code__workplace_address', 'work_type__type_of_work',  'timesheets__amount_of_work_time',],
                            'HEAD'   : ['Дата работы',    'Код ТТ',               'Тип ТТ',               'Адрес ТТ',                     'Вид работ',                'Фактическое время работы',], },
        # 'exPAY_S'       : { 'FIELDS' : ['date_for_work', 'shop_code__shop_code', 'timesheets__worker_id__worker_id',    'work_type__type_of_work', 'timesheets__start_work',        'timesheets__end_work',            'timesheets__amount_of_work_time', 'timesheets__worker_id__date_Of_Dismissal', 'timesheets__grade__grade_num', 'workplace_note',         'timesheets__is_worker_skip_work', 'timesheets__worker_id__payment_type__payment_type'       ], 
        #                     'HEAD'   : ['Дата работы',   'Код ТТ',               'Табельный номер сотрудника по факту', 'Вид работ',               'Время наччала работы по факту', 'Время окончания работы по факту', 'Фактическое время работы',        'Статус',                                   'Оценка',                       'Примечание от магазина', 'Прогул',                          'ЗАНЯТОСТЬ'    ],},    
            }
    
    if head == 'BASE_LIST':
        table_head = [userizeField(user, field) for field in HEADS['BASE_LIST']['FIELDS'][:]]
        df = pd.DataFrame(data.values_list(*table_head))
        df[1] = df[1].dt.tz_localize(None) # EXCEL NOT UNDERSTAND DATETIME_WITH_TZ
        df[14] = df[14].astype('float')
        df[17] = df[17].map({True: 'Прогул', False: ''})
        df[20] = df[20].map({True: 'Заявка подтверждена', False: ''})
        df[21] = df[21].map({True: 'Заявка отменена', False: ''})
        # df[23] = df[23].dt.tz_localize(None) # EXCEL NOT UNDERSTAND DATETIME_WITH_TZ

    elif head == 'exPAY':
        table_head = [userizeField(user, field) for field in HEADS['exPAY']['FIELDS'][:]]
        # ПРИСТАВКА_ВИДА_КОНТРАГЕНТА, ПРИСТАВКА_ВИДА_МАГАЗИНА, ПРИСТАВКА_РЕГИОНА, ВИД_РАБОТЫ
        if user.groups.filter(name='Отдел обслуживания'):
            data = data.annotate(
                # payment_type_of_work=Concat(F('shop_code__shop_region__payment_prefix'), F('work_type__type_of_work'), output_field=CharField()),
                counterparty_prefix=Case(When(**{userizeField(user, 'timesheets__worker_id__payment_type__payment_type'):'САМОЗАНЯТЫЙ - СПЕЦРЕСУРС'}, then=Value('-')), default=Value(''), output_field=CharField(),),
                shop_type_prefix=
                    Case(
                        When(Q(shop_code__shop_type='Фрешмаркет') & Q(shop_code__shop_region__location='Красноярск'), then=Value('ф) ')),
                        When(shop_code__shop_type='Фрешмаркет', then=Value('ф')), default=Value(''),
                    output_field=CharField(),),      )
            # Создаем новый столбец путем конкатенации
            data = data.annotate(new_column=Concat(F('counterparty_prefix'), F('shop_type_prefix'), F('shop_code__shop_region__payment_prefix'),  F('work_type__type_of_work'), output_field=CharField(),) )
            # NEED MODIFY TABLE HEAD
            table_head[4] = 'new_column'
        elif user.groups.filter(name='Служба Контроля'):
            data = data.annotate(ss_type_of_work=Case(When(work_type__type_of_work='Менеджер Службы Контроля', then=Value('МСК')), default=F('work_type__type_of_work')))
            table_head[4] = "ss_type_of_work"
        elif user.groups.filter(name='Разгуляй'):
            pass
        else:
            return JsonResponse({'message': 'OK'})
        data = data.values_list(*table_head)

        if len(data) < 1:
            return JsonResponse({'message': 'OK'})

        df = pd.DataFrame(data)
        # SHOP_TYPE_PREFIX = {'Фрешмаркет': 'ф', 'Дискаунтер': '', 'Суперстор': ''}
        # df[13] = ( df[2].map(SHOP_TYPE_PREFIX).fillna('ERROR') + df[4])
        # df[13] = ( df[13].map().fillna('ERROR') + df[4])
        # del df[2]
        # del HEADS['exPAY']['FIELDS'][2]
        # print(df)
        df[7]  = df[7].astype('float')
        df[8]  = df[8].map( lambda x: '' if str(x) in ['None', '', 'NaT', False, 'False'] else 'УВОЛЕН')
        df[11] = df[11].map(lambda x: '' if str(x) in ['None', '', 'NaT', False, 'False'] else 'Прогул')

    # elif head == 'exPAY_S':
    #     df = pd.DataFrame(data.values_list(*HEADS['exPAY_S']['FIELDS']))
    #     df[6]  = df[6].astype('float')
    #     df[7]  = df[7].map( lambda x: '' if str(x) in ['None', '', 'NaT', False, 'False'] else 'УВОЛЕН')
    #     df[10] = df[10].map(lambda x: '' if str(x) in ['None', '', 'NaT', False, 'False'] else 'Прогул')

    elif head == 'RECONCILIATION':
        start_perf = time.perf_counter_ns()
        table_head = [userizeField(user, field) for field in HEADS['RECONCILIATION']['FIELDS'][:]]
        df = pd.DataFrame(data.values_list(*table_head))
        perf_created_dataframe = time.perf_counter_ns()
        df = df.rename(columns={idx: col_name for idx, col_name in enumerate(HEADS[head]['HEAD'])})
        pivot_table = pd.pivot_table(df, 
                                         index=['Код ТТ', 'Тип ТТ', 'Адрес ТТ', 'Дата работы', 'Вид работ',],
                                        values=['Фактическое время работы',],
                                       aggfunc=[len, np.sum, ],
                                    )
        perf_created_pivot = time.perf_counter_ns()
        response = HttpResponse(content_type='application/ms-excel')
        response['Content-Disposition'] = 'attachment; filename="file.xlsx"'
        pivot_table.to_excel(response, float_format="%.1f", engine=ENGINE) # index=False, 
        perf_created_excel = time.perf_counter_ns()
        print(f"df = {(perf_created_dataframe - start_perf) / 10**9}  |  pv = {(perf_created_pivot - perf_created_dataframe) / 10**9}  |  excel = {(perf_created_excel - perf_created_pivot) / 10**9}")
        return response 

    df = df.rename(columns={idx: col_name for idx, col_name in enumerate(HEADS[head]['HEAD'])})
    response = HttpResponse(content_type='application/ms-excel')
    response['Content-Disposition'] = 'attachment; filename="file.xlsx"'
    df.to_excel(response, index=False, float_format="%.1f")
    return response


def checkDupplicatLUVRInDB(date_for_work, start_time, end_time, worker, user):
    '''# FIXME! '''
    # I know, that in this q exist error!
    q = Q(workSheet__date_for_work=date_for_work, worker_id=worker) & (
            Q(start_work__gte=start_time, start_work__lte=end_time) |
            Q(  end_work__gte=start_time,   end_work__lte=end_time) |
            Q(start_work__lte=start_time,   end_work__gte=end_time))
    if isinstance(TimeSheets := getSheetByGroup(user, 'TimeSheets'), JsonResponse):
        return TimeSheets
    return TimeSheets.objects.filter(q)


def findDuplicate_LUVRS(worksheet, start_time, end_time, worker, user):
    if start_time > end_time:
        midnight = dtLib.time(0, 0)
        before_midnight = dtLib.time(23, 59, 59)
        next_day = worksheet.date_for_work + dtLib.timedelta(days=1)

        dupplicate_luvr_qs = checkDupplicatLUVRInDB(worksheet.date_for_work, start_time, before_midnight, worker, user)
        if dupplicate_luvr_qs.count() > 0:
            return findedDupplicateLUVR(dupplicate_luvr_qs, worker)
        dupplicate_luvr_qs = checkDupplicatLUVRInDB(next_day, midnight, end_time, worker, user)
        if dupplicate_luvr_qs.count() > 0:
            return findedDupplicateLUVR(dupplicate_luvr_qs, worker)
    else:
        dupplicate_luvr_qs = checkDupplicatLUVRInDB(worksheet.date_for_work, start_time, end_time, worker, user)
        if dupplicate_luvr_qs.count() > 0:
            return findedDupplicateLUVR(dupplicate_luvr_qs, worker)


def findedDupplicateLUVR(dupplicate_luvr_qs, worker):
    return JsonResponse(
        {'message': 'DUPPLICATE',  
        'show_message': f'Сотрудник {worker.worker_full_name} в это время работал на {dupplicate_luvr_qs[0].workSheet.shop_code.shop_code} {str(dupplicate_luvr_qs[0].workSheet.date_for_work)} с {str(dupplicate_luvr_qs[0].start_work)} по {str(dupplicate_luvr_qs[0].end_work)} поэтому лувр не может быть зарегистрирован.', })

```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/FF_LUVR_filter.py"
```
from django.db.models                   import Q

# from .models                            import Shops

import datetime                         as dtLib

from decimal                            import Decimal

from .helpers                           import originalizeField





def deserializeSortAndFilter(raw_sort, raw_filter, user = False, list_fields = []):
    sorts   = raw_sort   if raw_sort   != None else []  # FIXME JUST SET DEFAULT!!!
    filters = raw_filter if raw_filter != None else {}  # FIXME JUST SET DEFAULT!!!

    # try:
    #     filters['shop_code__shop_code'] = [user.shopuser.shop.shop_code] # FIXME MANAGER INTERFACE!!!
    # except:
    #     pass

    try:
        if user.groups.filter(name='Администраторы сети Командор'):
            if user.groups.filter(Q(name='Отдел обслуживания') | Q(name='Служба Контроля')):
                filters['shop_code__shop_code'] = [user.kshopuser.shop.shop_code]
                print( f"'{user.kshopuser.shop.shop_code}'")
            elif user.groups.filter(name='Разгуляй'):
                filters['shop_code__shop_code'] = [user.razgulayshopuser.shop.shop_code]
            else:
                return JsonResponse({'message': 'OK'}) #400 #### FIXME 400??? NEED LOGGER
        # else:
        #     try:
        #         tmpWorkPlace  = Shops.objects.get(shop_code=data.get('shop'))
        #     except:
        #         return JsonResponse({'message': 'OK'}) #400 #### FIXME 400??? NEED LOGGER
    except:
        return JsonResponse({'message': 'OK'}) #400 #### FIXME 400??? NEED LOGGER

    q_objects = []
    filter_kwargs = {}
    for field, value in filters.items():
        if field in list_fields:
            f, n = getValues4Filter(originalizeField(field), value)
            if len(f) > 0 and n:
                q_objects.append(Q(**{f'{field}__isnull': True}) | Q(**{f'{field}__in': f})) # |= Q(**{f'{field}__isnull': True}) | Q(**{f'{field}__in': f})
            elif len(f) > 0 and not n:
                filter_kwargs[f'{field}__in'] = f
            elif len(f) == 0 and n:
                filter_kwargs[f'{field}__isnull'] = True

    sort_list = [s for s in sorts if (s in list_fields or s[1:] in list_fields)]
    return sort_list, filter_kwargs, q_objects, list_fields


def getSortAndFilter(sorts, filters):
    pass


# def getSortAndFilterFromRequest(raw_sort, raw_filter, append_shop_in_filter = False):
#     # FIXME DOC PLEASE!!!
#     sorts   = raw_sort   if raw_sort   != None else {}
#     filters = raw_filter if raw_filter != None else []

#     # if 'DEBUG_THIS_FUNC' in locals() and DEBUG_THIS_FUNC:
#     #     print(f"\n\nsorts = {sorts}\n\nfilters = {filters}\n\n")

#     LIST_FIELDS = ['id', 'created', 'date_for_work',  'shop_code__shop_code', 'shop_code__shop_type', 'shop_code__workplace_address', 'work_type__type_of_work', 'workplace_app_note', 'start_work', 'end_work', 'worker_id__worker_id', 'timesheets__worker_id__worker_id', 'timesheets__start_work', 'timesheets__end_work', 'timesheets__amount_of_work_time', 'timesheets__worker_id__worker_full_name', 'timesheets__grade__grade_num', 'timesheets__is_worker_skip_work', 'workplace_note', 'note_from_SR', 'confirmation_app', 'is_cancel'] #### FIXME NEED TAKE IT FROM REQUEST

#     if (append_shop_in_filter != False and Shops.objects.filter(shop_code=append_shop_in_filter).exists()):
#         filters['shop_code__shop_code'] = [append_shop_in_filter] # FIXME MANAGER INTERFACE!!!
    
#     q_objects = [] # Q()
#     filter_kwargs = {}
#     for field, value in filters.items():
#         if field in LIST_FIELDS:
#             f, n = getValues4Filter(field, value)
#             if len(f) > 0 and n:
#                 q_objects.append(Q(**{f'{field}__isnull': True}) | Q(**{f'{field}__in': f})) # |= Q(**{f'{field}__isnull': True}) | Q(**{f'{field}__in': f})
#             elif len(f) > 0 and not n:
#                 filter_kwargs[f'{field}__in'] = f
#             elif len(f) == 0 and n:
#                 filter_kwargs[f'{field}__isnull'] = True

#     sort_list = [s for s in sorts if (s in LIST_FIELDS or s[1:] in LIST_FIELDS)]

#     # if 'DEBUG_THIS_FUNC' in locals() and DEBUG_THIS_FUNC:
#     #     print(f"q_objects = {q_objects}")
#     return sort_list, filter_kwargs, q_objects, LIST_FIELDS


def getValues4Filter(field, value):
    '''Type conversion: Strings from JSON to types required for ORM '''
    relations = {
        'TO_DATETIME' : ['created', 'timesheets__export4payment__date_exported_to_excel'],
        'TO_DATE'     : ['date_for_work'],
        'TO_TIME'     : ['start_work', 'end_work', 'timesheets__start_work', 'timesheets__end_work',],
        'TO_INT'      : ['lying_worker_id', 'timesheets__worker_id__worker_id', 'timesheets__grade__grade_num'],
        'TO_DECIMAL'  : ['timesheets__amount_of_work_time'],
        'TO_BOOLEAN'  : ['timesheets__is_worker_skip_work', 'confirmation_app', 'is_cancel', 'timesheets__export4payment__is_exported', "quantium_wave_worker"] }

    conversion_functions = {
        'TO_DATETIME': lambda v: dtLib.datetime.strptime(v, "%Y-%m-%dT%H:%M:%S.%f%z"),
        'TO_DATE': dtLib.date.fromisoformat,
        'TO_TIME': dtLib.time.fromisoformat,
        'TO_INT': int,
        'TO_DECIMAL': Decimal,
        'TO_BOOLEAN': lambda v: True if v in [True, 'true', 'True', 1, '1', 'ok', 'Ok', 'OK'] else False # bool
        }

    ans, isnull = [], False
    type_field = [f for f, v in relations.items() if field in v] 
    type_field = type_field[0] if len(type_field) > 0 else field
    for v in value:
        if v != 'null':
            func = conversion_functions.get(type_field, lambda x: x)
            ans.append(func(v))
        else:
            isnull = True
    return ans, isnull


if __name__ == "__main__":
    pass
```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/helpers.py"
```
import re

from datetime                           import time

from django.db.models                   import Q
from django.http                        import JsonResponse

from .models                            import KWorkers,  KWorkSheets,  KTimeSheets,  KExport4Payment,  KTypeOfWork,  KShop,  KShopUser
from .models                            import SSWorkers, SSWorkSheets, SSTimeSheets, SSExport4Payment, SSTypeOfWork
from .models                            import RazgulayWorkers, RazgulayWorkSheets, RazgulayTimeSheets, RazgulayExport4Payment, RazgulayTypeOfWork, RazgulayShop, RazgulayShopUser

VIEW_PERMISSIONS   = ['KRSK_WorkSheets.view_ktimesheets',   'KRSK_WorkSheets.view_sstimesheets',   'KRSK_WorkSheets.view_razgulaytimesheets']
CHANGE_PERMISSIONS = ['KRSK_WorkSheets.change_ktimesheets', 'KRSK_WorkSheets.change_sstimesheets', 'KRSK_WorkSheets.change_razgulaytimesheets']
DELETE_PERMISSIONS = ['KRSK_WorkSheets.delete_ktimesheets', 'KRSK_WorkSheets.delete_sstimesheets', 'KRSK_WorkSheets.delete_razgulaytimesheets']

BASE_KWORKSHEET_LIST_FIELDS  =  ['id', 'created', 'date_for_work',  'shop_code__shop_code', 'shop_code__shop_type', 'shop_code__workplace_address', 'work_type__type_of_work', 'workplace_app_note', 'start_work', 'end_work', 'lying_worker_id', 'ktimesheets__worker_id__worker_id',   'ktimesheets__start_work',  'ktimesheets__end_work',  'ktimesheets__amount_of_work_time',  'ktimesheets__worker_id__worker_full_name',  'ktimesheets__grade__grade_num',  'ktimesheets__is_worker_skip_work', 'workplace_note', 'note_from_SR', 'confirmation_app', 'is_cancel',   'ktimesheets__kexport4payment__is_exported',  'ktimesheets__worker_id__payment_type__payment_type', 'shop_code__shop_region__id',  'ktimesheets__worker_id__payment_type__id']
BASE_SSWORKSHEET_LIST_FIELDS =  ['id', 'created', 'date_for_work',  'shop_code__shop_code', 'shop_code__shop_type', 'shop_code__workplace_address', 'work_type__type_of_work', 'workplace_app_note', 'start_work', 'end_work', 'lying_worker_id', 'sstimesheets__worker_id__worker_id', 'sstimesheets__start_work', 'sstimesheets__end_work', 'sstimesheets__amount_of_work_time', 'sstimesheets__worker_id__worker_full_name', 'sstimesheets__grade__grade_num', 'sstimesheets__is_worker_skip_work', 'workplace_note', 'note_from_SR', 'confirmation_app', 'is_cancel', 'sstimesheets__ssexport4payment__is_exported', 'sstimesheets__worker_id__payment_type__payment_type', 'shop_code__shop_region__id', 'sstimesheets__worker_id__payment_type__id']
BASE_RAZGULAYWORKSHEET_LIST_FIELDS =  ['id', 'created', 'date_for_work',  'shop_code__shop_code', 'shop_code__shop_type', 'shop_code__workplace_address', 'work_type__type_of_work', 'workplace_app_note', 'start_work', 'end_work', 'lying_worker_id', 'razgulaytimesheets__worker_id__worker_id', 'razgulaytimesheets__start_work', 'razgulaytimesheets__end_work', 'razgulaytimesheets__amount_of_work_time', 'razgulaytimesheets__worker_id__worker_full_name', 'razgulaytimesheets__grade__grade_num', 'razgulaytimesheets__is_worker_skip_work', 'workplace_note', 'note_from_SR', 'confirmation_app', 'is_cancel', 'razgulaytimesheets__razgulayexport4payment__is_exported', 'razgulaytimesheets__worker_id__payment_type__payment_type', 'shop_code__shop_region__id', 'razgulaytimesheets__worker_id__payment_type__id']

TABLE_RELATION_BY_USER = {
        'Отдел обслуживания': { 'WorkSheets'        : KWorkSheets, 
                                'TimeSheets'        : KTimeSheets, 
                                'Export4Payment'    : KExport4Payment,
                                'TypeOfWork'        : KTypeOfWork,
                                'Workers'           : KWorkers,    
                                'Shops'             : KShop,
                                'ShopUser'          : KShopUser,           
                                'BASE_WORKSHEET_LIST_FIELDS': BASE_KWORKSHEET_LIST_FIELDS,
                                'GROUP'             : 'Отдел обслуживания',
                                'SHOP_PREFIX'       : '',
                                'field_prefix'      : 'k',
                                },
        'Служба Контроля':    { 'WorkSheets'        : SSWorkSheets, 
                                'TimeSheets'        : SSTimeSheets, 
                                'Export4Payment'    : SSExport4Payment,
                                'TypeOfWork'        : SSTypeOfWork,
                                'Workers'           : SSWorkers,     
                                'Shops'             : KShop,
                                'ShopUser'          : KShopUser,                        
                                'BASE_WORKSHEET_LIST_FIELDS': BASE_SSWORKSHEET_LIST_FIELDS,
                                'GROUP'             : 'Служба Контроля',
                                'SHOP_PREFIX'       : 'С',
                                'field_prefix'      : 'ss',
                                },
        'Разгуляй':         {   'WorkSheets'        : RazgulayWorkSheets, 
                                'TimeSheets'        : RazgulayTimeSheets, 
                                'Export4Payment'    : RazgulayExport4Payment,
                                'TypeOfWork'        : RazgulayTypeOfWork,
                                'Workers'           : RazgulayWorkers,                             
                                'Shops'             : RazgulayShop,
                                'ShopUser'          : RazgulayShopUser,   
                                'BASE_WORKSHEET_LIST_FIELDS': BASE_RAZGULAYWORKSHEET_LIST_FIELDS,
                                'GROUP'             : 'Разгуляй',
                                'SHOP_PREFIX'       : '',
                                'field_prefix'      : 'razgulay',
                                },
                        }


def getWorkingHours(startTime, endTime):
    '''  # FIXME '''
    start_in_minute = startTime.minute + startTime.hour * 60
    end_in_minute   =   endTime.minute +   endTime.hour * 60
    subtract_in_minute = end_in_minute - start_in_minute if (end_in_minute - start_in_minute) > 0 else end_in_minute + 1440 - start_in_minute
    if subtract_in_minute > 390 and subtract_in_minute < 540:
        subtract_in_minute -= 30
    elif subtract_in_minute >= 540 and subtract_in_minute < 750:
        subtract_in_minute -= 60
    elif subtract_in_minute >= 750:
        subtract_in_minute -= 90
    return subtract_in_minute


def getSheetByGroup(user, table: str):
    '''  # FIXME'''
    # try:
    if True:
        if user.groups.filter(name='Отдел обслуживания').exists():  # FIXME!!! THIS VERY PERFORMANCE DEGRATED
            return TABLE_RELATION_BY_USER['Отдел обслуживания'][table]
        elif user.groups.filter(name='Служба Контроля').exists():
            return TABLE_RELATION_BY_USER['Служба Контроля'][table]
        elif user.groups.filter(name='Разгуляй').exists():
            return TABLE_RELATION_BY_USER['Разгуляй'][table]
        else:
            raise AssertionError('ERROR IN getSheetByGroup()')
    # except BaseException:
    #     return JsonResponse({'message': 'OK'})


def has_any_permissions(user, perms: list):
    return any((user.has_perm(perm) for perm in perms))


def has_all_permissions(user, perms: list):
    return all((user.has_perm(perm) for perm in perms))


def originalizeField(text):
    pattern = r'(k|ss|razgulay)(workers|worksheets|timesheets|export4payment|typeofwork)'
    replacement = r'\2'  # заменяем на вторую группу (без префикса)
    return re.sub(pattern, replacement, text)


# def userizeField(user, text):
#     pattern = r"\b(workers|worksheets|timesheets|export4payment)\b"
#     replacement = r"k\1"  # getSheetByGroup(user, 'field_prefix') + r"\1"
#     ans = re.sub(pattern, replacement, text)
#     print(f'''replacement = "{replacement}"    ||    userizeField({user}, {text}) = {ans} ''')
#     return ans


def userizeField(user, text):
    repl = getSheetByGroup(user, 'field_prefix')
    magic_words = ['workers', 'worksheets', 'timesheets', 'export4payment']
    for word in magic_words:  # FIXME!!! PERFORMANCE GEGRADED
        text = text.replace(word, repl + word)    
    return text


def userizeDictKeys(user, d: dict):
    return {userizeField(user, k): v for k, v in d.items()}  # FIXME!!! PERFORMANCE GEGRADED


def originalieDictKeys(d: dict):
    return {originalizeField(k): v for k, v in d.items()}  # FIXME!!! PERFORMANCE GEGRADED
```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/models.py"
```
# import time as timeLib
# import datetime as dtLib

from django.db import models
# from django.contrib.auth.models import User # 4 Extending
from django.contrib.auth import get_user_model
# from django.utils.translation import gettext_lazy as _
from auditlog.registry import auditlog

from .base_models import TrackableDateModel, BaseWorkSheets, BaseTimeSheets, BaseExport4Payment, BaseWorkers, BaseTypeOfWork, BaseShop, BaseShopUser


User = get_user_model()


class KShop(BaseShop):
    pass


class KShopUser(BaseShopUser):
    shop = models.ForeignKey(KShop, related_name="shopuser_%(app_label)s_%(class)s_related", on_delete=models.CASCADE)


### Komandor Worker Table
class KWorkSheets(BaseWorkSheets):
    work_type = models.ForeignKey('KTypeOfWork', on_delete = models.PROTECT,  null=True,  # FIXME
        help_text="Название вакансии", verbose_name="Вид Работ")
    shop_code = models.ForeignKey('KShop', related_name="worksheets_shop_code_%(app_label)s_%(class)s_related", on_delete = models.PROTECT,  null=True,  # FIXME
        help_text="Код Торговой Точки", verbose_name="Код ТТ")

class KTimeSheets(BaseTimeSheets):
    workSheet = models.OneToOneField('KWorkSheets', on_delete=models.CASCADE, null=True, blank=True, unique=True)
    worker_id = models.ForeignKey('KWorkers', related_name="timesheets_worker_id_%(app_label)s_%(class)s_related", on_delete = models.PROTECT, null=True,
        help_text="Табельный номер работавшего сотрудника", verbose_name="Табельный номер") #default=Workers.get_default_pk()) #### FIXME worker_id must be null=False, blank=False


class KExport4Payment(BaseExport4Payment):
    timesheet = models.OneToOneField('KTimeSheets', on_delete=models.CASCADE, null=True, blank=True, unique=True)


class KWorkers(BaseWorkers):
    pass


class KTypeOfWork(BaseTypeOfWork):
    pass


### Security Service Komandor Table
class SSWorkSheets(BaseWorkSheets):
    work_type = models.ForeignKey('SSTypeOfWork', on_delete = models.PROTECT,  null=True,  # FIXME
        help_text="Название вакансии", verbose_name="Вид Работ")
    shop_code = models.ForeignKey('KShop', related_name="worksheets_shop_code_%(app_label)s_%(class)s_related", on_delete = models.PROTECT,  null=True,  # FIXME
        help_text="Код Торговой Точки", verbose_name="Код ТТ")


class SSTimeSheets(BaseTimeSheets):
    workSheet = models.OneToOneField('SSWorkSheets', on_delete=models.CASCADE, null=True, blank=True, unique=True)
    worker_id = models.ForeignKey('SSWorkers', related_name="timesheets_worker_id_%(app_label)s_%(class)s_related", on_delete = models.PROTECT, null=True,
        help_text="Табельный номер работавшего сотрудника", verbose_name="Табельный номер") #default=Workers.get_default_pk()) #### FIXME worker_id must be null=False, blank=False


class SSExport4Payment(BaseExport4Payment):
    timesheet = models.OneToOneField('SSTimeSheets', on_delete=models.CASCADE, null=True, blank=True, unique=True)


class SSWorkers(BaseWorkers):
    pass


class SSTypeOfWork(BaseTypeOfWork):
    pass


### Razgulay Worker Table
class RazgulayShop(BaseShop):
    pass


class RazgulayShopUser(BaseShopUser):
    shop = models.ForeignKey(RazgulayShop, related_name="shopuser_%(app_label)s_%(class)s_related", on_delete=models.CASCADE)


class RazgulayWorkSheets(BaseWorkSheets):
    work_type = models.ForeignKey('RazgulayTypeOfWork', on_delete = models.PROTECT,  null=True,  # FIXME
        help_text="Название вакансии", verbose_name="Вид Работ")
    shop_code = models.ForeignKey('RazgulayShop', related_name="worksheets_shop_code_%(app_label)s_%(class)s_related", on_delete = models.PROTECT,  null=True,  # FIXME
        help_text="Код Торговой Точки", verbose_name="Код ТТ")


class RazgulayTimeSheets(BaseTimeSheets):
    workSheet = models.OneToOneField('RazgulayWorkSheets', on_delete=models.CASCADE, null=True, blank=True, unique=True)
    worker_id = models.ForeignKey('RazgulayWorkers', related_name="timesheets_worker_id_%(app_label)s_%(class)s_related", on_delete = models.PROTECT, null=True,
        help_text="Табельный номер работавшего сотрудника", verbose_name="Табельный номер") #default=Workers.get_default_pk()) #### FIXME worker_id must be null=False, blank=False


class RazgulayExport4Payment(BaseExport4Payment):
    timesheet = models.OneToOneField('RazgulayTimeSheets', on_delete=models.CASCADE, null=True, blank=True, unique=True)


class RazgulayWorkers(BaseWorkers):
    pass


class RazgulayTypeOfWork(BaseTypeOfWork):
    pass


class Locations(models.Model):
    location = models.CharField(help_text="Направление обслуживания", verbose_name="Направление", 
                                max_length=500, unique=True, default="Красноярск") # FIXME DEFAULT WTF?
    payment_prefix = models.CharField(help_text="Префикс для таблиц оплаты", verbose_name="Префикс", 
                                max_length=500, unique=True, null=True, blank=True) # FIXME DEFAULT WTF?

    def __unicode__(self):
        return str(self.location)

    def __str__(self):
        return str(self.location)


class Grades(models.Model):
    grade_num = models.IntegerField(help_text="Оценка (цифра, используется для формул)", verbose_name="Оценка", unique=True)
    grade_desc = models.CharField(help_text="Отображаемый текст оценки", verbose_name="Текст оценки", max_length=100, unique=True)

    class Meta:
        ordering = ["-grade_num"]

    def __unicode__(self):
        return str(f'{self.grade_num}) {self.grade_desc}')

    def __str__(self):
        return str(f'{self.grade_num}) {self.grade_desc}')


class PaymentType(models.Model):
    payment_type = models.CharField(max_length=100, help_text="Кто и как оплачивает", null=True, blank=True, verbose_name="Кто оплачивает")    # FIXME FK?

    def __unicode__(self):
        return str(f'{self.payment_type}')

    def __str__(self):
        return str(f'{self.payment_type}')


class ExtendAccount(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    last_filter_data = models.JSONField(default=dict)
    last_sort_data   = models.JSONField(default=list)
    changed_password = models.CharField(max_length=128, null=True, blank=True,)

    # @staticmethod
    # def get_default_filter():
    #     return {'filter': {}, 'sort': []}


auditlog.register(KWorkSheets)
auditlog.register(KTimeSheets)
auditlog.register(KExport4Payment)
auditlog.register(KWorkers)
auditlog.register(SSWorkSheets)
auditlog.register(SSTimeSheets)
auditlog.register(SSExport4Payment)
auditlog.register(SSWorkers)
auditlog.register(RazgulayWorkSheets)
auditlog.register(RazgulayTimeSheets)
auditlog.register(RazgulayExport4Payment)
auditlog.register(RazgulayWorkers)

############################################################
### TARIFFS
############################################################
# class BaseTarif(models.Model):
#     '''# FIXME '''
#     # kontr_agent = models.ForeignKey('KontrAgent', on_delete = models.SET_NULL, blank=True, null=True) # FIXME
#     location = models.ForeignKey('Locations', on_delete = models.SET_NULL, blank=True, null=True)
#     work_type = models.ForeignKey('TypeOfWork', on_delete = models.SET_NULL, blank=True, null=True)
#     taxation_type = models.ForeignKey('TypeOfTaxation', on_delete = models.SET_NULL, blank=True, null=True,)
#     сounterparty_payment = models.DecimalField(max_digits=11, decimal_places=2, default=0, help_text="Оплата за ед. от контрагента", verbose_name="Доход", )
#     employee_payment     = models.DecimalField(max_digits=11, decimal_places=2, default=0, help_text="Оплата за ед. сотруднику",     verbose_name="Расход",)


# class PersonalBonus(models.Model):
#     bonus = models.DecimalField(max_digits=11, decimal_places=2, default=0, help_text="Для штрафа поставьте знак минус",     verbose_name="Премия", )
#     timesheet = models.OneToOneField('TimeSheets', on_delete=models.CASCADE)


# class GradeBonus(models.Model):
#     # kontr_agent = models.ForeignKey('KontrAgent', on_delete = models.SET_NULL, blank=True, null=True) # FIXME
#     location = models.ForeignKey('Locations', on_delete = models.SET_NULL, blank=True, null=True)
#     grade = models.ForeignKey('Grade', on_delete = models.SET_NULL, blank=True, null=True)
#     taxation_type = models.ForeignKey('TypeOfTaxation', on_delete = models.SET_NULL, blank=True, null=True,)
#     bonus = models.DecimalField(max_digits=11, decimal_places=2, default=0, help_text="Для штрафа поставьте знак минус",     verbose_name="Премия", )


# class TypeOfTaxation(models.Model):
#     taxation_type = models.CharField(help_text="Как трудоустроен сотрудник", verbose_name="Вид договора (самозанятый?)", max_length=100, unique=True)











# class ExtendsShopManagerAccounts(models.Model):
#     user = models.OneToOneField(User, on_delete=models.CASCADE)
#     snShop = models.OneToOneField('Shops', on_delete=models.CASCADE)


# class ViUsers(models.Model):
#     """    Viber Users and base information about chats    """, 
#     viberChatID = models.CharField(max_length=24, unique=True, null=True,
#                                    help_text="ID чата с этим вибер-аккаунтом",
#                                    verbose_name="ID Чата Вибер") # FIXME (Мне хватит символов?)
#     # DEFAULT_BIG_BANG_TIME = dtLib.datetime(dtLib.datetime.min.year,    # FIXME ?
#     #                                             dtLib.datetime.min.month,    # IS IT NEED ME?
#     #                                             dtLib.datetime.min.day, 
#     #                                             dtLib.datetime.min.hour, 
#     #                                             dtLib.datetime.min.minute)   
#     timeSubscribe = models.DateTimeField(auto_now=False, auto_now_add=True, null=True, blank=True,
#                                          help_text="Время первого сообщения с этим вибер-аккаунтом", 
#                                          verbose_name="Подписан",  )
#     timeUnSubscribe = models.DateTimeField(auto_now=False, auto_now_add=False, null=True, blank=True, 
#                                            help_text="Время отписки",
#                                            verbose_name="Отписан")
#     JUST_WORKER                 = 'JW'
#     ABSOLUTE_ADMINISTRATOR      = 'AA'
#     SPECRESURS_MANAGER          = 'SR'
#     KOMMANDORS_MANAGER          = 'KM'
#     viROLEList = [(JUST_WORKER,                'WORKER'),
#                   (ABSOLUTE_ADMINISTRATOR,     'ADMIN'),
#                   (SPECRESURS_MANAGER,         'SR_MANAGER'),
#                   (KOMMANDORS_MANAGER,         'KOMMANDORS_MANAGER')]
#     viROLE = models.CharField(max_length=2, help_text="Роль", choices=viROLEList, default=JUST_WORKER, verbose_name="Роль") # IT'S MUST BE AT SHEET? FIXME 

# class Meta:
#     ordering = ["-timeSubscribe"]

# def get_absolute_url(self):
#      return reverse('model-detail-view', args=[str(self.id)])

# def __str__(self):
#     return f'Chat = "{self.viberChatID}"'

# def addNewUser(self, ChatID, viROLE=JUST_WORKER): # GOOD IDEA  BAD IMPLEMENTATION # FIXME
#     self.viberChatID = str(ChatID)
#     self.viROLE = viROLE
#     # self.workerID = wID_FK # FIXME
#     self.save()


# class ViUserMessage(models.Model):
#     '''ViberUser Message's'''
#     ViUserID = models.ForeignKey('ViUsers', on_delete = models.SET_NULL, null=True, blank=True)
#     lastMessageID = models.BigIntegerField(help_text="ID последнего сообщения с этим вибер-аккаунтом", 
#                                      null=True, blank=True, verbose_name="ID посл. сообщ. Вибер") # FIXME (Это сломается, если у вибера uint64 тут... BigIntegerField -- это int64!!! (В 2 раза меньше max_int)
#     timeLastMessage = models.DateTimeField(auto_now=False, auto_now_add=True,
#                                            help_text="Время последнего сообщения с этим вибер-аккаунтом", null=True, blank=True, verbose_name="Время последнего сообщения")

#     def get_absolute_url(self):
#         return reverse('model-detail-view', args=[str(self.ViUserID)])

#     def __str__(self):
#         return f'Chat = "{self.ViUserID}"   MID = "{self.lastMessageID}"    TMID = "{self.timeLastMessage}"'
#     # In THIS (??) PLACE NEED SAVE MESSAGES_FROM_USER_TO_BOT AND MESSAGES_FROM_BOT_TO_USER     # FIXME 



# class DUTY_Workers(models.Model):    
#     """    Parse Google Sheets Table with work employee     """
#     rawRowIdx = models.IntegerField(help_text="Номер строки в таблице", verbose_name="Номер строки", unique=True, null=True)
#     workerID = models.CharField(max_length=50, help_text="Табельный номер сотрудника", null=True, blank=True, verbose_name="Табельный номер") 
#     workerFullName = models.CharField(max_length=100, help_text="ФИО сотрудника", null=True, blank=True, verbose_name="ФИО")
#     workerPhone = models.CharField(max_length=50, help_text="Номер телефона сотрудника", null=True, blank=True, verbose_name="Номер телефона")
#     workerPhoneFormula = models.CharField(max_length=200, help_text="Формула для звонка сотруднику (заполняется автоматически)", null=True, blank=True, verbose_name="Формула номера телефона") # FIXME (Что-то придумать тут)
#     workerBirthDate = models.CharField(max_length=50, help_text="Дата рождения сотрудника", null=True, blank=True, verbose_name="Дата рождения")
#     workerPassportRegistration = models.CharField(max_length=500, help_text="Прописка сотрудника", null=True, blank=True, verbose_name="Прописка")
#     noteAboutWorker = models.CharField(max_length=1000, help_text="Примечание", null=True, blank=True, verbose_name="Примечание")
#     avaibleWorkForWorkers =  models.CharField(max_length=500, help_text="Профессия сотрудника", null=True, blank=True, verbose_name="ID Чата Вибер")
#     workerPassportNumber = models.CharField(max_length=50, help_text="Серия и номер пасспорта сотрудника", null=True, blank=True, verbose_name="Серия Номер пасспорта")
#     placeOfIsseOfTheWorkersPassport = models.CharField(max_length=1000, help_text="Место выдчи пасспорта", null=True, blank=True, verbose_name="Пасспорт выдан")
#     idPlaceOfIsseOfTheWorkersPassport = models.CharField(max_length=1000, help_text="Код подразделения", null=True, blank=True, verbose_name="Код подразделения")
#     workersHireDate = models.CharField(max_length=50, help_text="Дата найма сотрудника", null=True, blank=True, verbose_name="Дата найма")
#     workerLivePlace = models.CharField(max_length=500, help_text="Приоритетный район для поиска работы", null=True, blank=True, verbose_name="Район проживания")
#     workersBankDetails = models.CharField(max_length=500, help_text="Платежные реквизиты сотрудника", null=True, blank=True, verbose_name="Банковские реквизиты")
#     dateOfDismissal = models.CharField(max_length=50, help_text="Дата увольнения сотрудника", null=True, blank=True, verbose_name="Дата увольнения")
#     paymentType = models.CharField(max_length=500, help_text="Кто и как оплачивает", null=True, blank=True, verbose_name="Кто оплачивает")
#     INN = models.CharField(max_length=200, help_text="ИНН Сотрудника", null=True, blank=True, verbose_name="ИНН")
#     countWorkerIDFromGSheets = models.CharField(max_length=2, help_text="Количество повторов табельного номера", null=True, blank=True, verbose_name="Количество повторов табельного номера")


# def get_absolute_url(self):
#      return reverse('model-detail-view', args=[str(self.workerID)])

# def __str__(self):
#     return self.workerFullName


# class RAWKommandorWorksFromGSheets(models.Model):    
#     """    Parse Google Sheets Table with works    """
#     rawRowIdx = models.IntegerField(help_text="Номер строки в таблице", verbose_name="Номер строки", unique=True, null=True) 
#     timeStamp = models.CharField(max_length=50, help_text="Время заполнения заявки", null=True, blank=True, verbose_name="Отметка времени")
#     dateForWork = models.CharField(max_length=50, help_text="Дата начала работы", null=True, blank=True, verbose_name="Дата заявки")
#     workerID = models.CharField(max_length=50, help_text="Табельный номер сотрудника в заявке", null=True, blank=True, verbose_name="Табельный номер")
#     workerFullName = models.CharField(max_length=500, help_text="ФИО сотрудника", null=True, blank=True, verbose_name="ФИО")
#     workType = models.CharField(max_length=500, help_text="Название вакансии", null=True, blank=True, verbose_name="Вид Работ")
#     startTimeWork = models.CharField(max_length=50, help_text="Время начала заявки", null=True, blank=True, verbose_name="Начало заявки")
#     endTimeWork = models.CharField(max_length=50, help_text="Время окончиания заявки", null=True, blank=True, verbose_name="Конец заявки")
#     amountOfWorkTime = models.CharField(max_length=50, help_text="Количество часов в заявке", null=True, blank=True, verbose_name="К-во часов в заявке")
#     workPlaceName = models.CharField(max_length=50, help_text="Код Торговой Точки", null=True, blank=True, verbose_name="Код ТТ")
#     workPlaceType = models.CharField(max_length=50, help_text="Тип Торговой Точки", null=True, blank=True, verbose_name="Тип ТТ")
#     workPlaceAddress = models.CharField(max_length=500, help_text="Адрес Торговой Точки", null=True, blank=True, verbose_name="Адрес ТТ")
#     closingConfirmation = models.CharField(max_length=50, help_text="Подтверждение заявки", null=True, blank=True, verbose_name="Подтверждение")
#     workPlaceNote = models.CharField(max_length=1000, help_text="Примечание от магазина", null=True, blank=True, verbose_name="Примечание")
#     ourNote = models.CharField(max_length=500, help_text="Ответ от контрагента", null=True, blank=True, verbose_name="Ответ для ТТ")
#     lastTimeWorkPlaceNoteChange = models.CharField(max_length=50, help_text="Время последнего изменения комментария", null=True, blank=True, verbose_name="Время коментария магазина")
#     INN = models.CharField(max_length=100, help_text="ИНН Сотрудника", null=True, blank=True, verbose_name="ИНН")
#     theCreatorID = models.CharField(max_length=50, help_text="ID Творца", null=True, blank=True, verbose_name="ID Творца")
#     serialNumberForMe = models.IntegerField(help_text="Серийный номер придуманный мной", verbose_name="S/N Заявки", unique=True, null=True) 

#     def getKommandorDataFromGSheets():
#         pass

#     def get_absolute_url(self):
#          return reverse('model-detail-view', args=[str(self.id)])

#     def __str__(self):
#         return f'{self.dateForWork} на {self.workPlaceName} для {self.workerID}'


# class WorkPlacesFromGSheets(models.Model): 
#     """    Parse Google Sheets Table with Work Places    """
#     sheetsID = models.CharField(max_length=3, help_text="Порядковый номер торговой точки в таблице", null=True, blank=True, verbose_name="ID ТТ")
#     workPlaceName = models.CharField(max_length=20, help_text="Код Торговой Точки", null=True, blank=True, verbose_name="Код ТТ")
#     workPlaceType = models.CharField(max_length=19, help_text="Тип Торговой Точки", null=True, blank=True, verbose_name="Тип ТТ")
#     workPlaceDirector = models.CharField(max_length=100, help_text="ФИО и номер директора ТТ", null=True, blank=True, verbose_name="Директор")
#     workPlaceAddress = models.CharField(max_length=19, help_text="Адрес Торговой Точки", null=True, blank=True, verbose_name="Адрес ТТ")

#     def getWorkPlacesFromGsheets():
#         pass

#     def get_absolute_url(self):
#          return reverse('model-detail-view', args=[str(self.workPlaceName)])

#     def __str__(self):
#         return str(self.workPlaceName)


# class RAWKommandorEmployeeTimeSheetFromGSheets(models.Model):    
#     """    Parse Google Sheets Table with Employeers TimeSheets    """
#     rawRowIdx = models.IntegerField(help_text="Номер строки в таблице", verbose_name="Номер строки", unique=True, null=True) 
#     timeStamp = models.CharField(max_length=50, help_text="Время заполнения заявки", null=True, blank=True, verbose_name="Отметка времени")
#     dateForWork = models.CharField(max_length=50, help_text="Дата начала работы", null=True, blank=True, verbose_name="Дата заявки")
#     workPlaceName = models.CharField(max_length=50, help_text="Код Торговой Точки", null=True, blank=True, verbose_name="Код ТТ")
#     workerID = models.CharField(max_length=50, help_text="Табельный номер сотрудника в заявке", null=True, blank=True, verbose_name="Табельный номер")
#     workType = models.CharField(max_length=500, help_text="Название вакансии", null=True, blank=True, verbose_name="Вид Работ")
#     startTimeWork = models.CharField(max_length=50, help_text="Время начала заявки", null=True, blank=True, verbose_name="Начало заявки")
#     endTimeWork = models.CharField(max_length=50, help_text="Время окончиания заявки", null=True, blank=True, verbose_name="Конец заявки")
#     amountOfWorkTime = models.CharField(max_length=50, help_text="Количество часов в заявке", null=True, blank=True, verbose_name="К-во часов в заявке")
#     statusWorker = models.CharField(max_length=200, help_text="Статус сотрудника", null=True, blank=True, verbose_name="Статус")
#     rateWorker = models.CharField(max_length=500, help_text="Оценка сотрудника", null=True, blank=True, verbose_name="Оценка")
#     noteRate = models.CharField(max_length=1000, help_text="Коментарий к оценке", null=True, blank=True, verbose_name="Коментарий оценки")
#     workerFullName = models.CharField(max_length=500, help_text="ФИО сотрудника", null=True, blank=True, verbose_name="ФИО")
#     KommangorMananerNote = models.CharField(max_length=500, help_text="Дата выгрузки?", null=True, blank=True, verbose_name="Комментарий менеджера коммандора")
#     isKey = models.CharField(max_length=50, help_text="Что мне с ним делать?", null=True, blank=True, verbose_name="МойКлюч?")
#     serialNumberForMe = models.IntegerField(help_text="Серийный номер придуманный мной", verbose_name="S/N Заявки", unique=True, null=True) 

#     def get_absolute_url(self):
#          return reverse('model-detail-view', args=[str(self.id)])

#     def __str__(self):
#         return f'{self.dateForWork} на {self.workPlaceName} для {self.workerID}'


# class RelationKRSKKommandorWorksToEmployeeTimeSheets(models.Model):
#     '''My BADEST implementation M:N Relation'''
#     worksIDX = models.IntegerField(help_text="Серийный номер придуманный мной из таблицы заявок", verbose_name="S/N Заявки", unique=True, null=True)
#     timeSheetIDX = models.IntegerField(help_text="Серийный номер придуманный мной из таблицы с ЛУВРами", verbose_name="S/N ЛУВРа", unique=True, null=True) 




# class WorkingHours(models.Model):
#     workingHours = models.DecimalField(help_text="Количество оплачиваемых часов", verbose_name="Часы работы",
#                                        max_digits=3, decimal_places=1, unique=True, default=0)
    
#     class Meta:
#         ordering = ["workingHours"]

#     def __unicode__(self):
#         return str(self.workingHours)

#     def __str__(self):
#         return str(self.workingHours)


```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/sendConstantsToServer.py"
```
import json
# import datetime as dtLib

# from django.contrib.auth.decorators import permission_required
from django.contrib.auth.decorators     import user_passes_test
# from django.shortcuts               import render
from django.views.decorators.http   import require_http_methods
from django.http                    import JsonResponse # ,HttpResponseRedirect

from .models                        import Grades, Locations, PaymentType #, # WorkSheets #, Workers, , TimeSheets # and all

from .helpers                       import getSheetByGroup, has_any_permissions
from .helpers                       import VIEW_PERMISSIONS, CHANGE_PERMISSIONS, DELETE_PERMISSIONS


@require_http_methods("GET")
@user_passes_test(lambda user: has_any_permissions(user, VIEW_PERMISSIONS))  # FIXME
def getAllGrades(request):
    all_grades = list(Grades.objects.all().values_list('gradeNum', 'gradeText').order_by('-gradeNum'))
    return JsonResponse(all_grades, safe=False)


@require_http_methods("GET")
@user_passes_test(lambda user: has_any_permissions(user, VIEW_PERMISSIONS))  # FIXME
def getAllShops(request):
    if isinstance(Shops       := getSheetByGroup(request.user,       'Shops'), JsonResponse):
        return Shops
    all_shops = list(Shops.objects.all().values_list('shop_code').order_by('-shop_code'))
    return JsonResponse(all_shops, safe=False)


@require_http_methods("GET")
@user_passes_test(lambda user: has_any_permissions(user, VIEW_PERMISSIONS))  # FIXME
def getAllTypeOfWork(request):
    krsk_location = Locations.objects.get(location="Красноярск")
    if isinstance(TypeOfWork := getSheetByGroup(request.user, 'TypeOfWork'), JsonResponse):
        return TypeOfWork
    all_types = list(TypeOfWork.objects.filter(location=krsk_location).values_list('id', 'typeOfWork').order_by('id'))
    return JsonResponse(all_types, safe=False)


@require_http_methods("GET")
@user_passes_test(lambda user: has_any_permissions(user, VIEW_PERMISSIONS))  # FIXME
def getAllWorkers(request):
    if isinstance(Workers := getSheetByGroup(request.user, 'Workers'), JsonResponse):
        return Workers
    all_workers = list(Workers.objects.all().values_list('worker_id', 'worker_full_name', 'payment_type__payment_type', 'date_Of_Dismissal', named=False))
    all_workers = {r[0]: [r[1], r[2], r[3]] for r in all_workers}
    # all_workers = list(Workers.objects.all().values_list('id', 'worker_id', 'worker_full_name').order_by('worker_id')) # MAYBE IT NEED...
    return JsonResponse(all_workers, safe=False)


@require_http_methods("GET")
@user_passes_test(lambda user: has_any_permissions(user, VIEW_PERMISSIONS))  # FIXME
def getLocations(request):
    locations = list(Locations.objects.all().values_list('id', 'location',)) 
    return JsonResponse(locations, safe=False)


@require_http_methods("GET")
@user_passes_test(lambda user: has_any_permissions(user, VIEW_PERMISSIONS))  # FIXME
def getPaymentType(request):
    payment_type = list(PaymentType.objects.all().values_list('id', 'payment_type',)) 
    return JsonResponse(payment_type, safe=False)


@require_http_methods("GET")
@user_passes_test(lambda user: has_any_permissions(user, VIEW_PERMISSIONS))  # FIXME
def getUserGroups(request):
    user_groups = list(request.user.groups.values_list('name', flat=True))
    return JsonResponse(user_groups, safe=False)
```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/urls.py"
```
from django.urls                import path
from django.contrib.auth.views  import LoginView

# from .WorkSheets_View           import form_KRSK_WorkSheets
# from .LUVRs_View                import LUVRsViews, change_Note
# from .ClosingWorkSheets_View    import closingWorkSheets, changePriorityWorkplace, changeWorkerFromShopStatus, changeWorker, changeSR_Note, getAllDates, getWorkSheetsWithDates
# from .new_LUVR                  import LUVRs_View, getWorkSheetsWithDatesFromLUVRS, getWorkSheetsWithDatesFromLUVRS_asList, saveLUVR, changeKomandorsNote
# from .new_LUVR                  import getAllDates as getAllDatesFromLUVR
# from .new_LUVR_TimeSheets_View  import TimeSheets_View, getTimeSheetsWithDatesFromTimeSheets_View
# from .new_LUVR_TimeSheets_View  import getAllDates as getAllDates_from_Timesheets_View
# from .new_LUVR_TimeSheets_View  import genCSV      as getTimeSheetsWithDatesFromTimeSheets_View_AsCSV

#### DEPRECATED UPPER
from .views                     import index  # , test

from .create_vacancy_View       import create_vacancy_page

from .sendConstantsToServer     import getAllGrades, getAllShops, getAllTypeOfWork, getAllWorkers, getLocations, getPaymentType, getUserGroups

from .FF_LUVR                   import FF_LUVR_View, FF_LUVR_getTable, FF_LUVR_getHead #, excelThisTimeSheets
from .FF_LUVR                   import changeTypeOfWork       as FF_LUVR_changeTypeOfWork
from .FF_LUVR                   import changeKomandorsNote    as FF_LUVR_changeKomandorsNote
from .FF_LUVR                   import changeSRNote           as FF_LUVR_changeSRNote
from .FF_LUVR                   import changeCancelApp        as FF_LUVR_changeCancelApp
from .FF_LUVR                   import FF_saveLUVR            as FF_saveLUVR
from .FF_LUVR                   import changeWorkerSkipWork   as FF_changeWorkerSkipWork
from .FF_LUVR                   import changeConformationApp  as FF_changeConformationApp
from .FF_LUVR                   import removeApp              as FF_removeApp
from .FF_LUVR                   import changeField            as FF_changeField
from .FF_LUVR                   import FF_Exporting_page_View as FF_Exporting_page

# from .callTable                 import getCallTablePage 



urlpatterns = [
    path('создать_заявку', create_vacancy_page, name='create_vacancy_page'),  # Заполнение заявок администраторами командора
    # path('testKRSK/', form_KRSK_WorkSheets, name='testKRSK'), # Заполнение заявок администраторами командора DEPRECATED

    # path('закрытие_заявок/get_all_dates',                  getAllDates,                name='get_all_dates'),
    # path('закрытие_заявок/get_worksheets_with_dates',      getWorkSheetsWithDates,     name='get_worksheets_with_dates'),
    # path('закрытие_заявок/change_priority_workplace',      changePriorityWorkplace,    name='change_priority_workplace'),
    # path('закрытие_заявок/change_worker',                  changeWorker,               name='change_worker'),
    # path('закрытие_заявок/change_sr_note',                 changeSR_Note,              name='change_sr_note'),
    # path('закрытие_заявок/change_worker_from_shop_status', changeWorkerFromShopStatus, name='changeWorkerFromShopStatus'),
    # path('закрытие_заявок/',                               closingWorkSheets,          name='closingWorkSheets'), # PATH: "закрытие_заявок/"

    # path('LUVRs/', LUVRs_View, name='LUVRs_View'),
    # path('LUVRs/save_luvr', saveLUVR, name='save_LUVR'),
    # path('LUVRs/change_komandor_note', changeKomandorsNote, name='change_komandor_note'),
    # path('LUVRs/get_all_dates', getAllDatesFromLUVR, name='getAllDatesFromLUVR'),
    # path('LUVRs/get_worksheets_with_dates', getWorkSheetsWithDatesFromLUVRS, name='getWorkSheetsWithDatesFromLUVRS'),
    # path('LUVRs/get_worksheets_with_dates_new', getWorkSheetsWithDatesFromLUVRS_asList, name='getWorkSheetsWithDatesFromLUVRS_asList'),
    
    # path('timesheets/', TimeSheets_View, name='TimeSheets_View'),
    # path('timesheets/get_all_dates', getAllDates_from_Timesheets_View, name='getAllDatesFrom_new_Timesheets'),
    # path('timesheets/get_timesheets_with_dates', getTimeSheetsWithDatesFromTimeSheets_View, name='getTimeSheetsWithDatesFromTimeSheets_View'),
    # path('timesheets/get_timesheets_with_dates_as_CSV', getTimeSheetsWithDatesFromTimeSheets_View_AsCSV, name='getTimeSheetsWithDatesFromTimeSheets_View_AsCSV'),

    # path('call_table/', getCallTablePage, name='getCallTable_page'),
    # path('call_table/get_all_dates', getAllDates_from_Timesheets_View, name='getAllDatesFrom_new_Timesheets'),
    # path('call_table/get_timesheets_with_dates', getTimeSheetsWithDatesFromTimeSheets_View, name='getTimeSheetsWithDatesFromTimeSheets_View'),
    # path('call_table/get_timesheets_with_dates_as_CSV', getTimeSheetsWithDatesFromTimeSheets_View_AsCSV, name='getTimeSheetsWithDatesFromTimeSheets_View_AsCSV'),
    
    # path('test/', test, name='test'),
    #### DEPRECATED UPPER
    
    path('GETTERS/all_grades',        getAllGrades,     name='getAllGrades'),
    path('GETTERS/all_types_of_work', getAllTypeOfWork, name='getAllTypeOfWork'),
    path('GETTERS/all_workers',       getAllWorkers,    name='getAllWorkers'),
    path('GETTERS/all_shops',         getAllShops,      name='getAllShops'),
    path('GETTERS/all_locations',     getLocations,     name='getAllLocations'),
    path('GETTERS/all_payment_type',  getPaymentType,   name='getAllPayTypes'),
    path('GETTERS/get_user_groups',   getUserGroups,    name='getUserGroups'),

    path('ЛУВР/get_table', FF_LUVR_getTable, name='FF_LUVR_getTable'),
    path('ЛУВР/get_head',  FF_LUVR_getHead,  name='FF_LUVR_getHead'),
    # path('ЛУВР/change_worker_skip_work', FF_LUVR_changeKomandorsNote, name='FF_LUVR_changeKomandorsNote'),

    path('ЛУВР/change_type_of_work',   FF_LUVR_changeTypeOfWork,    name='FF_LUVR_changeTypeOfWork'),
    path('ЛУВР/change_komandor_note',  FF_LUVR_changeKomandorsNote, name='FF_LUVR_change_komandor_note'),
    path('ЛУВР/change_sr_note',        FF_LUVR_changeSRNote,        name='FF_LUVR_change_sr_note'),
    path('ЛУВР/change_cancel_app',     FF_LUVR_changeCancelApp,     name='FF_LUVR_changeCancelApp'),
    path('ЛУВР/send_LUVR',             FF_saveLUVR,                 name='FF_saveLUVR'),
    path('ЛУВР/worker_skip_work',      FF_changeWorkerSkipWork,     name='FF_changeWorkerSkipWork'),
    path('ЛУВР/changeConformationApp', FF_changeConformationApp,    name='FF_changeConformationApp'),
    path('ЛУВР/removeApp',             FF_removeApp,                name='FF_removeApp'),
    path('ЛУВР/fast_change_field',     FF_changeField,              name='FF_changeField'),
    # path('ЛУВР/get_excel', excelThisTimeSheets,    name='excelThisTimeSheets'),
    path('ЛУВР/exporting_page', FF_Exporting_page, name='FF_Exporting_page'),
    path('ЛУВР/', FF_LUVR_View,      name='FF_LUVR'),

    path('', index, name='index'),

]
```

File: "/home/rabbit/Documents/Prog/sshfs/DjangoForm/DjangoForms/KRSK_WorkSheets/views.py"
```
# CRITICAL BUG: HTTP -> HTTPS AUTOREDIRECT # FIXME!!!

# import json
# from datetime import datetime as dt

# # from django.db                      import models
# from django.contrib.auth.views      import LoginView
# from django.contrib.auth.models     import User, Group
# # from django.contrib.auth.forms      import AuthenticationForm
from django.contrib.auth.decorators import login_required # , permission_required, 

from django.shortcuts               import render
# from django.http                    import HttpResponseRedirect, JsonResponse
# from django.urls                    import reverse
# from django.utils.html              import escape


# from .models                        import WorkSheets, TimeSheets, TypeOfWork, Shops
# from .models                        import WorkingHours, Grades, Workers
# from .forms                         import KrskWorksheetsForm, Grade_ModelForm # , KRSK_LUVR_MForm
# from .WorkSheets_View               import form_KRSK_WorkSheets
# from bridge_to_GoogleSheets.bridge import appendRow


# def form_KRSK_WorkSheets(request): # move at .WorkSheets_View.py

@login_required
def index(request):
    return render(request, 'KRSK_WorkSheets/index.html')


def test(request):
    return render(request, 'KRSK_WorkSheets/test.html')
```


Это код моего сайта на Django. Мне он не нравится. Предложи, что можно улучшить