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

Change currency rate on the fly #9

Open
dalholm opened this issue Dec 30, 2021 · 3 comments
Open

Change currency rate on the fly #9

dalholm opened this issue Dec 30, 2021 · 3 comments
Labels
enhancement New feature or request

Comments

@dalholm
Copy link
Contributor

dalholm commented Dec 30, 2021

Before I start something unnecessary, I thought I would check if there is a good way to update an exchange rate on the fly?

Use case
You have an order with a specific exchange rate. A couple of days later, the course has changed and you want to present what they paid.

Note, In my system, all prices are saved in a base currency.

An idea would be something similar

currency()->updateRate(1.0);
@dalholm
Copy link
Contributor Author

dalholm commented Dec 30, 2021

Of course there was a smarter solution for this! :)

$newRate = 4.0
$money = money(100)->convertTo(
  new \ArchTech\Money\Currency('EUR', 'Euro', $newRate, '', 'EUR')
);

// $money->value(); // should now be 400

@dalholm dalholm closed this as completed Dec 30, 2021
@stancl
Copy link
Member

stancl commented Dec 30, 2021

A couple of days later, the course has changed and you want to present what they paid.

In this case the order should store the exchange rate that was used at the time of purchase.

I see your point about changing the currency rate to format the value correctly. Hmm. Right now the package expects Money to be created with a currency code, and the actual currency is stored in the CurrencyManager.

Updating the rate for the entire currency would be wrong here, because you could have e.g. a navbar with the cart total, and you only want to change how some value is rendered on a specific part of the page (like a "show order" table).

The code you just posted seems to be a good solution. I checked the Currency class and it doesn't register the currency into CurrencyManager automatically, so it won't override the global EUR value.

But perhaps we could add something like:

money(100)->convertTo(EUR::class, rate: $newRate);

As in, the ability to specify overrides after the currency code. I'll re-open this issue to consider that in the future.

I'd also advise storing the value that the user actually paid, and converting that to the base currency if needed. There probably isn't a difference when you handle the math well, but it seems like a better practice to store what the user actually paid rather than having to compute it from some other value.

@stancl stancl reopened this Dec 30, 2021
@stancl stancl added the enhancement New feature or request label Dec 30, 2021
@dalholm
Copy link
Contributor Author

dalholm commented Dec 30, 2021

The code you just posted seems to be a good solution. I checked the Currency class and it doesn't register the currency into CurrencyManager automatically, so it won't override the global EUR value.

But perhaps we could add something like:

money(100)->convertTo(EUR::class, rate: $newRate);

That solution would be really nice, no need for duplication then. :)

As in, the ability to specify overrides after the currency code. I'll re-open this issue to consider that in the future.

I'd also advise storing the value that the user actually paid, and converting that to the base currency if needed. There probably isn't a difference when you handle the math well, but it seems like a better practice to store what the user actually paid rather than having to compute it from some other value.

I save the current rate of what the customer paid. In my case i store everything in SEK with a currency rate. Its easier to maintain and report statistics on.

To make this possible i use cast for returning a DataType class with this money package and some custom functions.
e.g:

// your model

protected $casts = ['price' => MoneyCast::class]; // Returns a DataType with logical stuff in it
// Usage
$item->price->value; // Original value, i do all the calculations on
$item->price->currencyValue; // Calculated currency value (used for payments etc)
$item->price->formatted; // Formatted in selected currency or related currency and rate
// and more

dalholm added a commit to dalholm/money that referenced this issue Dec 30, 2021
@gauravmak gauravmak mentioned this issue Mar 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants