Конвертация валюты для сайта электронной коммерции – Предотвращение неправильной полной корзины из-за округления

Я добавляю поддержку нескольких валют в приложение для электронной коммерции. Способ, которым я столкнулся с проблемой, состоял в том, чтобы сохранить приложение в его базовой валюте и вызвать шаблон для функции priceDisplay () / plugin в любое время, когда он отображает цену. Таким образом, шаблон продолжает получать цены в долларах. Функция priceDisplay корректно преобразует цену, если это необходимо, и добавляет правильный знак $ или Euro в зависимости от настроек зрителей, хранящихся в сеансе. При заказе заявки приложение будет хранить заказ в долларовой сумме, а также код валюты и валюту. Кроме того, мы будем взимать кредитную карту клиента в своей валюте, чтобы убедиться, что они получают счет, точно то, что было показано на экране заказа.

Теперь проблема связана с отображением итогов корзины в тележке, а также во время проверки. Например, приложение отправляет шаблон, чтобы цены отображались в корзине покупок:

промежуточный итог: 9,75
корабль: 5.95
всего: 15,70

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

промежуточное соединение: 10,725 -> 10,73
корабль: 6.545 -> 6.55
всего: 17,27

Вы можете видеть, что суммарный итог + корабль = 17,28, но общая конвертация равна 17,27.

Так что пара вариантов, которые, я думаю, могла бы сработать, хотя и не продумана до конца:

  1. Обрабатывать все преобразования со стороны приложения
  2. Если элементы будут суммированы, шаблон должен отправить все отдельные сложения и общее количество вместе в базовой валюте в функцию priceDisplay, которая будет их конвертировать и гарантировать, что конвертированное общее количество и сумма слагаемых совпадут . В этом случае, как мне сообщить приложению, что сумма не равна 15.70, а может быть 15.71 или 15.69 (так как мы будем хранить заказ в базовой валюте и умножаться на exchangeRate при обработке платежа).
  3. Следите за уменьшенными / добавленными десятичными точками как частью конверсий и делайте что-то «умное» с этим. Итак, в этом примере, 10.725, мы добавили 5 тысячных. Поэтому, когда мы конвертируем 6.545, сначала нужно отбросить .005, а затем конвертировать. Возможно, это процесс, описанный выше в варианте 2?
  4. Ваше предложение здесь.

Если это имеет значение, приложение находится в PHP, а шаблон – Smarty.

Вы также можете увидеть ту же проблему при добавлении итогов строк элементов корзины:
3 элемента x 9,75 каждый = 29,25
конвертирована:
3 элемента х 10,73 (10,725) = 32,18 (32,175)
но 3 х 10,73 = 32,19! = 32,18

Я твердо в 1 лагере. Конвертация валюты – это основная бизнес-логика, которая принадлежит вашим моделям, а не вашим взглядам.

Кроме того, хотя деньги выглядят как числа с плавающей запятой, это не так. Деньги меняют руки в целых количествах независимо от вашего базового блока. В США, например, если gumballs 10 центов каждый, и я покупаю десять, то я торгую 100 пенни за 10 gumballs. Даже если я дам долларовый счет, с точки зрения программного обеспечения, лучше всего считать это 100 пенни.

Подробнее об этом см. «Шаблоны архитектуры корпоративного приложения» Мартина Фаулера и «Шаблоны анализа» . Он подробно обсуждает все вопросы и дает хороший пример кода. Вы также можете найти часть этой информации в Интернете:

  • Количество (с некоторым кодом выборки денег)
  • Деньги (в основном указатель на его книгу)

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

Если вы рассчитываете на основе конвертированной валюты, вы действительно не должны делать этот расчет в своей логике представления.

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

Не используйте числа с плавающей запятой за деньги! Вы позволяете себе в мир боли с округлением без уважительной причины. Поскольку PHP не имеет десятичного типа с фиксированной точкой, выполните все расчеты денег с помощью целых чисел. См. Ссылки Уильяма.