What's the best strategy for storing e-commerce product information (i.e. product price, current price) in a localized-currency environment?
I came across an issue in Spree, an e-commerce engine for Ruby on Rails regarding the display of currency using localization, delimiters, precision digits, etc.
However, resolving the display of price became more complex, when we had to figure out if the storing of values in the database should include the localization delimiter / precision digits or be normalized. The solution involves localizing both the display of the value as well as potentially normalizing the stored value in the database. But I'm not sure if that's the standard practice (scrubbing the data to fit a "standard" precision and delimiter OR modifying the model to take in a "currency" field, and keeping the input standard.
CASE STUDY:
If a product from the USA (using "en" localization file) is priced at 2.99, then it is stored in the database as 2.99.
If the site updates to be localized for Germany (using "de" localization file), then it is priced at 2,99.
But should updates to that price (and cost_price) value be stored as 2.99, or 2,99? If they're stored at 2.99 and the value is returned back to the view from the model, then the localization will modify the value to be 2,99.
I'm hesitant to standardize user input without their knowledge. Is standardizing currency values normal, or should the model change to handle multi-currency formats?
An extra issue to note is that even though the Spree engine can change localization, I don't believe it can flip by user-demand yet. So it's not technically a "multi-currency" environment, I believe? I'd like to pick a choice that can scale.
RELATED QUESTIONS:
database design: accounts with multi currency
Currency modeling in database
The issue is that you have a product, selling in different exchange-regimes with different cultures. Say it's $1,450.00 USD in America, and €1111,11 in Germany. There are two main factors:
A. There are different prices in different currencies
B. There are different ways to display a money amount in different cultures
Regarding A, you could
store in one price/currency, and adjust to different exchange rates on the fly
or adjust nightly
or just have different prices in different countries
I would go with a table of prices, segregated by currency. updating nightly is probably reasonable:
ProductId Currency Price
1 EUR 1111.11
1 CAD 1436.65
1 USD 1450.00
These values should be numbers, so that you can easily do math on them if necessary. Use decimal(10,2) in your database
Regarding B
You should format the selected price to a given culture upon display. Imagine an American paying in Euros. What do they want to see? Your output would look like this, depending on the selected culture:
Say it's 1,111.11 Euros
Culture Price Long Name
de_de 1.111,11 (German)
fr_ca 1 111,11 (Quebec)
en_us 1,111.11 (US English)
It's all the same amount, just formatted differently, depending on the user's preferences.
If users are entering in different amounts, you will also have to parse their values based on the selected culture. Check out Yii's (sorry, PHP) L10N and I18N features.
Notes:
Whatever you do, don't store it as a float, or you will get subtle errors over time. Use the decimal type
Consider using 4 digits after the decimal place for fields that are the result of calculations
Related
I am doing a test for a data analytics bootcamp. i have to use google sheets and i am an absolute beginner.
We have a dataset called products that we have to extract on a google spreadsheet first. I will upload the link to my google spreadsheet here:
https://docs.google.com/spreadsheets/d/1m67VmLZispyTwFTmPdppsdJNtbvnZsZK2LBCSchUWmU/edit?usp=sharing
the question is to use a formula to say what the average unit price of all products listed is.
My formula was to write under colum F(unit price) the formula: =AVERAGE(F2:F78). but the number i get is 44702 which cant be correct, if you look at the table.
also i dont know if i have to consider Column E, where the quantityperunit is stated to answer the question.
Could someone please help me?
I feel like I answered this for you in another post recently. But I can add more details.
You are working with a spreadsheet that seems to have been created in the United States, yet you've set the locale to Germany. This is creating a conflict, because the decimal separator in Germany is a comma while the decimal separator in the US is a period.
In addition, your Col-F values are all strings, not numbers — except for the one entry in F66. So you have mixed data types, and math functions can't act on that mix.
This leaves the only valid number being 21.05. However, as I said, in Germany, this is not a valid number. It's a date: May 21. And the data of May 21 (2022) is 44702 days since the Google Sheets origin date of December 30, 1899 (which is how Sheets stores all dates). So that is why you are getting that result.
If you change your locale to "United States," this will solve some of your issues. But no matter what your locale, it won't change those strings in Col F to real numbers. So you'll need to convert them in place, or your formula is going to need to account for them.
Seeing as this is an assignment, it's unclear whether the instructor intended for you to have to address these problems, or whether the additional problems are an unintentional result of spreadsheet conversions that happened somewhere.
In addition to all of that, you interpreted the original question in your post rather than sharing the actual exact wording of the question; and wording matters.
First, I would ask the instructor if the numbers in Col F were all supposed to be real numbers, or if most of them being strings is part of the assignment.
In any case, given exactly what you have right now, this should produce the average unit price (regardless of quantity in stock, as we don't know the actual wording of that question):
=ArrayFormula(ROUND(AVERAGE(VALUE(SUBSTITUTE(F2:F78&"",".",","))),2))
It's a lot longer than it would have needed to be if not for the multiple factors I described above. That is, given the locale setting of Germany and the fact that you have mixed data types, all of the Col-F values had to be converted to strings, then all of the periods had to be SUBSTITUTEd with commas, then they all had to be converted to numbers with VALUE before AVERAGE could be applied.
I am storing phone numbers in the database in the user model in various formats. All the followings are possible.
+306974135662, 306974135662, 30 6974135662
Then from the front-end, I am getting a specific format that has the plus sign and no spaces.
+306974135662
I want to write a mongoid query that matches all the above formats. Is that possible?
User.where(phone: params[phone])
should return all 3 users with phone numbers +306974135662, 306974135662, and 30 6974135662
Option 1: store phone numbers as they are entered, use regular expressions for matching.
Option 2: store phone numbers as they are entered in one field. In another field store canonicalized representations of the phone numbers (the second one in your example). Match against the canonicalized representation.
The second option costs additional disk space, memory and pre-processing but allows queries to be simpler and faster.
I'm using Google Sheets to organize data from my global royalty statements. Currently I'm querying several tabs (one for each country) to produce a single table with results from all countries. As you can imagine, I don't want 125 Japanese Yen showing up in my charts and graphs as $125 USD (125 Y is equivalent to about $1.09 USD).
Since I receive my royalty statements in their respective currencies, I'd like to apply average conversion rates either during the query operation or after the fact. Since the table is being generated dynamically, the values won't always be the same, so I need some way to apply the conversion by searching the list of currencies on the fly. I've got a separate table on the same tab containing all the average conversion rates for each currency. Here's a sample of how this is set up:
So basically I just don't know how to say, in coding terms, "If this line item comes from the UK, divide the royalty amount by the UK exchange rate. If it comes from Canada, divide by the Canadian rate, etc."
Anyone have any insight as to how I might pull this off (or whether it's possible)? The actual table includes over 500 line items from a dozen different countries, so doing this by hand is something I'd like to avoid.
I believe you are looking for the GoogleFinance() function. You may want to set the Country to a pick list of the valid country entries so you could create the string for the conversion. I have not looked at many, but this will take a value in CA & and apply the exchange rate to convert it to the US $ Equivalent. The exchange rate in this case is an average of, I believe, the past 30 days.
=C2 * GoogleFinance("CURRENCY:CADUSD" , "average")
For your use, you can get the country code from row M if you change it to match what the formula is after, such as CAD for Canadian Dollars."
=C2 * GoogleFinance("CURRENCY:" & M2 & "USD" , "average")
Another option would be to create a lookup table and use VLOOKUP or some other function, depending on how you set up your table.
This should be useful for anyone who needs to write out amounts in words in SAP.
I need to convert an amount, e.g. $100.15, into words ("One hundred dollars and fifteen cents"). For the amount, I use function module spell_amount, which gives me "one hundred" and "fifteen". The name of the currency is easily found in table TCURT. Where can I find the name of the currency subdivision?
I think there is no such table. There are already some discussions about it (e.g at SCN: Table for currency) and the conclusion is: Make your own table.
If you want to create the table, you may get the name of sub-divisions in the German Wikipedia-article for ISO 4217 (Untereinheit means sub-division) or List of circulating currencies
I have a Practice model that is storing start_time, end_time and day.
That information (like the rest of the site) will need to be displayed in 3 different
languages.
Start_time and end_time are both stored as Datetime types in the DB.
Day is not yet implemented, but will be shown as a select box. I have see people suggest an array of constants and storing it as an integer in the DB. While that seems reasonable, I am having trouble imagining that working well with different languages (using either I18n or Globalize2).
What is the cleanest way to implement this so it works well in different languages?
I can't see a good reason to store the days of the week in the database; I'd be surprised if such names will change and we are talking about 7 * 3 strings, that is a small amount of data to handle for your application.
i18n is the way to go. You can browser this repository to find day_names already traslated in different languages.
If you can't store or calculate the day of the week from the start and end DateTime objects, then I would recommend using an ENUM in the database - this causes the data to be stored as an integer - which takes up less space and is easier to index, and the conversion to the string types is done automatically for you so that you can query and insert strings, but the actual database values are integers.
Definitely do not store these values as strings though, it's harder to deal with them and they take up more space.