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

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

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

промежуточный итог: 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 предмета х 9,75 каждый = 29,25
Преобразованный:
3 элемента х 10,73 (10,725) = 32,18 (32,175)
но 3 х 10,73 = 32,19! = 32,18

Ответы [ 4 ]

5 голосов
/ 17 июля 2009

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

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

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

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

1 голос
/ 17 июля 2009

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

0 голосов
/ 17 июля 2009

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

0 голосов
/ 17 июля 2009

Ну, лично я бы сделал общую сумму, промежуточную сумму, добавленную к сумме корабля. Очевидно, это самый простой метод, и никто не упустит лишнюю копейку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...