Мультивалютность: хранить ли курс валют или сразу пересчитанное значение

slavamakhotkin

Новичок
Мультивалютность: хранить ли курс валют или сразу пересчитанное значение

Здравствуйте.
Подскажите, пожалуйста, с принципом.
На сайте можно заказывать услуги. Выбранные услуги оформляются в заказ. Стоимости услуг в базе указаны в рублях. К каждому заказу привязано еще две валюты: валюта заказа (выбранная клиентом) и доллары. В долларах выводится только общая сумма заказа в списке заказов.

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

Я вижу два варианта решения.
1. Для того, чтобы пересчитать общую стоимость заказа, мне надо взять цены в рублях заказанных услуг, конвертнуть в две валюты, записать обновленные значения стоимостей услуг и, сложив, получить общую стоимость заказа в валюте заказа и долларах. Это будет происходить раз в день, количество запросов = около 20 * n, где n со временем увеличивается на несколько единиц в день. Зато при выводе на экран информации о заказе мне достаточно только выбрать цену в нужной валюте.
2. Хранить только курс валюты и при выводе на экран каждый раз точно также выбирать цены в рублях, конвертировать, но выводить на экран.

Какой вариант предпочесть или можно решить лучше?
 

флоппик

promotor fidei
Команда форума
Партнер клуба
2. т.к. будет одна точка входа-выхода - в отображении списка.
а гонятся за ошибками в пересчетах курса каждый раз при изменении технологии расчета цен... (скидок, проч, например)
ЗЫ. Конвертить по курсу, кстати, не обязательно на сервере.
 

slavamakhotkin

Новичок
одна-то одна, но ведь чтобы показать общую сумму, мне все равно надо будет вынуть все стоимости услуг и конвернуть их.

По поводу конвертировать на клиенте подумаю, спасибо
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
>Какой вариант предпочесть или можно решить лучше?

недостаточно информации
чем конкретно тебе не нравится 1й и 2й варианты?

-~{}~ 25.05.09 01:44:

>надо будет вынуть все стоимости услуг
что в этом тебе не нравится?
 

флоппик

promotor fidei
Команда форума
Партнер клуба
мне все равно надо будет вынуть все стоимости услуг и конвернуть их.
а посчитать сумму и потом ковертнуть- нельзя? или коммутативные свойства сложения уже отменили?
 

slavamakhotkin

Новичок
флоппик,

нет, нельзя. Для каждой услуги сумма в валюте округляется до целого. То есть, например, получается две услуги по 2,5 доллара. Каждая округляется до трех. И в сумме получается 6. Если округлять все сразу получится 5.

grigori,

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

-~{}~ 25.05.09 14:39:

Ладно. Буду хранить уже пересчитанные значения и обновлять их при изменении курса.
 

dimagolov

Новичок
То есть, например, получается две услуги по 2,5 доллара. Каждая округляется до трех. И в сумме получается 6. Если округлять все сразу получится 5.
офигеть бухгалтерия.... а как правильно по-твоему?

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

SiMM

Новичок
Чота мне кажется проблема высосана из пальца.
Есть таблица со стоимостью услуг
id price currency_id
и есть таблица с текущими курсами валют
id value
Зачем специально обновлять стоимости услуг с помощью 20*n запросов - непонятно.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
в бухгалтерии есть такое понятие, как валюта учета.
в бизнесе есть такое понятие - на*бать, где незаметно )))

-~{}~ 25.05.09 18:54:

Зачем специально обновлять стоимости услуг
То есть, например, получается две услуги по 2,5 доллара. Каждая округляется до трех. И в сумме получается 6. Если округлять все сразу получится 5.
для "правильной" арифметики :)
 

TutanXamoN

Новичок
То есть, например, получается две услуги по 2,5 доллара. Каждая округляется до трех. И в сумме получается 6. Если округлять все сразу получится 5.
ЭТАПЯТЬ :)
Вам не кажется что клиент увидев 2*2,5=6 немного удивится?
ИМХО: стоит округлять таки общую сумму(хотя, кстати, я лично не могу понять нафига нам учитывать копеечные колебания курса и паритсо этому поводу при таких стоимостях услуг если присутствует такое округление)

ЗЫ Курс тоже округляйте и не парьтесь.
 

dimagolov

Новичок
не, все цены надо округлить до сотни в большую сторону, и курс тоже. на ближайшие годы хватит.
 

slavamakhotkin

Новичок
Клиент не увидит 2*2,5 = 6, потому что, как я написал, стоимости услуг уже сконвертированы, и он увидит 2*3 = 6.

SIMM,
> Зачем специально обновлять стоимости услуг с помощью 20*n запросов - непонятно.

Грубо говоря, есть таблица услуг, с ценами в рублях. Из имеющихся в ней услуг пользователь составляет заказ. Заказ состоит из двух таблиц: Информация о заказе (дата, номер, пользователь и т.п.) и Услуги заказа (номер услуги, *цена*). Есть таблица валют с курсами к рублю (доллары, евров ). Расчеты ведутся в валюте. Когда пользователь составляет заказ, он отмечает, в какой валюте хочет платить. Пользователь может платить не сразу, а через некоторое время. До тех пор, пока он не оплатит, курс валюты не фиксирован. То есть, до оплаты цены показываются всегда по актуальному курсу. Также, по актуальному курсу отображается *общая стоимость* заказа.

-~{}~ 25.05.09 20:17:

Как это вообще делается, хранятся точные переконвертированные значения? А если округляются, то как быть с возникающими арифметическими ошибками в просмотре заказа, когда выводится две услуги по 3 и общая сумма - 5. Числа утрированы, это может быть 3,12*2 и общая сумма 6,02. Или на такие погрешности все забивают?
 

dimagolov

Новичок
если твоя проблема в том, что округление суммы не равно сумме округлений, то обычно разницу добавляют-отнимают от самого большого слагаемого.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
>это может быть больше тысячи запросов
в какой промежуток времени?

>Второй вариант накладнее в процессе показа
насколько накладнее?

>Клиент не увидит 2*2,5 = 6, потому что стоимости услуг уже сконвертированы
ага, он будет рад, что на сайте курс 40, а не 32

таблица услуг с ценами в рублях.
Заказ в двух таблицах: Информация о заказе (дата, номер, пользователь и т.п.) и Услуги заказа (номер услуги, *цена*).
Расчеты ведутся в валюте.
Есть таблица с курсами валют
до оплаты цены показываются по актуальному курсу.
Как это связано с тысячами запросов?
Почему нельзя просто умножать текущую цену в рублях на курс?

>как быть с возникающими арифметическими ошибками при округлении

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

AmdY

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

slavamakhotkin

Новичок
grigori, расскажи, пожалуйста.

AmdY,
а у тебя может изменяться курс, когда заказ уже составлен, и как в таком случае пересчитывается сумма заказа?
 

TutanXamoN

Новичок
> Зачем специально обновлять стоимости услуг с помощью 20*n запросов - непонятно.

Грубо говоря, есть таблица услуг, с ценами в рублях. Из имеющихся в ней услуг пользователь составляет заказ. Заказ состоит из двух таблиц: Информация о заказе (дата, номер, пользователь и т.п.) и Услуги заказа (номер услуги, *цена*). Есть таблица валют с курсами к рублю (доллары, евров ). Расчеты ведутся в валюте. Когда пользователь составляет заказ, он отмечает, в какой валюте хочет платить. Пользователь может платить не сразу, а через некоторое время. До тех пор, пока он не оплатит, курс валюты не фиксирован. То есть, до оплаты цены показываются всегда по актуальному курсу. Также, по актуальному курсу отображается *общая стоимость* заказа.
Есть постоянные цены в рублях. Соответственно сумма этих цен (будешь ты округлять по отдельности или всю сумму пох) постоянна.
Что мешает выводить клиенту данные вида сумма/курс? и зачем для этой операции 20 запросов?

А по поводу фин. операций - есть специальное понятие:
банковское — округление половины (N+1 знак = 5) к ближайшему чётному. В этом случае исчезает систематическая ошибка округления при суммировании большого количества чисел.
 

AmdY

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

TutanXamoN

Новичок
AmdY
Угу) Копейки. При покупке 10 услуг за 2,50$ человек теряет 5$ исключительно из-за оригинального мышления разработчиков.
А касательно:
Клиент не увидит 2*2,5 = 6, потому что, как я написал, стоимости услуг уже сконвертированы, и он увидит 2*3 = 6.
и
есть таблица услуг, с ценами в рублях. ...Заказ состоит из двух таблиц: Информация о заказе (дата, номер, пользователь и т.п.) и Услуги заказа (номер услуги, *цена*).
Мне показалось или из данной записи следует что помимо стоимости услуги в таблице "услуги", в таблице "услуги заказа" хранятся округленные стоимости под каждый заказ каждой услуги?
 

AmdY

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