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

No support for adding CurrencyProviders #61

Open
devsi opened this issue Jun 2, 2022 · 6 comments
Open

No support for adding CurrencyProviders #61

devsi opened this issue Jun 2, 2022 · 6 comments

Comments

@devsi
Copy link

devsi commented Jun 2, 2022

Hi,

Although you do support custom currencies through new Currency, the project does not support the expectation that the Money class may not rely on the ISOCurrencyProvider, and could instead rely on a CurrencyProviderInterface.

I propose making ISOCurrencyProvider an implementation of CurrencyProviderInterface, and setting it to default to maintain the existing functionality, and then enable users to set their own Concrete CurrencyProvider to allow for additional options.

This would cover the case where cryptocurrencies (popularity rising as they are!) can be built using the interface and be validated correctly, instead of having to manually override the string currency with a new Currency() every time. This is for sure necessary as a developer when you want to dynamically load a list of available crypto's. I wouldn't expect the CryptoCurrencyProvider to be a part of this project, but at least the Interface to support additional non standard currencies.

I would be more than happy to pick this work up and submit a PR. I am writing it anyway for my local project but without the reliance on the Interface :)

Thanks.

@BenMorel
Copy link
Member

BenMorel commented Jun 3, 2022

Hi, I don't have a problem with introducing a CurrencyProviderInterface, however I'm reluctant to inject it globally so that it can be used in Money::of() as a default value. I'm against using any kind of global state here.

IMO, if you're using something else than ISO currencies, you should create your Monies from a factory that gets the provider injected, not from Money::of().

@devsi
Copy link
Author

devsi commented Jun 3, 2022

Absolutely I agree. I wouldn't want a secondary provider to come in through Money::of either That makes no sense to me. However coupling the Provider of Currency to the Money object I think would be beneficial, which means there should be an easy way to override the default. As Money::of is the general way of doing this, and there's no state to the Money object (agree there too). I think you're right in that a Factory would be the way to go, but would need a way to create a Money object that uses a different provider without maintaining state of that provider.

Any suggestions as to how such a factory might work? If Money::of doesn't take the provider, but its the way to generate a new object, how does one switch the Provider out?

For my project, i have done the following, any alternative to this?:

function factoryFunc($amount, string $currency, $context, $roundingMode) {
    // getCurrencyFromCode fetches `new Currency` from a Collection of a few different CurrencyProviders
    $currency = $this->getCurrencyFromCode($currency);

    return Money::of($amount, $currency, $context, $roundingMode);
}

@puzzledmonkey
Copy link

puzzledmonkey commented Feb 10, 2023

Hi! Nice library, thanks.

However, version 0.8.0 completely removes HRK from the ISO currencies. While this is correct, we have legacy data in Croatian Kuna, and we use Laravel Nova which interfaces directly to Money::of or Money::ofMinor and does not allow us to hook into this and provide a custom new Currency(...) easily.

Is it possible to implement an extension to ISOCurrencyProvider such as addCurrency(new Currency(...)); which adds the new currency to $currencyData for the singleton? This would allow us (or anyone else) to add currencies at boot time and not have to hook deeper into the system.

Thanks for considering!

@BenMorel
Copy link
Member

@puzzledmonkey I'm generally against adding any kind of global state configuration, as it may have side effects if several parts of your application use brick/money.

What exactly prevents Laravel Nova from using a factory to create Money instances?

@puzzledmonkey
Copy link

Well I can't modify their code, so for now I've just made a small field class that extends their Currency field and overrides the method that uses Money::of.

I understand you're against any kind of global state configuration, but isn't that kind of what the ISOCurrentProvider singleton's currencyData provides? Of course it's up to you, but I just figured it would help people in our case where a legacy currency has been removed but needs supporting for the forseeable future too.

@puzzledmonkey
Copy link

Note: for now I just overrode the Nova Currency field method and add the custom currency in as necessary. However I'm not sure this is the best method either because I'm creating a new Currency object for each call to the field. A global setting would only need to instantiate it once.

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

No branches or pull requests

3 participants