forked from mirzaev/site-tordv-calculator
465 lines
23 KiB
JavaScript
465 lines
23 KiB
JavaScript
'use strict';
|
||
|
||
let calculator = {
|
||
index: document.getElementById("calculator"),
|
||
calculators: [],
|
||
account: [],
|
||
settings: {
|
||
defaults: {
|
||
buyer: 'individual',
|
||
complexity: 'medium',
|
||
}
|
||
},
|
||
init() {
|
||
// Инициализация калькулятора
|
||
|
||
this.generate.buyer(this.settings.defaults.buyer)
|
||
.then(
|
||
success => {
|
||
this.generate.complexity(this.settings.defaults.complexity)
|
||
.then(
|
||
success => {
|
||
this.generate.menu()
|
||
.then(
|
||
success => {
|
||
this.authenticate(cookie.read('id'))
|
||
.then(
|
||
success => {
|
||
// Запись данных аккаунта
|
||
this.account = success;
|
||
|
||
if (this.account !== undefined && typeof this.account === 'object' && this.account.permissions !== undefined) {
|
||
// Найден аккаунт
|
||
|
||
if (this.account.permissions.calculate == 1) {
|
||
// Разрешено использовать калькулятор
|
||
|
||
this.generate.result();
|
||
}
|
||
}
|
||
}
|
||
);
|
||
}
|
||
);
|
||
}
|
||
);
|
||
}
|
||
);
|
||
|
||
console.log('[КАЛЬКУЛЯТОР] Инициализирован');
|
||
},
|
||
authenticate(id) {
|
||
// Запрос и генерация HTML с данными о типе покупателя (юр. лицо и физ. лицо)'
|
||
|
||
return fetch('/account/data?id=' + id, {
|
||
method: "POST",
|
||
headers: { "content-type": "application/x-www-form-urlencoded" }
|
||
}).then((response) => {
|
||
if (response.status === 200) {
|
||
return response.json().then(
|
||
success => {
|
||
console.log('[КАЛЬКУЛЯТОР] Загружены данные пользователя: ' + id);
|
||
|
||
return success;
|
||
},
|
||
error => {
|
||
console.log('[КАЛЬКУЛЯТОР] [ОШИБКА] Не удалось загрузить данные пользователя: ' + id);
|
||
});
|
||
}
|
||
});
|
||
},
|
||
calculate() {
|
||
// Запрос и генерация HTML с данными о рассчете со всех калькуляторов
|
||
|
||
// Инициализация буфера запроса
|
||
let query = {};
|
||
|
||
for (const number in this.calculators) {
|
||
// Перебор калькуляторов
|
||
|
||
// Инициализация буфера запроса для нового калькулятора
|
||
query[number] = {};
|
||
|
||
// Инициализация типа калькулятора
|
||
query[number]['calculator'] = this.calculators[number].getAttribute('data-calculator');
|
||
|
||
for (const buyer of this.index.querySelectorAll('input[name="buyer"]')) {
|
||
// Перебор полей с параметрами типа заказчика
|
||
|
||
if (buyer.checked) {
|
||
// Найдено выбранное поле
|
||
|
||
// Запись в буфер запроса
|
||
query[number]['buyer'] = buyer.value;
|
||
}
|
||
}
|
||
|
||
for (const complexity of this.index.querySelectorAll('input[name="complexity"]')) {
|
||
// Перебор полей с параметрами сложности
|
||
|
||
if (complexity.checked) {
|
||
// Найдено выбранное поле
|
||
|
||
// Запись в буфер запроса
|
||
query[number]['complexity'] = complexity.value;
|
||
}
|
||
}
|
||
|
||
for (const field of this.calculators[number].querySelectorAll('[data-calculator-parameter]')) {
|
||
// Перебор полей с параметрами
|
||
|
||
if (field.getAttribute('type') === 'checkbox') {
|
||
// Флажок
|
||
|
||
// Запись в буфер запроса
|
||
query[number][field.getAttribute('data-calculator-parameter')] = field.checked;
|
||
} else if (field.getAttribute('type') === 'text' || field.getAttribute('type') === 'number' || field.getAttribute('type') === 'range') {
|
||
// Текстовое, цифровое поле или ползунок
|
||
|
||
// Запись в буфер запроса
|
||
query[number][field.getAttribute('data-calculator-parameter')] = field.value;
|
||
} else {
|
||
// Элемент с тегом <select> (подразумевается)
|
||
|
||
// Запись в буфер запроса
|
||
query[number][field.getAttribute('data-calculator-parameter')] = field.value ?? field.options[field.selectedIndex].text;
|
||
}
|
||
}
|
||
|
||
// Сортировка
|
||
query[number] = query[number];
|
||
}
|
||
|
||
return fetch('/calculator/calculate', {
|
||
method: "POST",
|
||
headers: { "content-type": "application/json" },
|
||
body: JSON.stringify(query)
|
||
}).then((response) => {
|
||
if (response.status === 200) {
|
||
response.json().then(
|
||
success => {
|
||
// Инициализация буфера расходов
|
||
let expenses = 0;
|
||
|
||
for (const [, machine] of Object.entries(success.machines)) {
|
||
// Перебор станков
|
||
|
||
// Прибавление данных к буферу расходов
|
||
expenses += (machine.electricity + (machine.metal ?? 0));
|
||
}
|
||
|
||
for (const [, manager] of Object.entries(success.managers)) {
|
||
// Перебор менеджеров
|
||
|
||
// Прибавление данных к буферу расходов
|
||
expenses += manager.time * manager.hour;
|
||
}
|
||
|
||
for (const [, engineer] of Object.entries(success.engineers)) {
|
||
// Перебор менеджеров
|
||
|
||
// Прибавление данных к буферу расходов
|
||
expenses += engineer.time * engineer.hour;
|
||
}
|
||
|
||
for (const [, operator] of Object.entries(success.operators)) {
|
||
// Перебор операторов
|
||
|
||
// Прибавление данных к буферу расходов
|
||
expenses += (operator.time.design + operator.time.machine) * operator.hour;
|
||
}
|
||
|
||
for (const [, handyman] of Object.entries(success.handymans)) {
|
||
// Перебор разнорабочих
|
||
|
||
// Прибавление данных к буферу расходов
|
||
expenses += handyman.time * handyman.hour;
|
||
}
|
||
|
||
// Добавление переработки
|
||
expenses += success.other.reprocessing;
|
||
|
||
// Добавление наценки (коэффициент)
|
||
expenses *= success.other.additive;
|
||
|
||
// Добавление скидки менеджера
|
||
expenses -= expenses * (success.other.discount / 100)
|
||
|
||
// Округление
|
||
expenses = expenses.toFixed(2);
|
||
|
||
if (this.generate.result(expenses + ' рублей')) {
|
||
console.log(`[КАЛЬКУЛЯТОР] Сгенерирован результат: ${expenses} рублей`);
|
||
} else {
|
||
console.log('[КАЛЬКУЛЯТОР] [ОШИБКА] Не удалось сгенерировать результат');
|
||
}
|
||
},
|
||
error => {
|
||
console.log('[КАЛЬКУЛЯТОР] [ОШИБКА] Не удалось сгенерировать результат');
|
||
});
|
||
}
|
||
});
|
||
},
|
||
generate: {
|
||
buyer(value = 'individual') {
|
||
// Запрос и генерация HTML с данными о типе покупателя (юр. лицо и физ. лицо)
|
||
|
||
return fetch('/calculator/generate/buyer?value=' + value, {
|
||
method: "POST",
|
||
headers: { "content-type": "application/x-www-form-urlencoded" }
|
||
}).then((response) => {
|
||
if (response.status === 200) {
|
||
response.text().then(
|
||
success => {
|
||
calculator.index.insertAdjacentHTML('beforeend', success);
|
||
|
||
console.log('[КАЛЬКУЛЯТОР] Загружен элемент с кнопками выбора типа покупателя');
|
||
},
|
||
error => {
|
||
console.log('[КАЛЬКУЛЯТОР] [ОШИБКА] Не удалось загрузить элемент с кнопками выбора типа покупателя');
|
||
});
|
||
}
|
||
});
|
||
},
|
||
complexity(value = 'medium') {
|
||
// Запрос и генерация HTML с данными о сложности работы
|
||
|
||
return fetch('/calculator/generate/complexity?value=' + value, {
|
||
method: "POST",
|
||
headers: { "content-type": "application/x-www-form-urlencoded" }
|
||
}).then((response) => {
|
||
if (response.status === 200) {
|
||
response.text().then(
|
||
success => {
|
||
calculator.index.insertAdjacentHTML('beforeend', success);
|
||
|
||
console.log('[КАЛЬКУЛЯТОР] Загружен элемент с кнопками выбора сложности');
|
||
},
|
||
error => {
|
||
console.log('[КАЛЬКУЛЯТОР] [ОШИБКА] Не удалось загрузить элемент с кнопками выбора сложности');
|
||
});
|
||
}
|
||
});
|
||
},
|
||
menu() {
|
||
// Запрос и генерация HTML с кнопками добавления калькулятора
|
||
|
||
return fetch('/calculator/generate/menu', {
|
||
method: "POST",
|
||
headers: { "content-type": "application/x-www-form-urlencoded" }
|
||
}).then((response) => {
|
||
if (response.status === 200) {
|
||
response.text().then(
|
||
success => {
|
||
calculator.index.insertAdjacentHTML('beforeend', success);
|
||
|
||
console.log('[КАЛЬКУЛЯТОР] Загружен элемент с кнопками добавления калькулятора');
|
||
},
|
||
error => {
|
||
console.log('[КАЛЬКУЛЯТОР] [ОШИБКА] Не удалось загрузить элемент с кнопками добавления калькулятора');
|
||
});
|
||
}
|
||
});
|
||
},
|
||
result(expenses) {
|
||
// Запрос и генерация HTML с данными о результате калькуляции
|
||
|
||
function request() {
|
||
return fetch('/calculator/generate/result', {
|
||
method: "POST",
|
||
headers: { "content-type": "application/x-www-form-urlencoded" }
|
||
}).then((response) => {
|
||
if (response.status === 200) {
|
||
response.text().then(
|
||
success => {
|
||
calculator.index.insertAdjacentHTML('beforeend', success);
|
||
|
||
console.log('[КАЛЬКУЛЯТОР] Загружен элемент с данными о результате калькуляции');
|
||
},
|
||
error => {
|
||
console.log('[КАЛЬКУЛЯТОР] [ОШИБКА] Не удалось загрузить элемент с данными о результате калькуляции');
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
if (document.getElementById("result") === null) {
|
||
// Не найден элемент с данными расчётов
|
||
|
||
// Генерация элемента с данными расчётов
|
||
}
|
||
|
||
if (expenses !== undefined) {
|
||
// Переданы расходы
|
||
|
||
// Инициализация элемента
|
||
let element = document.getElementById('calculate');
|
||
|
||
if (element == null) {
|
||
// Не найден элемент с результатом расчёта
|
||
|
||
return false;
|
||
}
|
||
|
||
// Запись расходов в элемент (подразумевается кнопка отправки на расчёт)
|
||
element.innerText = expenses;
|
||
|
||
return true;
|
||
}
|
||
|
||
return request();
|
||
},
|
||
mark(element, type = '') {
|
||
// Запрос и генерация HTML с полем выбора марки металла
|
||
|
||
return fetch('/calculator/generate/mark?type=' + type, {
|
||
method: "POST",
|
||
headers: { "content-type": "application/x-www-form-urlencoded" }
|
||
}).then((response) => {
|
||
if (response.status === 200) {
|
||
response.text().then(
|
||
success => {
|
||
// Поиск устаревшего списка с марками
|
||
let old = element.querySelectorAll('select[name="mark"]')[0];
|
||
|
||
if (old !== undefined) {
|
||
// Найден список с марками
|
||
|
||
// Деинициализация
|
||
old.parentElement.parentElement.remove();
|
||
}
|
||
|
||
// Инициализация оболочки в которую необходимо записать список
|
||
let wrap = element.querySelectorAll('select[name="type"]')[0].parentElement.parentElement
|
||
|
||
// Запись полученного списка в оболочку
|
||
wrap.insertAdjacentHTML('afterend', success);
|
||
|
||
console.log('[КАЛЬКУЛЯТОР] Загружен список с марками металла');
|
||
},
|
||
error => {
|
||
console.log('[КАЛЬКУЛЯТОР] [ОШИБКА] Не удалось загрузить список с марками металла');
|
||
});
|
||
}
|
||
});
|
||
},
|
||
divider(element, position) {
|
||
// Запрос и генерация HTML с данными о результате калькуляции
|
||
|
||
return fetch('/calculator/generate/divider', {
|
||
method: "POST",
|
||
headers: { "content-type": "application/x-www-form-urlencoded" }
|
||
}).then((response) => {
|
||
if (response.status === 200) {
|
||
response.text().then(
|
||
success => {
|
||
if (element === undefined || position === undefined) {
|
||
// Не задан элемент и позиция добавляемого разделителя
|
||
|
||
// Запись разделителя в конце калькулятора
|
||
calculator.index.insertAdjacentHTML('beforeend', success);
|
||
} else {
|
||
// Задан элемент и позиция добавляемого разделителя
|
||
|
||
// Запись разделителя по заданным параметрам
|
||
element.insertAdjacentHTML(position, success);
|
||
}
|
||
|
||
console.log('[КАЛЬКУЛЯТОР] Загружен разделитель');
|
||
},
|
||
error => {
|
||
console.log('[КАЛЬКУЛЯТОР] [ОШИБКА] Не удалось загрузить разделитель');
|
||
});
|
||
}
|
||
});
|
||
},
|
||
calculators: {
|
||
laser() {
|
||
// Запрос и генерация HTML с калькулятором лазерной резки
|
||
|
||
function write(target, position, html) {
|
||
if (target === undefined || position === undefined || html === undefined) return false;
|
||
|
||
// Запись калькулятора после последнего калькулятора
|
||
target.insertAdjacentHTML(position, html);
|
||
|
||
// Поиск калькуляторов
|
||
let calculators = calculator.index.querySelectorAll('section[data-calculator]');
|
||
|
||
// Инициализация идентификатора калькулятора
|
||
let id = calculators.length - 1;
|
||
|
||
// Запись калькулятору его идентификатора
|
||
calculators[id].id = 'laser_' + id;
|
||
|
||
// Запись в реестр последнего калькулятора (подразумевается, что он новый и только что был записан)
|
||
calculator.calculators.push(calculators[id]);
|
||
|
||
// Запись в журнал
|
||
console.log('[КАЛЬКУЛЯТОР] Инициализирован калькулятор лазерной резки');
|
||
|
||
// Инициализация поля с маркой металла
|
||
calculator.generate.mark(calculators[id]);
|
||
}
|
||
|
||
return fetch('/calculator/generate/laser', {
|
||
method: "POST",
|
||
headers: { "content-type": "application/x-www-form-urlencoded" }
|
||
}).then((response) => {
|
||
if (response.status === 200) {
|
||
response.text().then(
|
||
success => {
|
||
// Поиск последнего калькулятора
|
||
let last = calculator.calculators[calculator.calculators.length - 1];
|
||
|
||
if (last !== undefined && last !== null) {
|
||
// Найден калькулятор
|
||
|
||
// Инициализация разделителя перед меню
|
||
calculator.generate.divider(last, 'afterend').then(divider => write(last, 'afterend', success));
|
||
} else {
|
||
// Не найден калькулятор
|
||
|
||
calculator.generate.divider(menu, 'beforebegin').then(
|
||
first => {
|
||
// Поиск меню
|
||
let menu = document.getElementById("menu");
|
||
|
||
if (menu !== null) {
|
||
// Найдено меню
|
||
|
||
// Инициализация разделителя перед меню
|
||
calculator.generate.divider(menu, 'beforebegin').then(divider => write(menu, 'beforebegin', success));
|
||
} else {
|
||
// Не найдено меню
|
||
|
||
// Поиск результатов калькуляции
|
||
let result = document.getElementById("result");
|
||
|
||
if (result !== null) {
|
||
// Найден элемент с результатами калькуляции
|
||
|
||
// Инициализация разделителя перед меню
|
||
calculator.generate.divider(result, 'beforebegin').then(result => write(result, 'beforebegin', success));
|
||
} else {
|
||
// Не найден элемент с результатами калькуляции
|
||
|
||
// Инициализация разделителя перед меню
|
||
calculator.generate.divider().then(result => write(calculator.index, 'beforeend', success));
|
||
}
|
||
}
|
||
}
|
||
);
|
||
}
|
||
},
|
||
error => {
|
||
// Запись в журнал
|
||
console.log('[КАЛЬКУЛЯТОР] [ОШИБКА] Не удалось инициализировать калькулятор лазерной резки');
|
||
});
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
};
|