forked from mirzaev/site-tordv-calculator
		
	Доработки под доп. листы
This commit is contained in:
		@@ -4,6 +4,7 @@ declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace mirzaev\calculator\controllers;
 | 
			
		||||
 | 
			
		||||
use Exception;
 | 
			
		||||
use mirzaev\calculator\controllers\core;
 | 
			
		||||
use mirzaev\calculator\models\calculators_model as calculators;
 | 
			
		||||
use mirzaev\calculator\models\settings_model as settings;
 | 
			
		||||
@@ -93,6 +94,12 @@ final class calculator_controller extends core
 | 
			
		||||
     */
 | 
			
		||||
    public function result(array $vars = []): ?string
 | 
			
		||||
    {
 | 
			
		||||
        // Инициализация журнала ошибок
 | 
			
		||||
        $vars['errors'] = ['calculators' => []];
 | 
			
		||||
 | 
			
		||||
        // Инициализация данных калькулятора
 | 
			
		||||
        $vars['discount'] = settings::read('discount', $vars['errors']['calculators']);
 | 
			
		||||
 | 
			
		||||
        // Генерация представления
 | 
			
		||||
        return $this->view->render(DIRECTORY_SEPARATOR . 'calculators' . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . 'result.html', $vars);
 | 
			
		||||
    }
 | 
			
		||||
@@ -118,7 +125,7 @@ final class calculator_controller extends core
 | 
			
		||||
        if (empty($vars['marks'])) $vars['marks'] = ['Не найдено'];
 | 
			
		||||
 | 
			
		||||
        // Генерация представления
 | 
			
		||||
        return $this->view->render(DIRECTORY_SEPARATOR . 'calculators' . DIRECTORY_SEPARATOR . 'elements' . DIRECTORY_SEPARATOR. 'metals' . DIRECTORY_SEPARATOR . 'mark.html', $vars);
 | 
			
		||||
        return $this->view->render(DIRECTORY_SEPARATOR . 'calculators' . DIRECTORY_SEPARATOR . 'elements' . DIRECTORY_SEPARATOR . 'metals' . DIRECTORY_SEPARATOR . 'mark.html', $vars);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -167,17 +174,13 @@ final class calculator_controller extends core
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Рассчёт
 | 
			
		||||
     * Расчёт
 | 
			
		||||
     *
 | 
			
		||||
     * Генерирует ответ в виде ['expenses' => 0, 'income' => 0, 'profit' => 0]
 | 
			
		||||
     *
 | 
			
		||||
     * @param array $vars Параметры
 | 
			
		||||
     *
 | 
			
		||||
     * @todo
 | 
			
		||||
     * 1. Отправлять данные в зависимости от разрешения (обычным пользователям только expenses)
 | 
			
		||||
     * 2. Переписать журнал ошибок и написать вывод ошибок куда-нибудь
 | 
			
		||||
     * 3. Вывод ошибок в представления
 | 
			
		||||
     * 4. Проверка на то, что существуют поставки для характеристик вписываемых в калькулятор (в режиме прямой трансляции)
 | 
			
		||||
     * 5. Убрать передачу цены работы (оставить только время работы в часах и цену за работу в час)
 | 
			
		||||
     */
 | 
			
		||||
    public function calculate(array $vars = []): ?string
 | 
			
		||||
@@ -185,11 +188,19 @@ final class calculator_controller extends core
 | 
			
		||||
        // Инициализация журнала ошибок
 | 
			
		||||
        $vars['errors'] = ['calculators' => []];
 | 
			
		||||
 | 
			
		||||
        // Инициализация калькуляторов из тела запроса (подразумевается, что там массивы с параметрами)
 | 
			
		||||
        $calculators = json_decode(file_get_contents('php://input'), true);
 | 
			
		||||
        try {
 | 
			
		||||
            // Инициализация параметров из тела запроса (подразумевается, что там массивы с параметрами)
 | 
			
		||||
            $vars['input'] = json_decode(file_get_contents('php://input'), true);
 | 
			
		||||
 | 
			
		||||
            $calculators = $vars['input']['calculators'];
 | 
			
		||||
            $discount = $vars['input']['discount'];
 | 
			
		||||
            $cutting = $vars['input']['cutting'];
 | 
			
		||||
 | 
			
		||||
            // Инициализация переменных для буфера вывода
 | 
			
		||||
        $machines = $managers = $engineers = $operators = 0;
 | 
			
		||||
            $machines = $managers = $engineers = $operators = $handymans = $other = 0;
 | 
			
		||||
 | 
			
		||||
            if (count($calculators) > 0) {
 | 
			
		||||
                // Найдены калькуляторы
 | 
			
		||||
 | 
			
		||||
                foreach ($calculators as $i => $calculator) {
 | 
			
		||||
                    // Перебор калькуляторов
 | 
			
		||||
@@ -224,8 +235,23 @@ final class calculator_controller extends core
 | 
			
		||||
                    $parameters += $calculator;
 | 
			
		||||
 | 
			
		||||
                    // Расчёт
 | 
			
		||||
            [$machines, $managers, $engineers, $operators, $handymans, $other] = calculators::$type(...$parameters);
 | 
			
		||||
                    [$machines, $managers, $engineers, $operators, $handymans, $other] = calculators::$type(...$parameters + ['cutting' => $cutting]);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // Не найдены калькуляторы
 | 
			
		||||
 | 
			
		||||
                throw new exception('Не найдены калькуляторы');
 | 
			
		||||
            }
 | 
			
		||||
        } catch (exception $e) {
 | 
			
		||||
            // Запись в журнал ошибок
 | 
			
		||||
            $vars['errors']['calculators'][] = [
 | 
			
		||||
                'text' => $e->getMessage(),
 | 
			
		||||
                'file' => $e->getFile(),
 | 
			
		||||
                'line' => $e->getLine(),
 | 
			
		||||
                'stack' => $e->getTrace()
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        return json_encode([
 | 
			
		||||
            'machines' => $machines,
 | 
			
		||||
@@ -233,8 +259,8 @@ final class calculator_controller extends core
 | 
			
		||||
            'engineers' => $engineers,
 | 
			
		||||
            'operators' => $operators,
 | 
			
		||||
            'handymans' => $handymans,
 | 
			
		||||
            'other' => $other,
 | 
			
		||||
            'errors' => $calculator['errors']
 | 
			
		||||
            'other' => $other + ['discount' => $discount],
 | 
			
		||||
            'errors' => $vars['errors']
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										163
									
								
								mirzaev/calculator/system/models/baloons_model.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								mirzaev/calculator/system/models/baloons_model.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace mirzaev\calculator\models;
 | 
			
		||||
 | 
			
		||||
use exception;
 | 
			
		||||
use pdo;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Модель баллонов
 | 
			
		||||
 *
 | 
			
		||||
 * @package mirzaev\calculator\models
 | 
			
		||||
 * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
 | 
			
		||||
 *
 | 
			
		||||
 * @todo
 | 
			
		||||
 * 1. Если длина реза баллона зависит от типа металла (учитывается) то перенести это в класс металлов
 | 
			
		||||
 */
 | 
			
		||||
final class baloons_model extends core
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Используемый газ
 | 
			
		||||
     */
 | 
			
		||||
    public string $gas;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Количество баллонов
 | 
			
		||||
     */
 | 
			
		||||
    public float $amount = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Цена всех баллонов
 | 
			
		||||
     */
 | 
			
		||||
    public float $cost;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Вычисление используемого газа
 | 
			
		||||
     *
 | 
			
		||||
     * @param float $length Толщина металла
 | 
			
		||||
     * @param array &$errors Журнал ошибок
 | 
			
		||||
     *
 | 
			
		||||
     * @return string|null Название газа
 | 
			
		||||
     */
 | 
			
		||||
    public function gas(float $length, array &$errors = []): ?string
 | 
			
		||||
    {
 | 
			
		||||
        try {
 | 
			
		||||
            return $this->gas = match (true) {
 | 
			
		||||
                $length >= 4 => 'oxygen',
 | 
			
		||||
                default => 'air'
 | 
			
		||||
            };
 | 
			
		||||
        } catch (exception $e) {
 | 
			
		||||
            // Запись в журнал ошибок
 | 
			
		||||
            $errors[] = [
 | 
			
		||||
                'text' => $e->getMessage(),
 | 
			
		||||
                'file' => $e->getFile(),
 | 
			
		||||
                'line' => $e->getLine(),
 | 
			
		||||
                'stack' => $e->getTrace()
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Вычисление количества используемых баллонов
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $metal Тип металла
 | 
			
		||||
     * @param float $cutting Длина реза
 | 
			
		||||
     * @param float $length Толщина листа
 | 
			
		||||
     * @param string|null $gas Используемый газ
 | 
			
		||||
     * @param array &$errors Журнал ошибок
 | 
			
		||||
     *
 | 
			
		||||
     * @return int|null Количество баллонов
 | 
			
		||||
     *
 | 
			
		||||
     * @todo
 | 
			
		||||
     * 1. Добавить к баллонам уточнение чтобы считало не по листам а по объёму а лучше по длине реза
 | 
			
		||||
     * 2. Определение длины реза по типу металла
 | 
			
		||||
     */
 | 
			
		||||
    public function amount(string $metal, float $cutting, float $length, ?string $gas = null, array &$errors = []): ?float
 | 
			
		||||
    {
 | 
			
		||||
        try {
 | 
			
		||||
            // Инициализация входных параметров
 | 
			
		||||
            $gas ?? $gas = &$this->gas;
 | 
			
		||||
 | 
			
		||||
            // Инициализация запроса
 | 
			
		||||
            $request = static::$db->prepare("SELECT `length` FROM `baloons` WHERE `gas` = :gas LIMIT 30");
 | 
			
		||||
 | 
			
		||||
            // Отправка запроса
 | 
			
		||||
            $request->execute([
 | 
			
		||||
                ':gas' => $gas
 | 
			
		||||
            ]);
 | 
			
		||||
 | 
			
		||||
            // Генерация ответа
 | 
			
		||||
            $response = $request->fetch(pdo::FETCH_ASSOC);
 | 
			
		||||
 | 
			
		||||
            // Проверка на полученные значения
 | 
			
		||||
            if (!is_array($response)) return null;
 | 
			
		||||
 | 
			
		||||
            // Вычисление длины реза на которое хватит баллона
 | 
			
		||||
            $flow = $response['length'] / $length;
 | 
			
		||||
 | 
			
		||||
            // Вычисление количества баллонов (округление к большему)
 | 
			
		||||
            return $this->amount = $cutting / $flow;
 | 
			
		||||
        } catch (exception $e) {
 | 
			
		||||
            // Запись в журнал ошибок
 | 
			
		||||
            $errors[] = [
 | 
			
		||||
                'text' => $e->getMessage(),
 | 
			
		||||
                'file' => $e->getFile(),
 | 
			
		||||
                'line' => $e->getLine(),
 | 
			
		||||
                'stack' => $e->getTrace()
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Вычисление стоимости баллонов
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $metal Тип металла
 | 
			
		||||
     * @param int|null $gas Используемый газ
 | 
			
		||||
     * @param array &$errors Журнал ошибок
 | 
			
		||||
     *
 | 
			
		||||
     * @return float|null Стоимость баллонов
 | 
			
		||||
     */
 | 
			
		||||
    public function cost(string $metal, ?int $amount = null, ?string $gas = null, array &$errors = []): ?float
 | 
			
		||||
    {
 | 
			
		||||
        try {
 | 
			
		||||
            // Инициализация входных параметров
 | 
			
		||||
            $amount ?? $amount = &$this->amount;
 | 
			
		||||
            $gas ?? $gas = &$this->gas;
 | 
			
		||||
 | 
			
		||||
            // Инициализация запроса
 | 
			
		||||
            $request = static::$db->prepare("SELECT `cost` FROM `baloons` WHERE `gas` = :gas LIMIT 30");
 | 
			
		||||
 | 
			
		||||
            // Отправка запроса
 | 
			
		||||
            $request->execute([
 | 
			
		||||
                ':gas' => $gas
 | 
			
		||||
            ]);
 | 
			
		||||
 | 
			
		||||
            // Генерация ответа
 | 
			
		||||
            $response = $request->fetch(pdo::FETCH_ASSOC);
 | 
			
		||||
 | 
			
		||||
            // Проверка на полученные значения
 | 
			
		||||
            if (!is_array($response)) return null;
 | 
			
		||||
 | 
			
		||||
            // Инициализация стоимости всех баллонов
 | 
			
		||||
            return $this->cost = $response['cost'] * $amount;
 | 
			
		||||
        } catch (exception $e) {
 | 
			
		||||
            // Запись в журнал ошибок
 | 
			
		||||
            $errors[] = [
 | 
			
		||||
                'text' => $e->getMessage(),
 | 
			
		||||
                'file' => $e->getFile(),
 | 
			
		||||
                'line' => $e->getLine(),
 | 
			
		||||
                'stack' => $e->getTrace()
 | 
			
		||||
            ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -6,6 +6,7 @@ namespace mirzaev\calculator\models;
 | 
			
		||||
 | 
			
		||||
use mirzaev\calculator\models\settings_model as settings;
 | 
			
		||||
use mirzaev\calculator\models\metals_model as metals;
 | 
			
		||||
use mirzaev\calculator\models\baloons_model as baloons;
 | 
			
		||||
 | 
			
		||||
use exception;
 | 
			
		||||
 | 
			
		||||
@@ -22,18 +23,18 @@ final class calculators_model extends core
 | 
			
		||||
     * Расчёт стоимости переработки за 1 тонну
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $complexity Сложность
 | 
			
		||||
     * @param float $lenght Толщина
 | 
			
		||||
     * @param float $length Толщина
 | 
			
		||||
     * @param array &$errors Журнал ошибок
 | 
			
		||||
     *
 | 
			
		||||
     * @return float Стоимость переработки за 1 тонну (руб)
 | 
			
		||||
     */
 | 
			
		||||
    public static function reprocessing(string $complexity, float $lenght, array &$errors = []): ?float
 | 
			
		||||
    public static function reprocessing(string $complexity, float $length, array &$errors = []): ?float
 | 
			
		||||
    {
 | 
			
		||||
        try {
 | 
			
		||||
            return (float) match (true) {
 | 
			
		||||
                $lenght > 0 && $lenght < 4 => settings::read('reprocessing_' . $complexity . '_1_3', $errors),
 | 
			
		||||
                $lenght > 3 && $lenght < 7 => settings::read('reprocessing_' . $complexity . '_4_6', $errors),
 | 
			
		||||
                $lenght > 6 && $lenght < 11 => settings::read('reprocessing_' . $complexity . '_7_10', $errors),
 | 
			
		||||
                $length > 0 && $length < 4 => settings::read('reprocessing_' . $complexity . '_1_3', $errors),
 | 
			
		||||
                $length > 3 && $length < 7 => settings::read('reprocessing_' . $complexity . '_4_6', $errors),
 | 
			
		||||
                $length > 6 && $length < 11 => settings::read('reprocessing_' . $complexity . '_7_10', $errors),
 | 
			
		||||
                default => settings::read('reprocessing_' . $complexity . '_10', $errors),
 | 
			
		||||
            }
 | 
			
		||||
                ?? 0.0;
 | 
			
		||||
@@ -52,7 +53,7 @@ final class calculators_model extends core
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $complexity Сложность детали (easy, medium, hard)
 | 
			
		||||
     * @param int|null $area Площадь детали
 | 
			
		||||
     * @param float|null $lenght Толщина детали
 | 
			
		||||
     * @param float|null $length Толщина детали
 | 
			
		||||
     * @param array &$errors Журнал ошибок
 | 
			
		||||
     *
 | 
			
		||||
     * @return float Коэффициент
 | 
			
		||||
@@ -60,7 +61,7 @@ final class calculators_model extends core
 | 
			
		||||
     * @todo
 | 
			
		||||
     * 1. Коэффициент исходя из типа газа (баллоны)
 | 
			
		||||
     */
 | 
			
		||||
    public static function coefficient(string $complexity, ?int $area = null, ?float $lenght = null, array &$errors = []): float|false
 | 
			
		||||
    public static function coefficient(string $complexity, ?int $area = null, ?float $length = null, array &$errors = []): float|false
 | 
			
		||||
    {
 | 
			
		||||
        try {
 | 
			
		||||
            // Коэффициент полученный исходя из сложности детали
 | 
			
		||||
@@ -78,15 +79,15 @@ final class calculators_model extends core
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (
 | 
			
		||||
                isset($lenght)
 | 
			
		||||
                && ($lenght <= (settings::read('coefficient_lenght_less', $errors) ?? throw new exception("Не найдено: coefficient_lenght_less"))
 | 
			
		||||
                    || $lenght >= (settings::read('coefficient_lenght_more', $errors) ?? throw new exception("Не найдено: coefficient_lenght_more")))
 | 
			
		||||
                isset($length)
 | 
			
		||||
                && ($length <= (settings::read('coefficient_length_less', $errors) ?? throw new exception("Не найдено: coefficient_length_less"))
 | 
			
		||||
                    || $length >= (settings::read('coefficient_length_more', $errors) ?? throw new exception("Не найдено: coefficient_length_more")))
 | 
			
		||||
            ) {
 | 
			
		||||
                // Толщина детали не более и не менее заданных в базе данных размеров
 | 
			
		||||
 | 
			
		||||
                // Прибавление коэффициента исходя из толщины детали
 | 
			
		||||
                // $coefficient += settings::read('coefficient_lenght_degree', $errors) ?? throw new exception("Не найдено: coefficient_lenght_degree");
 | 
			
		||||
                // $coefficient -= settings::read('coefficient_lenght_degree', $errors) ?? throw new exception("Не найдено: coefficient_lenght_degree");
 | 
			
		||||
                // $coefficient += settings::read('coefficient_length_degree', $errors) ?? throw new exception("Не найдено: coefficient_length_degree");
 | 
			
		||||
                // $coefficient -= settings::read('coefficient_length_degree', $errors) ?? throw new exception("Не найдено: coefficient_length_degree");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return (float) $coefficient;
 | 
			
		||||
@@ -167,18 +168,18 @@ final class calculators_model extends core
 | 
			
		||||
     * @param bool|null $out Наш металл?
 | 
			
		||||
     * @param int|string|null $holes Количество отверстий
 | 
			
		||||
     * @param int|string|null $diameter Диаметр отверстий (мм)
 | 
			
		||||
     * @param string|null $discount Скидка менеджера
 | 
			
		||||
     * @param float|null $cutting Длина реза (мм)
 | 
			
		||||
     * @param array &$errors Журнал ошибок
 | 
			
		||||
     *
 | 
			
		||||
     * @return array|bool Аккаунт, если удалось аутентифицироваться
 | 
			
		||||
     *
 | 
			
		||||
     * @todo
 | 
			
		||||
     * 18. 1200 баллон кислород расход 1 баллон на 3 листа 4ки
 | 
			
		||||
     * 22. Выводится результат даже если не аутентифицирован (проблема с куки)
 | 
			
		||||
     * 29. Амортизация станка
 | 
			
		||||
     * 30. Аренда помещения
 | 
			
		||||
     * 31. Расходники
 | 
			
		||||
     * 37. Проверка на то, что загружен минимум 1 калькулятор
 | 
			
		||||
     * 39. Переделать массивы в объекты там, где позволяет случай
 | 
			
		||||
     * 40. Перенести лазерный станок в отдельную таблицу в базе данных со всеми его данными
 | 
			
		||||
     * 43. Удаление калькуляторов
 | 
			
		||||
     * @ 44. от 750 +1 лист от 3
 | 
			
		||||
     * @ 45. от 0.5 до 3 от 620 +1
 | 
			
		||||
     */
 | 
			
		||||
    public static function laser(
 | 
			
		||||
        bool|int|string|null $company = null,
 | 
			
		||||
@@ -192,7 +193,7 @@ final class calculators_model extends core
 | 
			
		||||
        ?bool $our = null,
 | 
			
		||||
        int|string|null $holes = null,
 | 
			
		||||
        float|string|null $diameter = null,
 | 
			
		||||
        float|string|null $discount = null,
 | 
			
		||||
        float|null $cutting = null,
 | 
			
		||||
        array &$errors = []
 | 
			
		||||
    ): array {
 | 
			
		||||
        // Инициализация журнала ошибок
 | 
			
		||||
@@ -217,7 +218,7 @@ final class calculators_model extends core
 | 
			
		||||
            $our = (bool) $our ?? true;
 | 
			
		||||
            $holes = (int) $holes ?? throw new exception('Не передан параметр holes');
 | 
			
		||||
            $diameter = (float) $diameter ?? throw new exception('Не передан параметр diameter');
 | 
			
		||||
            $discount = (float) $discount ?? throw new exception('Не передан параметр discount');
 | 
			
		||||
            $cutting = (float) $cutting ?? throw new exception('Не передан параметр time');
 | 
			
		||||
 | 
			
		||||
            if ($width <= 0 || $height <= 0 || $length <= 0) {
 | 
			
		||||
                // Неподходящие для выполнения значения
 | 
			
		||||
@@ -225,9 +226,11 @@ final class calculators_model extends core
 | 
			
		||||
                throw new exception('Передан нулевой размер одной из сторон заготовки');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 | 
			
		||||
            // $gas = 'oxygen';
 | 
			
		||||
            $gas = 'air';
 | 
			
		||||
            // Инициализация инстанции баллонов
 | 
			
		||||
            $baloons = new baloons;
 | 
			
		||||
 | 
			
		||||
            // Вычисление используемого газа
 | 
			
		||||
            $baloons->gas($length, $errors) ?? throw new exception('Не удалось вычислить тип газа для резки');
 | 
			
		||||
 | 
			
		||||
            // Инициализация станка для буфера вывода
 | 
			
		||||
            $machine = [
 | 
			
		||||
@@ -236,25 +239,24 @@ final class calculators_model extends core
 | 
			
		||||
 | 
			
		||||
            // Инициализация буфера остальных вычислений для буфера вывода
 | 
			
		||||
            $other = [
 | 
			
		||||
                'additive' => (float) settings::read('additive', $errors) ?? throw new exception('Не найдено: additive'),
 | 
			
		||||
                'discount' => $discount
 | 
			
		||||
                'additive' => (float) settings::read('additive', $errors) ?? throw new exception('Не найдено: additive')
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
            // Инициализация прибавок к наценке
 | 
			
		||||
            $increase_300_3000 = (float) settings::read('additive_increase_300_3000', $errors) ?? throw new exception('Не найдено: additive_increase_300_3000');
 | 
			
		||||
            // // Инициализация прибавок к наценке
 | 
			
		||||
            // $increase_300_3000 = (float) settings::read('additive_increase_300_3000', $errors) ?? throw new exception('Не найдено: additive_increase_300_3000');
 | 
			
		||||
 | 
			
		||||
            if ($amount >= 300) {
 | 
			
		||||
                // Количество заказанных деталей равно или более чем 300 шт.
 | 
			
		||||
            // if ($amount >= 300) {
 | 
			
		||||
            //     // Количество заказанных деталей равно или более чем 300 шт.
 | 
			
		||||
 | 
			
		||||
                for ($i = 0; $i <= $amount; ++$i) {
 | 
			
		||||
                    // Перебор по количеству изготавливаемых деталей
 | 
			
		||||
            //     for ($i = 0; $i <= $amount; ++$i) {
 | 
			
		||||
            //         // Перебор по количеству изготавливаемых деталей
 | 
			
		||||
 | 
			
		||||
                    // Количество заказанных деталей равно или более чем 300 шт. и равно или менее чем 3000 шт.
 | 
			
		||||
                    if ($amount <= 3000) $other['additive'] += $increase_300_3000;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            //         // Количество заказанных деталей равно или более чем 300 шт. и равно или менее чем 3000 шт.
 | 
			
		||||
            //         if ($amount <= 3000) $other['additive'] += $increase_300_3000;
 | 
			
		||||
            //     }
 | 
			
		||||
            // }
 | 
			
		||||
 | 
			
		||||
            $other['additive'] = 1.07;
 | 
			
		||||
            // $other['additive'] = 1.07;
 | 
			
		||||
 | 
			
		||||
            // Площадь
 | 
			
		||||
            $area = $width * $height;
 | 
			
		||||
@@ -283,7 +285,7 @@ final class calculators_model extends core
 | 
			
		||||
 | 
			
		||||
            // Инициализация характеристик металла
 | 
			
		||||
            $metal = [
 | 
			
		||||
                'cut' => metals::cut($type, $gas, $length, $errors),
 | 
			
		||||
                'cut' => metals::cut($type, $baloons->gas, $length, $errors),
 | 
			
		||||
                'weight' => metals::kg($type, $errors) * $length,
 | 
			
		||||
                'cost' => $list['ton'] / 1000 // Цена за килограмм
 | 
			
		||||
            ];
 | 
			
		||||
@@ -294,6 +296,9 @@ final class calculators_model extends core
 | 
			
		||||
                throw new exception('Ошибка при вычислении характеристик металла');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($cutting === 0.0) {
 | 
			
		||||
                // Не передана длина реза
 | 
			
		||||
 | 
			
		||||
                if ($holes == 0 ?? $diameter == 0) {
 | 
			
		||||
                    // Не переданы данные об отверстиях
 | 
			
		||||
 | 
			
		||||
@@ -305,8 +310,10 @@ final class calculators_model extends core
 | 
			
		||||
                    // Длина реза (мм)
 | 
			
		||||
                    $cutting = (3.1416 * $diameter * $holes + $width * 2 + $height * 2) * self::coefficient($complexity, $area, $length, $errors);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $metal['cut'] = 65;
 | 
			
		||||
            // Запись в буфер вывода
 | 
			
		||||
            $other['cutting'] = $cutting;
 | 
			
		||||
 | 
			
		||||
            // Время реза одной детали (c)
 | 
			
		||||
            $time = $cutting / $metal['cut'];
 | 
			
		||||
@@ -323,6 +330,9 @@ final class calculators_model extends core
 | 
			
		||||
            // Стоимость переработки (руб)
 | 
			
		||||
            $other['reprocessing'] = self::reprocessing($complexity, $length, $errors) / 1000 * $weight;
 | 
			
		||||
 | 
			
		||||
            // Стоимость аренды помещения
 | 
			
		||||
            $other['rent'] = $time * $amount / 60 / 60 * (int) settings::read('rent', $errors) ?? throw new exception('Не найдено: rent');
 | 
			
		||||
 | 
			
		||||
            // (Наш металл) Стоимость металла (руб)
 | 
			
		||||
            if ($our) $machine['metal'] = $weight * $metal['cost'];
 | 
			
		||||
 | 
			
		||||
@@ -338,6 +348,41 @@ final class calculators_model extends core
 | 
			
		||||
            // Вычисление количества листов
 | 
			
		||||
            for ($lists = 0; ++$lists * $list['volume'] < $volume * $amount;);
 | 
			
		||||
 | 
			
		||||
            // Условия для прибавления листа (костыль)
 | 
			
		||||
            if (($length > 3 && ($width >= 750 || $height >= 750))
 | 
			
		||||
                || ($length >= 0.5 && $length <= 3 && ($width >= 620 || $height >= 620))
 | 
			
		||||
            ) ++$list;
 | 
			
		||||
 | 
			
		||||
            // Инициализация данных линзы
 | 
			
		||||
            $lense = [
 | 
			
		||||
                'cost' => (int) settings::read('laser_lense_cost', $errors) ?? throw new exception('Не найдено: laser_lense_cost'),
 | 
			
		||||
                'length' => (int) settings::read('laser_lense_flow', $errors) ?? throw new exception('Не найдено: laser_lense_flow')
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
            // Вычисление количества используемых линз
 | 
			
		||||
            $lenses = $cutting / $lense['length'];
 | 
			
		||||
 | 
			
		||||
            // Запись данных о линзах в буфер вывода (стоимость)
 | 
			
		||||
            $machine['lenses'] = $lenses * $lense['cost'];
 | 
			
		||||
 | 
			
		||||
            // Вычисление количества использованных баллонов
 | 
			
		||||
            $baloons->amount($type, $cutting * $amount, $length, errors: $errors) ?? throw new exception('Не удалось вычислить количество используемых баллонов');
 | 
			
		||||
 | 
			
		||||
            // Вычисление стоимости баллонов
 | 
			
		||||
            $baloons->cost($type, errors: $errors) ?? throw new exception('Не удалось вычислить стоимость баллонов');
 | 
			
		||||
 | 
			
		||||
            // Запись данных о баллонах в буфер вывода
 | 
			
		||||
            $other['baloons'] = [
 | 
			
		||||
                'amount' => $baloons->amount,
 | 
			
		||||
                'cost' => $baloons->cost
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
            // Запись данных о баллонах в буфер вывода
 | 
			
		||||
            $other['baloons'] = [
 | 
			
		||||
                'amount' => $baloons->amount,
 | 
			
		||||
                'cost' => $baloons->cost
 | 
			
		||||
            ];
 | 
			
		||||
 | 
			
		||||
            // Вычисление времени работы разнорабочих (ч)
 | 
			
		||||
            $work = $lists * $load / 60;
 | 
			
		||||
 | 
			
		||||
@@ -375,7 +420,7 @@ final class calculators_model extends core
 | 
			
		||||
                    [
 | 
			
		||||
                        'time' => [
 | 
			
		||||
                            'design' => $operator['time'],
 | 
			
		||||
                            'machine' => ($time * $amount / 60 / 60) + $work
 | 
			
		||||
                            'machine' => $time * $amount / 60 / 60 + $work
 | 
			
		||||
                        ],
 | 
			
		||||
                        'hour' => $operator['hour']
 | 
			
		||||
                    ]
 | 
			
		||||
@@ -407,6 +452,8 @@ final class calculators_model extends core
 | 
			
		||||
                ];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $machine['depreciation'] = $time * $amount / 60 / 60 * (int) settings::read('laser_depreciation', $errors) ?? throw new exception('Не найдено: laser_depreciation');
 | 
			
		||||
 | 
			
		||||
            // Инициализация станков
 | 
			
		||||
            $machines = [
 | 
			
		||||
                $machine
 | 
			
		||||
 
 | 
			
		||||
@@ -116,3 +116,56 @@
 | 
			
		||||
#calculator>.calculator>div>div>input[type="range"] {
 | 
			
		||||
    min-width: 50%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#calculator>.calculator>div>div>input[type="range"] {
 | 
			
		||||
    min-width: 50%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#calculator>#result {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#calculator>#result>a {
 | 
			
		||||
    margin: unset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#calculator>#result>#errors {
 | 
			
		||||
    margin-bottom: unset;
 | 
			
		||||
    padding: 15px 25px;
 | 
			
		||||
    background-color: #acacac;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#calculator>#result>#errors:empty {
 | 
			
		||||
    margin: unset;
 | 
			
		||||
    padding: unset;
 | 
			
		||||
    background-color: unset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#calculator>#result>#errors>dt {
 | 
			
		||||
    margin-bottom: 8px;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#calculator>#result>#errors>dd {
 | 
			
		||||
    margin-left: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#calculator>#result>div[type="row"]:first-of-type {
 | 
			
		||||
    margin-top: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#calculator>#result>div[type="row"]:last-of-type {
 | 
			
		||||
    margin-bottom: 20px;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#calculator>#result>div[type="row"] {
 | 
			
		||||
    padding: 0 10px;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-direction: column;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#calculator>#result>div[type="row"]>label {
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -71,17 +71,25 @@ let calculator = {
 | 
			
		||||
    calculate() {
 | 
			
		||||
        // Запрос и генерация HTML с данными о рассчете со всех калькуляторов
 | 
			
		||||
 | 
			
		||||
        // Инициализация параметров
 | 
			
		||||
        let cutting = document.getElementById('cutting');
 | 
			
		||||
        let discount = document.getElementById('discount');
 | 
			
		||||
 | 
			
		||||
        // Инициализация буфера запроса
 | 
			
		||||
        let query = {};
 | 
			
		||||
        let query = {
 | 
			
		||||
            calculators: {},
 | 
			
		||||
            cutting: +cutting.value ?? 0,
 | 
			
		||||
            discount: +discount.value ?? 0
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        for (const number in this.calculators) {
 | 
			
		||||
            // Перебор калькуляторов
 | 
			
		||||
 | 
			
		||||
            // Инициализация буфера запроса для нового калькулятора
 | 
			
		||||
            query[number] = {};
 | 
			
		||||
            query['calculators'][number] = {};
 | 
			
		||||
 | 
			
		||||
            // Инициализация типа калькулятора
 | 
			
		||||
            query[number]['calculator'] = this.calculators[number].getAttribute('data-calculator');
 | 
			
		||||
            query['calculators'][number]['calculator'] = this.calculators[number].getAttribute('data-calculator');
 | 
			
		||||
 | 
			
		||||
            for (const buyer of this.index.querySelectorAll('input[name="buyer"]')) {
 | 
			
		||||
                // Перебор полей с параметрами типа заказчика
 | 
			
		||||
@@ -90,7 +98,7 @@ let calculator = {
 | 
			
		||||
                    // Найдено выбранное поле
 | 
			
		||||
 | 
			
		||||
                    // Запись в буфер запроса
 | 
			
		||||
                    query[number]['buyer'] = buyer.value;
 | 
			
		||||
                    query['calculators'][number]['buyer'] = buyer.value;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -101,7 +109,7 @@ let calculator = {
 | 
			
		||||
                    // Найдено выбранное поле
 | 
			
		||||
 | 
			
		||||
                    // Запись в буфер запроса
 | 
			
		||||
                    query[number]['complexity'] = complexity.value;
 | 
			
		||||
                    query['calculators'][number]['complexity'] = complexity.value;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -112,22 +120,19 @@ let calculator = {
 | 
			
		||||
                    // Флажок
 | 
			
		||||
 | 
			
		||||
                    // Запись в буфер запроса
 | 
			
		||||
                    query[number][field.getAttribute('data-calculator-parameter')] = field.checked;
 | 
			
		||||
                    query['calculators'][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;
 | 
			
		||||
                    query['calculators'][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['calculators'][number][field.getAttribute('data-calculator-parameter')] = field.value ?? field.options[field.selectedIndex].text;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Сортировка
 | 
			
		||||
            query[number] = query[number];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return fetch('/calculator/calculate', {
 | 
			
		||||
@@ -141,31 +146,67 @@ let calculator = {
 | 
			
		||||
                        // Инициализация буфера расходов
 | 
			
		||||
                        let expenses = 0;
 | 
			
		||||
 | 
			
		||||
                        // Инициализация буфера с данными расчёта
 | 
			
		||||
                        let result;
 | 
			
		||||
 | 
			
		||||
                        if (this.generate.error(success.errors) > 0) {
 | 
			
		||||
                            // Найдены ошибки
 | 
			
		||||
 | 
			
		||||
                            // Генерация текста ответа
 | 
			
		||||
                            result = 'Ошибка';
 | 
			
		||||
                        } else {
 | 
			
		||||
                            // Не найдены ошибки
 | 
			
		||||
 | 
			
		||||
                            if (success.other.cutting !== undefined) {
 | 
			
		||||
                                // Получены данные времени работы
 | 
			
		||||
 | 
			
		||||
                                // Запись полученных данных
 | 
			
		||||
                                cutting.value = success.other.cutting;
 | 
			
		||||
                                cutting.parentElement.children[0].innerText = 'Длина реза 1 детали (' + cutting.value + 'мм)';
 | 
			
		||||
 | 
			
		||||
                                // Разблокировка параметра
 | 
			
		||||
                                cutting.removeAttribute('disabled');
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            if (success.other.discount !== undefined) {
 | 
			
		||||
                                // Получены данные скидки
 | 
			
		||||
 | 
			
		||||
                                // Запись полученных данных
 | 
			
		||||
                                discount.value = success.other.discount;
 | 
			
		||||
                                discount.parentElement.children[0].innerText = 'Скидка (' + discount.value + '%)';
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            for (const [, machine] of Object.entries(success.machines)) {
 | 
			
		||||
                                // Перебор станков
 | 
			
		||||
 | 
			
		||||
                            // Прибавление данных к буферу расходов
 | 
			
		||||
                                // Прибавление данных станка к буферу расходов
 | 
			
		||||
                                expenses += (machine.electricity + (machine.metal ?? 0));
 | 
			
		||||
 | 
			
		||||
                                // Прибавление амортизации к буферу вывода
 | 
			
		||||
                                expenses += machine.reprocessing ?? 0;
 | 
			
		||||
 | 
			
		||||
                                // Прибавление линз к буферу вывода
 | 
			
		||||
                                expenses += machine.lenses ?? 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;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
@@ -176,19 +217,29 @@ let calculator = {
 | 
			
		||||
                                expenses += handyman.time * handyman.hour;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        // Добавление переработки
 | 
			
		||||
                        expenses += success.other.reprocessing;
 | 
			
		||||
                            // Прибавление аренды к буферу расходов
 | 
			
		||||
                            expenses += success.other.rent ?? 0;
 | 
			
		||||
 | 
			
		||||
                        // Добавление наценки (коэффициент)
 | 
			
		||||
                        expenses *= success.other.additive;
 | 
			
		||||
                            // Прибавление переработки к буферу расходов
 | 
			
		||||
                            expenses += success.other.reprocessing ?? 0;
 | 
			
		||||
 | 
			
		||||
                        // Добавление скидки менеджера
 | 
			
		||||
                        expenses -= expenses * (success.other.discount / 100)
 | 
			
		||||
                            // Прибавление баллонов к буферу расходов
 | 
			
		||||
                            expenses += success.other.baloons.cost ?? 0;
 | 
			
		||||
 | 
			
		||||
                            // Вычисление наценки (коэффициент)
 | 
			
		||||
                            expenses *= success.other.additive ?? 1;
 | 
			
		||||
 | 
			
		||||
                            // Вычитание скидки менеджера
 | 
			
		||||
                            expenses -= expenses * ((discount.value ?? 100) / 100);
 | 
			
		||||
 | 
			
		||||
                            // Округление
 | 
			
		||||
                            expenses = expenses.toFixed(2);
 | 
			
		||||
 | 
			
		||||
                        if (this.generate.result(expenses + ' рублей')) {
 | 
			
		||||
                            // Генерация текста ответа
 | 
			
		||||
                            result = expenses + ' рублей';
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (this.generate.result(result)) {
 | 
			
		||||
                            console.log(`[КАЛЬКУЛЯТОР] Сгенерирован результат: ${expenses} рублей`);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            console.log('[КАЛЬКУЛЯТОР] [ОШИБКА] Не удалось сгенерировать результат');
 | 
			
		||||
@@ -261,54 +312,6 @@ let calculator = {
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
        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 с полем выбора марки металла
 | 
			
		||||
 | 
			
		||||
@@ -373,6 +376,116 @@ let calculator = {
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
        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) {
 | 
			
		||||
                // Не найден элемент с данными расчётов
 | 
			
		||||
            } else {
 | 
			
		||||
                // Найден элемент с данными расчётов
 | 
			
		||||
 | 
			
		||||
                if (expenses !== undefined) {
 | 
			
		||||
                    // Переданы расходы
 | 
			
		||||
 | 
			
		||||
                    // Инициализация элемента
 | 
			
		||||
                    let element = document.getElementById('calculate');
 | 
			
		||||
 | 
			
		||||
                    if (element == null) {
 | 
			
		||||
                        // Не найден элемент с результатом расчёта
 | 
			
		||||
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // Запись расходов в элемент (подразумевается кнопка отправки на расчёт)
 | 
			
		||||
                    element.innerText = expenses;
 | 
			
		||||
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return request();
 | 
			
		||||
        },
 | 
			
		||||
        error(errors = []) {
 | 
			
		||||
            // Генерация ошибки
 | 
			
		||||
 | 
			
		||||
            // Инициализация количества обработанных ошибок
 | 
			
		||||
            let amount = 0;
 | 
			
		||||
 | 
			
		||||
            if (typeof errors === 'object') {
 | 
			
		||||
                // Передан массив с ошибками и он является массивом
 | 
			
		||||
 | 
			
		||||
                // Инициализация буфера для проверки вложенности массива
 | 
			
		||||
                let first = Object.values(errors)[0];
 | 
			
		||||
 | 
			
		||||
                if (first !== undefined && first.text === undefined) {
 | 
			
		||||
                    // Найден массив с ошибками (категория)
 | 
			
		||||
 | 
			
		||||
                    // Вход в рекурсию
 | 
			
		||||
                    amount += this.error(first);
 | 
			
		||||
                } else {
 | 
			
		||||
                    // Не найден массив с ошибками (подразумевается, что это и есть информация об ошибке)
 | 
			
		||||
 | 
			
		||||
                    // Инициализация элемента-оболочки
 | 
			
		||||
                    let list = document.getElementById('errors');
 | 
			
		||||
 | 
			
		||||
                    // Перезапись данных об ошибках
 | 
			
		||||
                    list.innerText = '';
 | 
			
		||||
 | 
			
		||||
                    // Проверка на наличие ошибок
 | 
			
		||||
                    if (errors.length === 0) return false;
 | 
			
		||||
 | 
			
		||||
                    if (list !== null) {
 | 
			
		||||
                        // Оболочка найдена
 | 
			
		||||
 | 
			
		||||
                        for (const [, error] of Object.entries(errors)) {
 | 
			
		||||
                            // Перебор станков
 | 
			
		||||
 | 
			
		||||
                            // Инициализация элемента-заголовка
 | 
			
		||||
                            let term = document.createElement('dt');
 | 
			
		||||
 | 
			
		||||
                            // Запись содержимого
 | 
			
		||||
                            term.innerText = error.text;
 | 
			
		||||
 | 
			
		||||
                            // Инициализация элемента-описания
 | 
			
		||||
                            let definition = document.createElement('dd');
 | 
			
		||||
 | 
			
		||||
                            // Запись содержимого
 | 
			
		||||
                            definition.innerText = error.file + ' в строке ' + error.line;
 | 
			
		||||
 | 
			
		||||
                            // input.setAttribute('id', element.id);
 | 
			
		||||
 | 
			
		||||
                            // Запись в список
 | 
			
		||||
                            list.insertAdjacentElement('beforeend', term);
 | 
			
		||||
                            list.insertAdjacentElement('beforeend', definition);
 | 
			
		||||
 | 
			
		||||
                            // Добавление к счётчику обработанных ошибок
 | 
			
		||||
                            ++amount;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return amount;
 | 
			
		||||
        },
 | 
			
		||||
        calculators: {
 | 
			
		||||
            laser() {
 | 
			
		||||
                // Запрос и генерация HTML с калькулятором лазерной резки
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
<h3>Лазерная резка</h3>
 | 
			
		||||
<h3>Лазерная резка <span title="Удалить"></span></h3>
 | 
			
		||||
<section class="calculator" data-calculator="laser">
 | 
			
		||||
    <div>
 | 
			
		||||
        <label>Тип</label>
 | 
			
		||||
@@ -66,27 +66,4 @@
 | 
			
		||||
            <input data-calculator-parameter="our" type="checkbox" title="Используется наш металл" checked>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div>
 | 
			
		||||
        <label>Скидка ({{ calculators.laser.discount.default ?? 0 }}%)</label>
 | 
			
		||||
        <div>
 | 
			
		||||
            <input data-calculator-parameter="discount" type="range" title="Скидка менеджера"
 | 
			
		||||
                value="{{ calculators.laser.discount.default ?? 0 }}" min="{{ calculators.laser.discount.min ?? 0 }}"
 | 
			
		||||
                max="{{ calculators.laser.discount.max ?? 5 }}" step="{{ calculators.laser.discount.step ?? 1 }}" oninput="this.parentElement.parentElement.children[0].innerText = 'Скидка (' + this.value + '%)';">
 | 
			
		||||
 | 
			
		||||
            <!-- <datalist id="discount_level">
 | 
			
		||||
                <option value="0" label="{{ calculators.laser.discount.min ?? 0 }}%">
 | 
			
		||||
                <option value="10">
 | 
			
		||||
                <option value="20">
 | 
			
		||||
                <option value="30">
 | 
			
		||||
                <option value="40">
 | 
			
		||||
                <option value="50" label="{{ ((calculators.laser.discount.max ?? 5) + (calculators.laser.discount.min ?? 0)) / 2 }}%">
 | 
			
		||||
                <option value="60">
 | 
			
		||||
                <option value="70">
 | 
			
		||||
                <option value="80">
 | 
			
		||||
                <option value="90">
 | 
			
		||||
                <option value="100" label="{{ calculators.laser.discount.max ?? 5 }}%">
 | 
			
		||||
            </datalist> -->
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</section>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,46 @@
 | 
			
		||||
<section id="result">
 | 
			
		||||
    <div type="row">
 | 
			
		||||
        <label>Длина реза 1 детали ({{ cutting.default ?? 0 }}мм)</label>
 | 
			
		||||
        <input id="cutting" type="range" title="Длина реза 1 детали "
 | 
			
		||||
            value="{{ cutting.default ?? 0 }}" min="{{ cutting.min ?? 0 }}" max="{{ cutting.max ?? 10000 }}"
 | 
			
		||||
            step="{{ cutting.step ?? 1 }}"
 | 
			
		||||
            oninput="this.parentElement.children[0].innerText = 'Длина реза 1 детали (' + this.value + 'мм)';" disabled>
 | 
			
		||||
        <!-- <datalist id="cutting_level">
 | 
			
		||||
                <option value="0" label="{{ cutting.min ?? 0 }}%">
 | 
			
		||||
                <option value="10">
 | 
			
		||||
                <option value="20">
 | 
			
		||||
                <option value="30">
 | 
			
		||||
                <option value="40">
 | 
			
		||||
                <option value="50" label="{{ ((cutting.max ?? 10000) + (cutting.min ?? 0)) / 2 }}%">
 | 
			
		||||
                <option value="60">
 | 
			
		||||
                <option value="70">
 | 
			
		||||
                <option value="80">
 | 
			
		||||
                <option value="90">
 | 
			
		||||
                <option value="100" label="{{ cutting.max ?? 100005 }}%">
 | 
			
		||||
            </datalist> -->
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div type="row">
 | 
			
		||||
        <label>Скидка ({{ discount.default ?? 0 }}%)</label>
 | 
			
		||||
        <input id="discount" type="range" title="Скидка менеджера"
 | 
			
		||||
            value="{{ discount.default ?? 0 }}" min="{{ discount.min ?? 0 }}" max="{{ discount.max ?? 5 }}"
 | 
			
		||||
            step="{{ discount.step ?? 1 }}"
 | 
			
		||||
            oninput="this.parentElement.children[0].innerText = 'Скидка (' + this.value + '%)';">
 | 
			
		||||
 | 
			
		||||
        <!-- <datalist id="discount_level">
 | 
			
		||||
                <option value="0" label="{{ calculators.discount.min ?? 0 }}%">
 | 
			
		||||
                <option value="10">
 | 
			
		||||
                <option value="20">
 | 
			
		||||
                <option value="30">
 | 
			
		||||
                <option value="40">
 | 
			
		||||
                <option value="50" label="{{ ((calculators.discount.max ?? 5) + (discount.min ?? 0)) / 2 }}%">
 | 
			
		||||
                <option value="60">
 | 
			
		||||
                <option value="70">
 | 
			
		||||
                <option value="80">
 | 
			
		||||
                <option value="90">
 | 
			
		||||
                <option value="100" label="{{ discount.max ?? 5 }}%">
 | 
			
		||||
            </datalist> -->
 | 
			
		||||
    </div>
 | 
			
		||||
    <a id="calculate" class="unselectable" type="button" onclick="return calculator.calculate();">0 рублей</a>
 | 
			
		||||
    <dl id="errors"></dl>
 | 
			
		||||
</section>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user