Можно ли создать формулу для расчета скидки, которая будет меняться от одной ситуации к другой?

Добрый день! Не могли бы вы помочь мне реализовать сложную функцию расчета скидки для калькулятора стоимости? <br/> <br/> У каждого сочетания <code>Формат бумаги + Тип бумаги + Количество [&gt;=9; &gt;=99]</code> имеется своя фиксированная скидка. <br/> <br/> Формат бумаги имеет <code>value</code>, который представляет цену одного листа без учета скидки. Тип бумаги также имеет <code>value</code>, означающий множитель стоимости одного листа для данного типа бумаги. Для простоты я указал два типа бумаги, но на самом деле их много. <br/> <br/> Примеры: <br/> <code>Лист А2 * Матовый тип бумаги = 4</code> <br/> <code>Лист А2 * Матовый тип бумаги * 10 шт = 36</code> <br/> <code>Лист А2 * Матовый тип бумаги * 100 шт = 350</code> <br/> <br/> При смене типа бумаги на <code>Глянцевый</code>: <br/> <code>Лист А2 * Глянцевый тип бумаги = 2</code> <br/> <code>Лист А2 * Глянцевый тип бумаги * 10 шт = 19</code> <br/> <code>Лист А2 * Глянцевый тип бумаги * 100 шт = 185</code> <br/> <br/> Как видно, комбинации бумаги и типа имеют различный уровень фиксированной скидки в зависимости от количества. <br/> <br/> <pre><code class="html">&lt;div id="calc"&gt;

	&lt;label&gt;Формат бумаги&lt;/label&gt;
	&lt;select class="form-control" id="paper"&gt;
		&lt;option value="2"&gt;А2&lt;/option&gt;
		&lt;option value="1"&gt;А3&lt;/option&gt;
	&lt;/select&gt;
	
	&lt;label&gt;Тип бумаги&lt;/label&gt;
	&lt;select class="form-control" id="paper-type"&gt;
		&lt;option value="1"&gt;Глянцевая&lt;/option&gt;
		&lt;option value="2"&gt;Матовая&lt;/option&gt;
	&lt;/select&gt;

	&lt;label&gt;Листов в упаковке&lt;/label&gt;
	&lt;input type="text" class="form-control" id="paper-amount" data-price="1"&gt;
		
	&lt;div&gt;
		&lt;sp
  • 27 ноября 2024 г. 18:43
Ответы на вопрос 2
Для создания функции расчета скидки для вашего калькулятора стоимости, вы можете использовать объект или Map для хранения фиксированных скидок по комбинациям "Формат бумаги + Тип бумаги + Количество". Ниже представлен пример реализации на JavaScript.

## Пример

```html
<div id="calc">
    <label>Формат бумаги</label>
    <select class="form-control" id="paper">
        <option value="A2">А2</option>
        <option value="A3">А3</option>
    </select>

    <label>Тип бумаги</label>
    <select class="form-control" id="paper-type">
        <option value="glossy">Глянцевая</option>
        <option value="matte">Матовая</option>
    </select>

    <label>Листов в упаковке</label>
    <input type="number" class="form-control" id="paper-amount" value="1">

    <button id="calculate">Посчитать</button>
    <div id="result"></div>
</div>

<script>
    const prices = {
        A2: { glossy: 2, matte: 4 },
        A3: { glossy: 1.5, matte: 3 }
    };

    const discounts = {
        // Количество > 8
        'A2_glossy_10': 19,
        'A2_glossy_100': 185,
        'A2_matte_10': 36,
        'A2_matte_100': 350,
        
        'A3_glossy_10': 13,
        'A3_glossy_100': 135,
        'A3_matte_10': 26,
        'A3_matte_100': 280
    };

    document.getElementById('calculate').addEventListener('click', function() {
        const paper = document.getElementById('paper').value;
        const paperType = document.getElementById('paper-type').value;
        const amount = parseInt(document.getElementById('paper-amount').value, 10);
        
        const basePrice = prices[paper][paperType];
        let totalPrice = basePrice * amount;

        // Определение скидки на основе количества
        let discountKey = `${paper}_${paperType}_${amount >= 100 ? '100' : amount >= 10 ? '10' : '1'}`;
        const discount = discounts[discountKey];

        if (discount) {
            totalPrice = discount; // применяем фиксированную скидку
        }

        document.getElementById('result').textContent = `Итоговая цена: ${totalPrice} ₽`;
    });
</script>
```

### Описание

1. **Выбор формата и типа бумаги**: Созданы селекты для выбора формата бумаги (A2 или A3) и типа бумаги (глянцевая или матовая).
2. **Хранение цен и скидок**: Используются объекты `prices` и `discounts` для хранения цен и фиксированных скидок для различных комбинаций.
3. **Кнопка расчета**: При нажатии на кнопку "Посчитать" выполняется функция, которая:
   - Читает выбранный формат, тип бумаги и количество.
   - Умножает цену за лист на количество.
   - Проверяет наличие скидки в зависимости от формата бумаги, типа бумаги и количества, и применяет ее.
   - Выводит итоговую цену.

Этот код можно расширять и модифицировать по мере необходимости, добавляя другие форматы бумаги, типы, или меняя значения скидок и цен.
1. Крепим таблицы скидок (фиксированные скидки для различных комбинаций): <br/> <br/> <pre><code class="javascript">const discounts = {
  "A2": {
    "Глянцевая": [
      { min: 1, discount: 1 }, // До 10 листов
      { min: 10, discount: 0.9 }, // От 10 листов
      { min: 100, discount: 0.85 }, // От 100 листов
    ],
    "Матовая": [
      { min: 1, discount: 1 }, // До 10 листов
      { min: 10, discount: 0.8 }, // От 10 листов
      { min: 100, discount: 0.7 }, // От 100 листов
    ],
  },
  "A3": {
    "Глянцевая": [
      { min: 1, discount: 1 },
      { min: 10, discount: 0.95 },
      { min: 100, discount: 0.9 },
    ],
    "Матовая": [
      { min: 1, discount: 1 },
      { min: 10, discount: 0.85 },
      { min: 100, discount: 0.75 },
    ],
  },
};</code></pre> <br/> <br/> 2. Функция для расчёта скидки: <br/> <br/> <pre><code class="javascript">function getDiscount(format, type, amount) {
  const rules = discounts[format][type];
  let discount = 1;

  for (const rule of rules) {
    if (amount &gt;= rule.min) {
      discount = rule.discount;
    }
  }

  return discount;
}</code></pre> <br/> <br/> 3. Обновляем код калькулятора <br/> <br/> <pre><code class="javascript">jQuery(function ($) {
  $("#calc .form-control").on("input change", function () {
    const format = $("#paper option:selected").text();
    const type = $("#paper-type option:selected").text();
    const pricePerSheet = Number($("#paper option:selected").val());
    const multiplier = Number($("#paper-type option:selected").val());
    const amount = Number($("#paper-amount").val());

    if (!amount || amount &lt; 1) {
      $("#totalprice").text("0 руб.");
      return;
    }

    // Получение скидки
    const discount = getDiscount(format, type, amount);

    // Расчёт итоговой стоимости
    const total = amount * pricePerSheet * multiplier * discount;

    // Вывод результата
    $("#totalprice").text(`${total.toLocaleString("ru-RU")}`);
  });
});</code></pre> <br/> <br/> 4. HTML с адаптацией под решение (остаётся практически неизменным): <br/> <br/> <pre><code class="html">&lt;div id="calc"&gt;
  &lt;label&gt;Формат бумаги&lt;/label&gt;
  &lt;select class="form-control" id="paper"&gt;
    &lt;option value="2"&gt;A2&lt;/option&gt;
    &lt;option value="1"&gt;A3&lt;/option&gt;
  &lt;/select&gt;

  &lt;label&gt;Тип бумаги&lt;/label&gt;
  &lt;select class="form-control" id="paper-type"&gt;
    &lt;option value="1"&gt;Глянцевая&lt;/option&gt;
    &lt;option value="2"&gt;Матовая&lt;/option&gt;
  &lt;/select&gt;

  &lt;label&gt;Листов в упаковке&lt;/label&gt;
  &lt;input type="text" class="form-control" id="paper-amount" /&gt;

  &lt;div&gt;
    &lt;span id="totalprice"&gt;0&lt;/span&gt; руб.
  &lt;/div&gt;
&lt;/div&gt;</code></pre> <br/> <br/> Вся эта пурга динамического расчёта стоимости с учетом фиксированных скидок на основе комбинаций формата бумаги, типа бумаги и количества, лучше всего использовать таблицу скидок или конфигурационный объект, который описывает правила расчёта (определил выше). <br/> <br/> Это избавит тебя от необходимости прописывать каждую комбинацию вручную и упростит поддержку кода. <br/> <br/> Код проверил <br/> <br/> <a href="https://jsfiddle.net/pnr4hz10/" rel="nofollow">https://jsfiddle.net/pnr4hz10/</a>
Похожие вопросы