Номера JavaScript не добавляются правильно каждый раз, когда parseFloat toFixed - PullRequest
0 голосов
/ 17 января 2019

Я рассчитываю промежуточные итоги, налоги, доставку и страховку исходя из следующего:

public getSubTotal() {
  this.subTotal =
    document.getElementById("total").value -
    (document.getElementById("total").value * 0.07 +
      document.getElementById("total").value * 0.03 +
      document.getElementById("total").value * 0.01 +
      1.0);
  document.getElementById("tax").value =
    document.getElementById("total").value * 0.07;
  document.getElementById("shipping").value =
    document.getElementById("total").value * 0.03;
  document.getElementById("insurance").value =
    document.getElementById("total").value * 0.01;
  console.log(
    "tax: " +
      document.getElementById("total").value * 0.07 +
      " shipping: " +
      document.getElementById("total").value * 0.03 +
      " ins: " +
      document.getElementById("total").value * 0.01 +
      " total: " +
      document.getElementById("total").value +
      " subtotal: " +
      this.subTotal
  );
  return this.subTotal.toFixed(2);
}

details: {
  subtotal: document.getElementById("subTotal").value,
  tax: parseFloat(document.getElementById("tax").value).toFixed(
    2
  ),
  shipping: parseFloat(
    document.getElementById("shipping").value
  ).toFixed(2),
  handling_fee: "1.00",
  shipping_discount: "0.00",
  insurance: parseFloat(
    document.getElementById("insurance").value
  ).toFixed(2)
}

Итого фиксируется с каждым продуктом.

Когда я публикую это в PayPal API, цифры иногда складываются, а иногда нет. Я теряюсь, как это исправить.

Ниже приведен пример публикации, и я не понимаю, почему PayPal отклоняет этот пример:

details {…}
handling_fee    1.00
insurance   0.23
shipping    0.68
shipping_discount   0.00
subtotal    19.30
tax 1.60
total   22.81

Все эти числа основаны на 22,81, и на консоли отображается:

tax: 1.5967 
shipping: 0.6842999999999999 
ins: 0.2281 
total: 22.81 
subtotal: 19.3009

Как я могу сохранить parseFloat (). ToFixed (2) от изменения чисел? И если я оставляю числа с числом более двух десятичных разрядов, PayPal отклоняет его за неправильное форматирование.

Когда я использую калькулятор для этих чисел, я получаю результат 22,81

Ниже приведена ошибка, которую я получаю от PayPal - если я закомментирую раздел подробностей, то сообщение проходит без ошибок:

Error: Request to post https://www.sandbox.paypal.com/v1/payments/payment failed with 400 error. Correlation id: 12d500c6247f1, 12d500c6247f1

{
    "name": "VALIDATION_ERROR",
    "details": [
        {
            "field": "transactions[0]",
            "issue": "Item amount must add up to specified amount subtotal (or total if amount details not specified)"
        }
    ],
    "message": "Invalid request - see details",
    "information_link": "https://developer.paypal.com/docs/api/payments/#errors",
    "debug_id": "12d500c6247f1"
}

Ниже приведены несколько снимков экрана: you can see the hidden inputs have the correct values you can see the data posted to PayPal

Конечно, по мере того, как количество продуктов увеличивается, увеличивается и разница в том, что добавляется вместе с общим количеством, что приводит к моему общему вопросу.

Как мне правильно рассчитать эти позиции?

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 17 января 2019

После того, как мы пошли по кругу, взяв цену продукта, затем вычтя сумму налога, доставки, обработки и страхования, чтобы получить промежуточный итог - я понял, что я делаю эти фоны, и из-за точек с плавающей запятой будучи несколько «непредсказуемым», тогда суммы никогда не будут соответствовать 100% времени.

Вот тогда это поразило меня, и это было так очевидно. Я должен добавить все эти цифры к цене продукта:

 getFinalAmount() {
  this.model.subTotal = this.subTotal = this.prdSrvc.getPriceTotal();
  this.subTotal = parseFloat(this.subTotal).toFixed(2);

  document.getElementById("tax").value = this.model.tax = this.tax =
    this.subTotal * 0.07;
  document.getElementById(
    "shipping"
  ).value = this.model.shipping = this.shipping = this.subTotal * 0.03;
  document.getElementById(
    "insurance"
  ).value = this.model.insurance = this.insurance = this.subTotal * 0.01;

  this.total = this.payPalSrvc.finalAmount =
    parseFloat(this.tax) +
    parseFloat(this.shipping) +
    parseFloat(this.insurance) +
    parseFloat(this.subTotal) +
    1.0;

  this.payPalSrvc.finalAmount = parseFloat(
    this.payPalSrvc.finalAmount
  ).toFixed(2);
  this.total = parseFloat(this.total).toFixed(2);

  document.getElementById(
    "subTotal"
  ).value = this.model.subTotal = this.subTotal;
  document.getElementById("total").value = this.model.total = this.total;

  this.tax = parseFloat(this.tax).toFixed(2);
  this.shipping = parseFloat(this.shipping).toFixed(2);
  this.insurance = parseFloat(this.insurance).toFixed(2);
  return this.payPalSrvc.finalAmount;
}

Я также удалил валютную трубу из html, оставив меня с прямыми числами с двумя десятичными точками:

    <input type="hidden" name="tax" id="tax" value="{{ this.tax }}" />
    <input
      type="hidden"
      name="shipping"
      id="shipping"
      value="{{ this.shipping }}"
    />
    <input
      type="hidden"
      name="insurance"
      id="insurance"
      value="{{ this.insurance }}"
    />

Ниже показано, как выглядит заказ на панели инструментов PayPal: paypal dashboard detail of order

0 голосов
/ 17 января 2019

Когда вы работаете с денежными значениями, вы можете избежать многих ошибок округления, работая в центах, располагая все свои расходы в центах, а при отображении их вы можете отобразить

(cost/100).toFixed(2)

Это будет использовать целочисленную математику над плавающей точкой, и вы получите намного меньше ошибок округления.

...