Ошибки при расчете НДС в модуле commerce

25 января 2023 в 12:39
Аватар пользователя yulo yulo 0 6

День добрый всем.

У меня вот какой вопрос возник.

Имеется Drupal 9/10 (экспериментирую на 10й но на 9й думаю там все тоже самое будет).
Я пытаюсь создать магазин. Разобрался как задать НДС (20%) для товара, как создать доставку (фиксированную). Экспериментировал со скидками.

Все эти действия требуются чтобы настроить эквайринг. Подразумевается также работа с ОФД.

Создал товар стоимостью 22.22р, применил ему НДС, в настройке - НДС включен в стоимость товара. После чего попробовал создать заказ.

Вот что получается. Стоимость товара 22.22. За 5 ед. товара сумма - 111.1р (сюда должен быть включен НДС 20%). Он показывает стоимость в checkout за одну позицию товара 18.52р. Но мне в дальнейшем для платежной системы необходимо передавать полную стоимость товара (включая все скидки и налоги). Стоимость товара, которую я могу получить из заказа - 18.52р. Расчетный НДС для позиции товара - 3,7р. Здесь пока все правильно - 18.52р + 3.7р = 22.22 р.

Теперь же я смотрю на цифру, которую считает commerce за всю позицию товара и вижу там НДС - 18.52р.

Все круто, но на 5 эта цифра не делится. То есть он считает НДС не по стоимости за 1 ед товара (как он пересчитывал стоимость 1й позиции товара) а считает сейчас НДС по всей позиции в целом.

Таким образом, если прибавить стоимость товара и НДС получится 111,12р. Лишние 2 копейки, которые портят жизнь.

Я размотал как именно формируется "новая" стоимость товара (которая идет в заказ) и как формируется НДС и можно ли как-то встроиться. У меня сложилось впечатление что нет - нельзя.

Подскажите, пожалуйста, как вы решаете подобную проблему или в какую сторону посмотреть чтобы постараться решить эту проблему? Похоже, все идет к тому, что придется писать свой метод расчета цен для товаров, делать бы мне этого крайне не хотелось бы.

Комментарии

Если смотреть по коду вот тут:
https://git.drupalcode.org/project/commerce/-/blob/8.x-2.x/modules/tax/s...
то там используется именно unitPrice, то есть цена одной единицы. Можно попробовать поставить там брейкпоинт и посмотреть, что именно попадает $order_item и откуда берётся такое значение.

Хотя вот ещё здесь:
https://git.drupalcode.org/project/commerce/-/blob/8.x-2.x/modules/tax/s...
$tax_amount сначала высчитывается из юнит прайса в 133 строке, а потом пересчитывается заново в 145 для тотал прайса. Выглядит странно.

25 января 2023 в 13:35

Я мельком глянул этот issue, сложилось впечатление, что у них там решение заточено на точности округления, но это неправильный подход. Если работаешь с копейками (центами), то округлять нужно именно до копеек, а не тысячных или десятитысячных. Просто нужно высчитать НДС для одной единицы, округлить, а потом умножать на количество. А самая распространённая ошибка - это когда сначала умножают, а потом округляют.

25 января 2023 в 14:06

Ну это причина возникновения\пропадания копеек, это понятно. Это я тоже раскопал. Вопрос то в другом. Мне показалось странным что сначала рассчитывается некая "исходная" стоимость без налога, сохраняется а затем делается "обратный пересчет" но не по исходному алгоритму, когда в качестве исходных данных для расчета берется стоимость 1 ед товара, а по другому алгоритму, когда в качестве исходных данных для расчета берется стоимость всей позиции этого товара. Из-за этого и получается такая проблема - погрешности округлений. Можно ведь было также рассчитать налог для 1 ед. товара и умножить полученную цифру на кол-во товара для получения общей суммы налога которая была бы кратна кол-ву товара и прекрасно бы выделялась для определения стоимости 1 ед товара (для эквайринга), вот я сейчас думаю как мне поступить...

В order_item попадает именно рассчитанная стоимость с учетом НДС (с округлением по всем правилам) с нормальной точностью (до 2го знака) для 1 ед. товара. НДС = 3.7 руб. А вот в моем случае (как на скриншоте) делается обратный пересчет. Суммарно НДС 18.52 р, что составляет 3,704 р. для 1 ед. товара. Нехорошо.

25 января 2023 в 14:27

Можно, конечно, но не хотелось бы. Тем более придется копать параллельно еще кучу материала.

Я просто хотел узнать как другие люди справляются с подобной проблемой, есть ли какое-то "стандартное" решение? Я ведь наверняка не первый.

25 января 2023 в 15:56