Подсчитать промежуточную сумму и НДС из общей суммы

Я работаю над сайтом для финансовых расчетов. Лучшая практика для valuta — использовать десятичные дроби и не использовать числа с плавающей запятой, поэтому я знаю об этом.
Когда все значения были рассчитаны, я проверяю свои итоги, суб и НДС.

Например:
У меня есть следующие значения:

  • Общая цена: 10,00
  • Норма НДС: 21%
  • Итого: 8,26
  • НДС: 1,74

Когда я вычисляю значения, это вывод. Одно из ошибочных правил проверки, которое идет не так при округлении:

Промежуточный итог * НДС должен получить общую сумму

$calculateVatRate = ($vatRate + 100) / 100; // (21 + 100) / 100 = 1.21
$output = round($subTotal * $calculateVatRate, 2); //8.26 * 1.21 = 9.9946 -> round will 9.99 instead of 10.00

Я пробовал с:

какие-либо предложения?

— редактировать
Округление 9,9946, я ожидаю, что оно должно быть 10,00 или 10

0

Решение

Цена с учетом НДС состоит из двух компонентов. Актуальная цена и сумма НДС.

Для 21% -ной доли деление на 1.21 является правильным, то, что вам нужно проверить, это как округлить / усечь (некоторые люди любят называть последнее «округлением до нуля», очевидно). Уточните у бухгалтера, ответственного за проект, как следует рассчитывать сумму НДС.

После того, как вы взломали это, не делайте больше умножения / деления или округления любого рода. Простое сложение / вычитание с фактической официальной расчетной суммой НДС даст вам все, что вам нужно. Умножение / деление с округлением или без него приведет вас к потере, теряя копейки / центы тут и там, а иногда и «корректно» (но только по стечению обстоятельств).

При получении сумм счетов-фактур, которые включают НДС, рассчитанный инвойсером, вне вашей системы, есть два общих подхода, один из которых, как я теперь понимаю, вы используете.

Несмотря на то, что НДС является стандартным расчетом, существует несколько способов, которыми любая компания может выполнить расчет. Это означает, что НДС вам выставлен за может быть рассчитано (округление / усечение) иначе, чем ваш бухгалтер хочет, чтобы это было сделано в вашей системе, и это нормально для людей с НДС.

Что нужно сделать с НДС в счете-фактуре, так это обработать его как факт, но вам необходимо убедиться, что он правильный или хотя бы разумный (подход, который вы используете).

Чтобы убедиться в правильности выставленного счета, вам нужно знать, как поставщик рассчитывает свой НДС. Есть ограниченное количество способов, которые являются действительными, поэтому это не так сложно, как кажется. На вашем «столе поставщиков» у вас есть флаг / индикатор, который говорит, как они округляются. Узнав об этом, вы можете абсолютно точно убедиться, что выставленный вам НДС является верным.

Другой способ — это терпимость. Лично мне это не нравится, но так было сделано для счетов, полученных на последнем месте, где я работал. Одной сотой денежной единицы была применяемая терпимость.

Если вы рассчитаете НДС и округлите до ближайшей сотой единицы валюты, вы сможете проверить НДС, начисляемый на вас. В этот момент, опять же, не делайте больше умножения / деления / округления, но используйте сложение / вычитание по мере необходимости.

Я понятия не имею, как работает округление десятичных дробей в PHP.

24 / 1,21 = 19,8347 до четырех знаков после запятой.
= 19,834 до трех знаков после запятой (усечение промежуточного результата)

Если вы округлите от первого до двух знаков после запятой вручную, вы получите 19,84. Если вы округлите второе число, вы получите 19,83.

Хотя отличается, все же в пределах допуска. Однако, если вы умножите / разделите / округлите дважды, вы можете получить 0,02 (если ваш код не совпадает с кодом поставщика).

1

Другие решения

Вы создаете ошибку округления при расчете процентной ставки или общей суммы. Если ваш промежуточный итог равен 8,26, а НДС — 1,74, ставка НДС составляет 21,06%, а не 21%.

$calculateVatRat = 10 / 8.26; // 1.2106

Вам нужно учитывать десятичные дроби здесь, если вы хотите, чтобы результат был точным.

$output = round($subTotal * $calculateVatRate, 2); // 9.9999 rounded as 10.00.

Но если вы хотите, чтобы ставка НДС составляла 21%, то вам нужно взять дополнительные цифры для промежуточных итогов, чтобы обеспечить точность расчетов.

$subTotal = 8.2645;
$calculateVatRat = 1.21; // 10 / 8.2645
$output = round($subTotal * $calculateVatRate, 2); // 9.9999 rounded as 10.00.

Теперь, если вы не можете отобразить 4 цифры, вам нужно сохранить отдельное значение для отображения и расчетов.

Лучше всегда сохранять исходные расчетные значения в переменных (без округления). Только округлять каждую переменную при отображении (сохраняя переменную без изменений).

$subTotal = 10/1.21; //8.264462809917355
$vatTotal = 10 - $subTotal; // 1.735537190082646
$output = $subTotal * $calculateVatRate; //10
$subTotalDisplay = round($subTotal, 2); //8.26
$vatTotalDisplay = round($vatTotal, 2); //1.74
$outputDisplay = round($output, 2); //10.00
0