Рассчитать промежуточный итог и НДС от общей суммы

Я работаю над веб-сайтом для финансовых расчетов. Лучшей практикой для 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


person eL-Prova    schedule 04.01.2016    source источник
comment
Мне нужно посмотреть, понял ли я это, вам для вашего примера нужен такой вывод: Ставка НДС: 21% НДС: 2,1 доллара Итого: 7,9 доллара, верно?   -  person Angelo Berçacola    schedule 05.01.2016
comment
@AngeloBerzacola Итого 10,00, промежуточный итог должен быть 8,26, НДС 1,74 по ватте 21%. Чтобы было ясно, 8,26 = 100%, 1,74 = 21%, 10,00 = 121%   -  person eL-Prova    schedule 05.01.2016
comment
@BillWoodger да, мы работаем с двумя цифрами, а не с четырьмя :) это деньги.   -  person eL-Prova    schedule 05.01.2016
comment
Кроме того, вы должны включить по крайней мере пример расчета для случая, который был принят, и по крайней мере для одного случая, который был отклонен.   -  person Bill Woodger    schedule 05.01.2016


Ответы (2)


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

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

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

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

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

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

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

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

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

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

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

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

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

person Bill Woodger    schedule 05.01.2016
comment
Билл, это другой способ, которым я пытался заниматься. В моем случае я импортирую счета-фактуры, поэтому цена является точной, допускается разница в 0,01, больше выдает предупреждение для проверки :-) - person eL-Prova; 05.01.2016
comment
@eL-Прова Вау. Я знаю бухгалтера, который обычно приносил на каждую встречу отчет глубиной 10 см, чтобы подчеркнуть, что ему остается держать банку на одну сотую разницы в денежной единице. Это было на торгах в международном банке. У него была бы полная корова при мысли о том, чтобы получить скидку 0,01 при цене в десять долларов. Поскольку его здесь нет, у меня есть корова от его имени :-) - person Bill Woodger; 05.01.2016
comment
Иными словами, нет оправдания точности менее 100%. По крайней мере, нет хорошего оправдания. Ваш сайт могут ограбить за 0,01 валюты за транзакцию, и никто об этом не узнает. Ваша отчетность по НДС может быть ошибочной (и это никогда не хорошо). Это выглядит некрасиво и сбивает с толку клиентов. - person Bill Woodger; 05.01.2016
comment
@eL-Прова А. Перечитывая ваш комментарий сегодня утром (думаю, я всего на час отстаю от вашего времени), я думаю, вам нужно включить эту информацию в свой вопрос. Обновление. - person Bill Woodger; 05.01.2016

Вы создаете ошибку округления при расчете процента НДС или суммы промежуточного итога. Если ваш промежуточный итог равен 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
person Tᴀʀᴇǫ Mᴀʜᴍᴏᴏᴅ    schedule 05.01.2016
comment
Ставки НДС являются фиксированными цифрами, диктуемыми правительствами. Вы не можете просто использовать другой, когда числа не являются добрыми. - person Bill Woodger; 05.01.2016
comment
Привет Тарек, спасибо за ваш ответ. Я знаю о 1.2106, но если мой промежуточный итог уже 2 цифры, и мой ватрейт тоже 2 цифры, как возможно, что 4-я цифра создает проблемы? - person eL-Prova; 05.01.2016
comment
@eL-Prova С 4-й цифрой возникнут проблемы, потому что у вас есть округление при расчете промежуточной суммы, подождите минутку. Я редактирую ответ. - person Tᴀʀᴇǫ Mᴀʜᴍᴏᴏᴅ; 05.01.2016
comment
@TareqMahmood Я проведу расследование завтра, заранее спасибо за ваш ответ / пример! - person eL-Prova; 05.01.2016
comment
Какое значение вы собираетесь хранить? Какое значение попадает на счета? Отображение одного значения и использование другого внутри приведет к всевозможным ошибкам, путанице и запросам. Хуже всего то, что это ценность, которую увидят клиенты, а потом они увидят другую ценность, или общая сумма не будет складываться. - person Bill Woodger; 05.01.2016
comment
@BillWoodger Вы никогда не сможете быть точным, если сохраните 2 десятичных знака в переменных. Лучше хранить исходные значения в переменных и только округлять их при отображении. Не будет ошибок/путаницы, потому что сохранение исходных значений всегда будет давать точные округленные значения. - person Tᴀʀᴇǫ Mᴀʜᴍᴏᴏᴅ; 05.01.2016
comment
Нет, это глупо. Это настоящие деньги. 1,74 (или как там написано в отчете) — это сумма. Ни больше, ни меньше, 100% точность. 10.00 - 1.74 (или что-то еще) - это 100% точность. Правила для того, что важно. Если вы будете все время возиться с расчетами, вы будете неточными, поскольку они будут отличаться от того, что сообщается. Вам постоянно нужно будет предполагать, что эти небольшие ошибки в итогах — это просто ошибки округления. Вы, бухгалтеры и аудиторы, должны быть... обеспокоены. - person Bill Woodger; 05.01.2016
comment
Смотрите обновление в моей последней части ответа. Я думаю, это устранит ваши заблуждения. - person Tᴀʀᴇǫ Mᴀʜᴍᴏᴏᴅ; 05.01.2016
comment
Все должны знать, что они всегда видят округленные значения. - person Tᴀʀᴇǫ Mᴀʜᴍᴏᴏᴅ; 05.01.2016
comment
Становится лучше. НДС сообщается сборщику налогов/доходов, который является очень, очень серьезным органом. Это парни, которых ты не хочешь раздражать. По крайней мере, в некоторых юрисдикциях, если ваша компания разоряется, именно они первыми распоряжаются вашими активами. Так что не связывайтесь с ними. Сумма, которая должна быть сохранена, является суммой собранного НДС. Какое значение рассчитывается путем применения процента НДС, а затем принудительно округляется/усекается. Вот почему вы привлекаете бухгалтера, чтобы все было абсолютно правильно. - person Bill Woodger; 05.01.2016
comment
Все должны знать, что оно округлено? Нет. Рассмотрим 90-летнего или восьмилетнего человека, который покупает что-то в магазине в ЕС и получает кассовый чек, показывающий разбивку НДС на его покупки. Они не отличают округлое от соленья, да и не нужно. Но те суммы НДС, которые указаны в квитанции, должны быть теми, о которых сообщается налоговикам. То, что вы собираете в качестве НДС, должно быть передано (за вычетом ваших собственных сборов по НДС), иначе налоговики расстроятся. Рассмотрим сеть супермаркетов, в которой ежедневно продается 2 млн товаров. Не может быть, чтобы до 20 000 000 евро сбились с пути при округлении. - person Bill Woodger; 05.01.2016
comment
@BillWoodger, я думаю, вы говорите о сохранении в базе данных, что меня не беспокоило, я говорил только о сохранении в переменных php, и моя цель - исправить несоответствие в расчетах OP. Но если вы хотите сохранить его в базе данных для будущего использования, вы можете сохранить округленное значение после того, как закончите все расчеты. (После того, как вы закончите расчеты, вы можете использовать округленные значения, потому что это больше не испортит расчеты). И если вас беспокоит орган по НДС, вы можете в любом случае использовать округленное значение, которое в любом случае будет 1,74. - person Tᴀʀᴇǫ Mᴀʜᴍᴏᴏᴅ; 05.01.2016