Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Container for Money of different currencies #770

Closed
hmiller-mykey opened this issue May 4, 2018 · 9 comments
Closed

Container for Money of different currencies #770

hmiller-mykey opened this issue May 4, 2018 · 9 comments

Comments

@hmiller-mykey
Copy link

Hello!

Apologies if this is the wrong place to ask this question.

I'm looking for guidance with dealing with multiple currencies.

I have a unique constraint where I always want to keep Money of different currency separate(Money should never be exchanged). Additionally I want to be able to perform math operations on Money with different currency, and have the resultant object that contains each currency seperate.
For example:

10 USD + 10 CAD = { 10 USD, 10 CAD }

10 CAD + 10 CAD = { 20 CAD }

10 CAD + 10 CAD + 10 USD = { 20 CAD, 10 USD }

Basically what I need is a container object that lets me perform operations with different currency Money, but keeps them separate.

I haven't been able to find any gems that do something like this.

Has anyone had any experience with this?
Is there some gem that does this that I cannot find?

Thank you!

@antstorm
Copy link
Contributor

antstorm commented May 4, 2018

@hmiller-mykey this is a very interesting requirement and I see how that would make sense in some cases. I haven't hard to deal with this so I don't know if any plugins exist, however this shouldn't be hard to implement yourself.

If you want to utilise the + you would need to overwrite this on Money and instead of returning back an instance of Money, return your own object that keeps the track of different currency "buckets". Then when you add anything to it — it puts the amount in an appropriate bucket or creates a new one.

@hmiller-mykey
Copy link
Author

@antstorm This is good stuff. That is how we are planning to implement it.
We are considering whether to make it public or not. Do you think this is something that the community might use, if it was available?

@printercu
Copy link
Member

printercu commented May 7, 2018

I suggest not to override default implementation, but define separate class like MultiMoney or MoneyCollection. At least you'll be able to use Money#+ to sum values with same currency.

PS. You can define internal store like this @store = Hash.new { |h, currency| h[currency] = Money.new(0, currency) }. And then use it like store[money.currency] += money in #+ method.

@antstorm
Copy link
Contributor

antstorm commented May 8, 2018

@hmiller-mykey makes perfect sense to make it public. There's a good chance other people might need a similar solution.

Also @printercu has a really good point of not overriding the default implementation as it normally leads to bugs and confusion. The only problem is you won't be able to use it as a drop-in replacement, but it's all for the greater good.

@printercu
Copy link
Member

How can it be a drop-in replacement, if it would return different result type?

@antstorm
Copy link
Contributor

antstorm commented May 8, 2018

@printercu depends on the interface of the result type (duck type). It probably won't be 100% compatible, but a good part of it can be

@hmiller-mykey
Copy link
Author

I have began implementing this. MultiMoney so far I have added functionality for + - * / operators. MultiMoney accepts Money, MultiMoney or Integers(depending on the operator) as the operand.

I also made MultiMoney hashable, so for example you can do m_money[:USD] and it will return nil or the Money at that index.

I also need to create a monetize gem that works with MultiMoney, for my specific rails project.

I will keep updating this as I make progress.

If anyone has suggestions feel free to suggest to me.

@antstorm
Copy link
Contributor

antstorm commented May 9, 2018

@hmiller-mykey sounds great! Btw, why do you need an adopted monetize functionality? Are you accepting multi-currency user input?

It would also be useful if you could describe your use cases in a bit more detail.

@hmiller-mykey
Copy link
Author

I misspoke in my previous post when I said I need to create a monetize gem.
What want to do is change the money-rails gem so that my attributes setup with monetize returns a MultiMoney instead of a Money.
Do you have any input on that? If I was to create my own implementation of the money-rails gem I would potentially lose quite a bit of functionality/have to recreate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants