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

feat: support float amount values, and fix debts and gifts amount forms #3906

Merged
merged 31 commits into from
May 20, 2020
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a6ab0bb
Stores amount as integer-ish values, and fix debts and gifts amount f…
asbiin Apr 25, 2020
a936f21
Apply fixes from StyleCI
asbiin Apr 25, 2020
704ebd4
Merge remote-tracking branch 'origin/master' into 2020-04-25-stores-a…
asbiin Apr 25, 2020
391a22a
chore(assets): Update assets
MonicaBot Apr 25, 2020
fb20b57
Merge remote-tracking branch 'origin/master' into 2020-04-25-stores-a…
asbiin Apr 25, 2020
555d1bb
fixes
asbiin Apr 26, 2020
7a90bd5
Apply fixes from StyleCI
asbiin Apr 26, 2020
c4faee6
fix tests
asbiin Apr 26, 2020
32b693c
Merge remote-tracking branch 'origin/master' into 2020-04-25-stores-a…
asbiin Apr 26, 2020
a1d9a4e
fix oauth test
asbiin Apr 29, 2020
76f3045
Merge remote-tracking branch 'origin/master' into 2020-04-25-stores-a…
asbiin Apr 29, 2020
c589c8a
chore(assets): Update assets
MonicaBot Apr 29, 2020
d76ff0a
fix url
asbiin Apr 29, 2020
3687712
Merge branch '2020-04-25-stores-amount-integer' of github.com:monicah…
asbiin Apr 29, 2020
f16b882
Merge remote-tracking branch 'origin/master' into 2020-04-25-stores-a…
asbiin May 10, 2020
62a385a
Merge remote-tracking branch 'origin/master' into 2020-04-25-stores-a…
asbiin May 14, 2020
9a79a7f
fix
asbiin May 14, 2020
1d679af
chore(assets): Update assets
MonicaBot May 14, 2020
daad18e
Merge remote-tracking branch 'origin/master' into 2020-04-25-stores-a…
asbiin May 18, 2020
5323b7a
fix
asbiin May 18, 2020
bbd064b
Apply fixes from StyleCI
asbiin May 18, 2020
c9e1b77
More tests
asbiin May 18, 2020
77416bb
move function
asbiin May 18, 2020
867582a
Apply fixes from StyleCI
asbiin May 18, 2020
40cc2f5
fix psalm
asbiin May 19, 2020
56925dd
Merge branch '2020-04-25-stores-amount-integer' of github.com:monicah…
asbiin May 19, 2020
9ff743d
Rename functions
asbiin May 19, 2020
a416782
fixes
asbiin May 19, 2020
c8dcfbd
Merge branch 'master' into 2020-04-25-stores-amount-integer
asbiin May 19, 2020
f645a05
Merge branch 'master' into 2020-04-25-stores-amount-integer
asbiin May 19, 2020
4eabcb4
Merge remote-tracking branch 'origin/master' into 2020-04-25-stores-a…
asbiin May 20, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

### Enhancements:

* Stores amount as integer-ish values, and fix debts and gifts amount forms
* Use queue to send email verification
* Improve autocomplete fields on signup and login forms
* Add cache for S3 storage, and use new standard variables
Expand Down
2 changes: 1 addition & 1 deletion app/Helpers/InstanceHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static function getPlanInformationFromConfig(string $timePeriod): ?array
}

$currency = Currency::where('iso', strtoupper(config('cashier.currency')))->first();
$amount = MoneyHelper::format(config('monica.paid_plan_'.$timePeriod.'_price') / 100, $currency);
$amount = MoneyHelper::format(config('monica.paid_plan_'.$timePeriod.'_price'), $currency);

return [
'type' => $timePeriod,
Expand Down
141 changes: 129 additions & 12 deletions app/Helpers/MoneyHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,33 @@
use Money\Currencies\ISOCurrencies;
use Illuminate\Support\Facades\Auth;
use Money\Currency as MoneyCurrency;
use Money\Parser\DecimalMoneyParser;
use Money\Formatter\IntlMoneyFormatter;
use Money\Formatter\DecimalMoneyFormatter;

class MoneyHelper
{
/**
* Format a monetary amount with currency symbol.
*
* Amount must be an integer, in exchange format.
* i.e. '100' for 1,00€
*
* If the currency parameter is not passed, then the currency specified in
* the users's settings will be used. If the currency setting is not
* defined, then the amount will be returned without a currency symbol.
*
* @param int|null $amount Amount to format.
* @param Currency $currency Currency of amount.
* @return string Amount formatted with currency symbol.
* @param int|null $amount Amount to format.
* @param Currency|int|null $currency Currency of amount.
* @return string Amount formatted with currency symbol.
*/
public static function format($amount, Currency $currency = null)
public static function format($amount, $currency = null): string
{
if (is_null($amount)) {
$amount = 0;
}

if (! $currency && Auth::check()) {
$currency = Auth::user()->currency;
}
$currency = self::getCurrency($currency);

if (! $currency) {
$numberFormatter = new \NumberFormatter(App::getLocale(), \NumberFormatter::DECIMAL);
Expand All @@ -40,14 +43,128 @@ public static function format($amount, Currency $currency = null)
}

$moneyCurrency = new MoneyCurrency($currency->iso);
$currencies = new ISOCurrencies();
$minorUnitAdjustment = pow(10, $currencies->subunitFor($moneyCurrency));
$money = new Money($amount, $moneyCurrency);
$numberFormatter = new \NumberFormatter(App::getLocale(), \NumberFormatter::CURRENCY);
$moneyFormatter = new IntlMoneyFormatter($numberFormatter, new ISOCurrencies());

$money = new Money($amount * $minorUnitAdjustment, $moneyCurrency);
return $moneyFormatter->format($money);
}

$numberFormatter = new \NumberFormatter(App::getLocale(), \NumberFormatter::CURRENCY);
$moneyFormatter = new IntlMoneyFormatter($numberFormatter, $currencies);
/**
* Format a monetary amount (without the currency).
*
* Amount must be an integer, in exchange format.
* i.e. '100' for 1,00€
*
* @param int|null $amount
* @param Currency|int|null $currency
* @return string
*/
public static function formatValue($amount, $currency = null): string
{
$currency = self::getCurrency($currency);

if (! $currency) {
return (string) ($amount / 100);
}

$moneyCurrency = new MoneyCurrency($currency->iso);
$money = new Money($amount ?? 0, $moneyCurrency);
$numberFormatter = new \NumberFormatter(App::getLocale(), \NumberFormatter::PATTERN_DECIMAL);
$moneyFormatter = new IntlMoneyFormatter($numberFormatter, new ISOCurrencies());

return $moneyFormatter->format($money);
}

/**
* Format a monetary amount in exchange value with currency symbol.
*
* @param float|null $exchange
* @param Currency|int|null $currency
* @return string
*/
public static function display($exchange, $currency = null): string
{
$currency = self::getCurrency($currency);

return self::format(self::formatInput($exchange, $currency), $currency);
}

/**
* Format a monetary exchange value as storable integer.
*
* @param mixed|null $exchange
* @param Currency|int|null $currency
* @return int
*/
public static function formatInput($exchange, $currency): int
{
$currency = self::getCurrency($currency);

if (! $currency) {
return (int) ((float) $exchange * 100);
}

$moneyParser = new DecimalMoneyParser(new ISOCurrencies());
$money = $moneyParser->parse((string) $exchange, $currency->iso);

return (int) $money->getAmount();
}

/**
* Format a monetary value as exchange value.
*
* @param int|null $amount
* @param Currency|int|null $currency
* @return float
*/
public static function exchangeValue($amount, $currency): float
{
$currency = self::getCurrency($currency);

$moneyCurrency = new MoneyCurrency($currency->iso);
$money = new Money($amount ?? 0, $moneyCurrency);
$moneyFormatter = new DecimalMoneyFormatter(new ISOCurrencies());

return (float) $moneyFormatter->format($money);
}

/**
* Get unit adjustement value for the currency.
*
* @param Currency|int|null $currency
* @return int
*/
public static function unitAdjustment($currency): int
{
$currency = self::getCurrency($currency);

if (! $currency) {
return 100;
}

$moneyCurrency = new MoneyCurrency($currency->iso);
$currencies = new ISOCurrencies();

return (int) pow(10, $currencies->subunitFor($moneyCurrency));
}

/**
* Get currency object.
*
* @param Currency|int|null $currency
* @return Currency|null
*/
private static function getCurrency($currency): ?Currency
{
if (is_int($currency)) {
$currency = Currency::find($currency);
}

if (! $currency && Auth::check()) {
$currency = Auth::user()->currency;
}

return $currency;
}
}
4 changes: 2 additions & 2 deletions app/Http/Resources/Debt/Debt.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace App\Http\Resources\Debt;

use App\Helpers\DateHelper;
use App\Helpers\MoneyHelper;
use Illuminate\Http\Resources\Json\JsonResource;
use App\Http\Resources\Contact\ContactShort as ContactShortResource;

Expand All @@ -26,7 +25,8 @@ public function toArray($request)
'in_debt' => $this->in_debt,
'status' => $this->status,
'amount' => $this->amount,
'amount_with_currency' => MoneyHelper::format((int) $this->amount),
'value' => $this->value,
'amount_with_currency' => $this->displayValue,
'reason' => $this->reason,
'account' => [
'id' => $this->account_id,
Expand Down
5 changes: 3 additions & 2 deletions app/Http/Resources/Gift/Gift.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ public function toArray($request)
'name' => $this->name,
'comment' => $this->comment,
'url' => $this->url,
'amount' => $this->value,
'amount_with_currency' => $this->amount,
'amount' => $this->amount,
'value' => $this->value,
'amount_with_currency' => $this->displayValue,
'status' => $this->status,
'date' => DateHelper::getDate($this->date),
'recipient' => new ContactShortResource($this->recipient),
Expand Down
15 changes: 11 additions & 4 deletions app/Models/Contact/Contact.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use App\Models\Instance\SpecialDate;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use IlluminateAgnostic\Arr\Support\Arr;
use App\Models\Account\ActivityStatistic;
use App\Models\Relationship\Relationship;
use Illuminate\Database\Eloquent\Builder;
Expand Down Expand Up @@ -1069,6 +1070,7 @@ public function getTagsAsString()

/**
* Is this contact owed money?
*
* @return bool
*/
public function isOwedMoney()
Expand All @@ -1079,16 +1081,21 @@ public function isOwedMoney()
/**
* How much is the debt.
*
* @return int
* @return int amount in storage value
*/
public function totalOutstandingDebtAmount()
public function totalOutstandingDebtAmount(): int
{
return $this
->debts()
->where('status', '=', 'inprogress')
->inProgress()
->getResults()
->filter(function ($d) {
return Arr::has($d->attributes, 'amount');
})
->sum(function ($d) {
return $d->in_debt === 'yes' ? -$d->amount : $d->amount;
$amount = $d->attributes['amount'];

return $d->in_debt === 'yes' ? -$amount : $amount;
});
}

Expand Down
8 changes: 8 additions & 0 deletions app/Models/Contact/Debt.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
namespace App\Models\Contact;

use App\Models\Account\Account;
use App\Traits\AmountFormatter;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use App\Models\ModelBindingHasherWithContact as Model;

/**
Expand All @@ -16,6 +18,8 @@
*/
class Debt extends Model
{
use AmountFormatter;

/**
* The attributes that aren't mass assignable.
*
Expand All @@ -33,6 +37,8 @@ class Debt extends Model

/**
* Get the account record associated with the debt.
*
* @return BelongsTo
*/
public function account()
{
Expand All @@ -41,6 +47,8 @@ public function account()

/**
* Get the contact record associated with the debt.
*
* @return BelongsTo
*/
public function contact()
{
Expand Down
15 changes: 3 additions & 12 deletions app/Models/Contact/Gift.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace App\Models\Contact;

use App\Helpers\MoneyHelper;
use App\Models\Account\Photo;
use App\Models\Account\Account;
use App\Traits\AmountFormatter;
use Illuminate\Database\Eloquent\Builder;
use App\Models\ModelBindingWithContact as Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
Expand All @@ -19,12 +19,13 @@
* @property string $comment
* @property string $url
* @property Contact $is_for
* @property int $value
* @method static Builder offered()
* @method static Builder isIdea()
*/
class Gift extends Model
{
use AmountFormatter;

/**
* The attributes that aren't mass assignable.
*
Expand Down Expand Up @@ -150,14 +151,4 @@ public function getRecipientNameAttribute(): ?string

return null;
}

/**
* Get amount with currency.
*
* @return string
*/
public function getAmountAttribute(): string
{
return $this->value ? MoneyHelper::format($this->value) : '';
}
}
4 changes: 3 additions & 1 deletion app/Services/Account/Settings/ExportAccount.php
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ private function exportDebt(array $data)
'in_debt',
'status',
'amount',
'currency_id',
'reason',
'created_at',
'updated_at',
Expand Down Expand Up @@ -675,7 +676,8 @@ private function exportGift(array $data)
'name',
'comment',
'url',
'value',
'amount',
'currency_id',
'status',
'date',
'created_at',
Expand Down
7 changes: 6 additions & 1 deletion app/Services/Contact/Gift/CreateGift.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use App\Services\BaseService;
use App\Models\Contact\Contact;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;

class CreateGift extends BaseService
{
Expand Down Expand Up @@ -61,11 +62,15 @@ public function execute(array $data): Gift
'status' => $data['status'],
'comment' => $this->nullOrvalue($data, 'comment'),
'url' => $this->nullOrvalue($data, 'url'),
'value' => $this->nullOrvalue($data, 'amount'),
'amount' => $this->nullOrvalue($data, 'amount'),
'date' => $this->nullOrvalue($data, 'date'),
'recipient' => $this->nullOrvalue($data, 'recipient_id'),
];

if (Auth::check()) {
$array['currency_id'] = Auth::user()->currency->id;
}

return Gift::create($array);
}
}
Loading