feat: support float amount values, and fix debts and gifts amount forms (#3906)
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
### Enhancements:
|
||||
|
||||
* Stores amount as integer-ish values, and fix debts and gifts amount forms
|
||||
* Use current text from search bar to create a new person
|
||||
* Always allow to add a new person from search bar
|
||||
* Use queue to send email verification
|
||||
|
||||
@@ -34,7 +34,7 @@ class InstanceHelper
|
||||
}
|
||||
|
||||
$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,
|
||||
|
||||
+95
-13
@@ -8,30 +8,31 @@ use Illuminate\Support\Facades\App;
|
||||
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.
|
||||
* The value is formatted using current langage, as per the currency symbol.
|
||||
*
|
||||
* 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 value in storable format (ex: 100 for 1,00€).
|
||||
* @param Currency|int|null $currency Currency of amount.
|
||||
* @return string Formatted amount for display with currency symbol (ex '1,235.87 €').
|
||||
*/
|
||||
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);
|
||||
@@ -40,14 +41,95 @@ class MoneyHelper
|
||||
}
|
||||
|
||||
$moneyCurrency = new MoneyCurrency($currency->iso);
|
||||
$currencies = new ISOCurrencies();
|
||||
$minorUnitAdjustment = pow(10, $currencies->subunitFor($moneyCurrency));
|
||||
|
||||
$money = new Money($amount * $minorUnitAdjustment, $moneyCurrency);
|
||||
|
||||
$money = new Money($amount, $moneyCurrency);
|
||||
$numberFormatter = new \NumberFormatter(App::getLocale(), \NumberFormatter::CURRENCY);
|
||||
$moneyFormatter = new IntlMoneyFormatter($numberFormatter, $currencies);
|
||||
$moneyFormatter = new IntlMoneyFormatter($numberFormatter, new ISOCurrencies());
|
||||
|
||||
return $moneyFormatter->format($money);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a monetary amount, without the currency.
|
||||
* The value is formatted using current langage.
|
||||
*
|
||||
* @param int|null $amount Amount value in storable format (ex: 100 for 1,00€).
|
||||
* @param Currency|int|null $currency
|
||||
* @return string Formatted amount for display without currency symbol (ex: '1234.50').
|
||||
*/
|
||||
public static function getValue($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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a monetary exchange value as storable integer.
|
||||
* Currency is used to know the precision of this currency.
|
||||
*
|
||||
* @param mixed|null $exchange Amount value in exchange format (ex: 1.00).
|
||||
* @param Currency|int|null $currency
|
||||
* @return int Amount as storable format (ex: 14500).
|
||||
*/
|
||||
public static function parseInput($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.
|
||||
* Exchange value is the amount to be entered in an input by a user,
|
||||
* using ordinary format.
|
||||
*
|
||||
* @param int|null $amount Amount value in storable format (ex: 100 for 1,00€).
|
||||
* @param Currency|int|null $currency
|
||||
* @return string Real value of amount in exchange format (ex: 1.24).
|
||||
*/
|
||||
public static function exchangeValue($amount, $currency): string
|
||||
{
|
||||
$currency = self::getCurrency($currency);
|
||||
|
||||
$moneyCurrency = new MoneyCurrency($currency->iso);
|
||||
$money = new Money($amount ?? 0, $moneyCurrency);
|
||||
$moneyFormatter = new DecimalMoneyFormatter(new ISOCurrencies());
|
||||
|
||||
return $moneyFormatter->format($money);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get currency object.
|
||||
*
|
||||
* @param Currency|int|null $currency
|
||||
* @return Currency|null
|
||||
*/
|
||||
public static function getCurrency($currency): ?Currency
|
||||
{
|
||||
if (is_int($currency)) {
|
||||
$currency = Currency::find($currency);
|
||||
}
|
||||
|
||||
if (! $currency && Auth::check()) {
|
||||
$currency = Auth::user()->currency;
|
||||
}
|
||||
|
||||
return $currency;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -26,7 +25,8 @@ class Debt extends JsonResource
|
||||
'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,
|
||||
|
||||
@@ -26,8 +26,9 @@ class Gift extends JsonResource
|
||||
'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),
|
||||
|
||||
@@ -21,6 +21,7 @@ use Illuminate\Support\Collection;
|
||||
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;
|
||||
@@ -1069,6 +1070,7 @@ class Contact extends Model
|
||||
|
||||
/**
|
||||
* Is this contact owed money?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOwedMoney()
|
||||
@@ -1079,16 +1081,21 @@ class Contact extends Model
|
||||
/**
|
||||
* 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;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
@@ -16,6 +18,8 @@ use App\Models\ModelBindingHasherWithContact as Model;
|
||||
*/
|
||||
class Debt extends Model
|
||||
{
|
||||
use AmountFormatter;
|
||||
|
||||
/**
|
||||
* The attributes that aren't mass assignable.
|
||||
*
|
||||
@@ -33,6 +37,8 @@ class Debt extends Model
|
||||
|
||||
/**
|
||||
* Get the account record associated with the debt.
|
||||
*
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function account()
|
||||
{
|
||||
@@ -41,6 +47,8 @@ class Debt extends Model
|
||||
|
||||
/**
|
||||
* Get the contact record associated with the debt.
|
||||
*
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function contact()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
@@ -19,12 +19,13 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
* @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.
|
||||
*
|
||||
@@ -150,14 +151,4 @@ class Gift extends Model
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get amount with currency.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAmountAttribute(): string
|
||||
{
|
||||
return $this->value ? MoneyHelper::format($this->value) : '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,6 +562,7 @@ SET FOREIGN_KEY_CHECKS=0;
|
||||
'in_debt',
|
||||
'status',
|
||||
'amount',
|
||||
'currency_id',
|
||||
'reason',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
@@ -675,7 +676,8 @@ SET FOREIGN_KEY_CHECKS=0;
|
||||
'name',
|
||||
'comment',
|
||||
'url',
|
||||
'value',
|
||||
'amount',
|
||||
'currency_id',
|
||||
'status',
|
||||
'date',
|
||||
'created_at',
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Models\Contact\Gift;
|
||||
use App\Services\BaseService;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CreateGift extends BaseService
|
||||
{
|
||||
@@ -61,11 +62,15 @@ class CreateGift extends BaseService
|
||||
'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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Models\Contact\Gift;
|
||||
use App\Services\BaseService;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class UpdateGift extends BaseService
|
||||
{
|
||||
@@ -64,11 +65,15 @@ class UpdateGift extends BaseService
|
||||
'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 tap($gift)
|
||||
->update($array);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use App\Helpers\MoneyHelper;
|
||||
use App\Models\Settings\Currency;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
trait AmountFormatter
|
||||
{
|
||||
/**
|
||||
* Get the currency record associated with the debt.
|
||||
*
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function currency()
|
||||
{
|
||||
return $this->belongsTo(Currency::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set exchange value.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAmountAttribute($value)
|
||||
{
|
||||
$this->attributes['amount'] = MoneyHelper::parseInput($value, $this->currency);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get exchange value.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAmountAttribute(): ?string
|
||||
{
|
||||
if (! ($amount = Arr::get($this->attributes, 'amount', null))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return MoneyHelper::exchangeValue($amount, $this->currency);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value of amount (without currency).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValueAttribute(): string
|
||||
{
|
||||
if (! ($amount = Arr::get($this->attributes, 'amount', null))) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return MoneyHelper::getValue($amount, $this->currency);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get display value: amount with currency.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDisplayValueAttribute(): string
|
||||
{
|
||||
if (! ($amount = Arr::get($this->attributes, 'amount', null))) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return MoneyHelper::format($amount, $this->currency);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,11 @@ $factory->define(App\Models\User\User::class, function (Faker\Generator $faker)
|
||||
'timezone' => config('app.timezone'),
|
||||
'name_order' => 'firstname_lastname',
|
||||
'locale' => 'en',
|
||||
'currency_id' => function (array $data) {
|
||||
return factory(App\Models\Settings\Currency::class)->create([
|
||||
'iso' => 'USD',
|
||||
])->id;
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
use App\Helpers\MoneyHelper;
|
||||
use App\Models\Contact\Debt;
|
||||
use App\Models\Contact\Gift;
|
||||
use Money\Currencies\ISOCurrencies;
|
||||
use Money\Currency as MoneyCurrency;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
|
||||
class UpdateAmountFormat extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$this->fixDebts();
|
||||
$this->fixGifts();
|
||||
}
|
||||
|
||||
private function fixDebts()
|
||||
{
|
||||
Schema::table('debts', function (Blueprint $table) {
|
||||
$table->decimal('amount', 13, 2)->change();
|
||||
$table->unsignedInteger('currency_id')->after('amount')->nullable();
|
||||
$table->foreign('currency_id')->references('id')->on('currencies')->onDelete('set null');
|
||||
});
|
||||
|
||||
Debt::chunk(500, function ($debts) {
|
||||
foreach ($debts as $debt) {
|
||||
try {
|
||||
$user = $debt->account->users()->firstOrFail();
|
||||
} catch (ModelNotFoundException $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$debt->update([
|
||||
'amount' => $debt->amount * self::unitAdjustment($user->currency),
|
||||
'currency_id' => $user->currency_id,
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
Schema::table('debts', function (Blueprint $table) {
|
||||
$table->integer('amount')->change();
|
||||
});
|
||||
}
|
||||
|
||||
private function fixGifts()
|
||||
{
|
||||
Schema::table('gifts', function (Blueprint $table) {
|
||||
$table->unsignedInteger('currency_id')->after('value')->nullable();
|
||||
$table->foreign('currency_id')->references('id')->on('currencies')->onDelete('set null');
|
||||
});
|
||||
|
||||
Gift::where('value', '!=', 'null')->chunk(500, function ($gifts) {
|
||||
foreach ($gifts as $gift) {
|
||||
try {
|
||||
$user = $gift->account->users()->firstOrFail();
|
||||
} catch (ModelNotFoundException $e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$gift->update([
|
||||
'value' => $gift->value * self::unitAdjustment($user->currency),
|
||||
'currency_id' => $user->currency_id,
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
Schema::table('gifts', function (Blueprint $table) {
|
||||
$table->integer('value')->change()->nullable();
|
||||
$table->renameColumn('value', 'amount');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unit adjustement value for the currency.
|
||||
*
|
||||
* @param \App\Models\Settings\Currency|int|null $currency
|
||||
* @return int
|
||||
*/
|
||||
private static function unitAdjustment($currency): int
|
||||
{
|
||||
$currency = MoneyHelper::getCurrency($currency);
|
||||
|
||||
if (! $currency) {
|
||||
return 100;
|
||||
}
|
||||
|
||||
$moneyCurrency = new MoneyCurrency($currency->iso);
|
||||
$currencies = new ISOCurrencies();
|
||||
|
||||
return (int) pow(10, $currencies->subunitFor($moneyCurrency));
|
||||
}
|
||||
}
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* WebAuthn client.
|
||||
*
|
||||
* This file is part of asbiin/laravel-webauthn project.
|
||||
*
|
||||
* @copyright Alexis SAETTLER © 2019
|
||||
* @license MIT
|
||||
*/
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,144 @@
|
||||
/*!
|
||||
* Bootstrap button.js v4.4.1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Bootstrap collapse.js v4.4.1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Bootstrap dropdown.js v4.4.1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Bootstrap modal.js v4.4.1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Bootstrap tab.js v4.4.1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Bootstrap util.js v4.4.1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Sizzle CSS Selector Engine v2.3.5
|
||||
* https://sizzlejs.com/
|
||||
*
|
||||
* Copyright JS Foundation and other contributors
|
||||
* Released under the MIT license
|
||||
* https://js.foundation/
|
||||
*
|
||||
* Date: 2020-03-14
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Vue.js v2.6.11
|
||||
* (c) 2014-2019 Evan You
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* clipboard.js v2.0.6
|
||||
* https://clipboardjs.com/
|
||||
*
|
||||
* Licensed MIT © Zeno Rocha
|
||||
*/
|
||||
|
||||
/*!
|
||||
* jQuery JavaScript Library v3.5.0
|
||||
* https://jquery.com/
|
||||
*
|
||||
* Includes Sizzle.js
|
||||
* https://sizzlejs.com/
|
||||
*
|
||||
* Copyright JS Foundation and other contributors
|
||||
* Released under the MIT license
|
||||
* https://jquery.org/license
|
||||
*
|
||||
* Date: 2020-04-10T15:07Z
|
||||
*/
|
||||
|
||||
/*!
|
||||
* pretty-checkbox-vue v1.1.9
|
||||
* (c) 2017-2018 Hamed Ehtesham
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* vuejs-datepicker v2.0.2
|
||||
* (c) 2016-2019 Charlie Kassel
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Lodash <https://lodash.com/>
|
||||
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
||||
* Released under MIT license <https://lodash.com/license>
|
||||
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
||||
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||||
*/
|
||||
|
||||
/**!
|
||||
* @fileOverview Kickass library to create and place poppers near their reference elements.
|
||||
* @version 1.15.0
|
||||
* @license
|
||||
* Copyright (c) 2016 Federico Zivolo and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**!
|
||||
* @fileOverview Kickass library to create and place poppers near their reference elements.
|
||||
* @version 1.16.1
|
||||
* @license
|
||||
* Copyright (c) 2016 Federico Zivolo and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"/js/manifest.js": "/js/manifest.js?id=7db827d654313dce4250",
|
||||
"/js/vendor.js": "/js/vendor.js?id=25fadde867975f46f933",
|
||||
"/js/app.js": "/js/app.js?id=d5d979c96be86abeeb02",
|
||||
"/js/vendor.js": "/js/vendor.js?id=7ba2ee2218000e985a38",
|
||||
"/js/app.js": "/js/app.js?id=c50cecc66672829774a7",
|
||||
"/css/app-ltr.css": "/css/app-ltr.css?id=50a29d9a682008ec4075",
|
||||
"/css/app-rtl.css": "/css/app-rtl.css?id=54b5c63f9b15fa4d13c0",
|
||||
"/css/stripe.css": "/css/stripe.css?id=76c70a7b11ae5f38a725",
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
:style="inputStyle"
|
||||
:value="value"
|
||||
:maxlength="maxlength"
|
||||
:step="step"
|
||||
@input="onInput($event)"
|
||||
@blur="onBlur($event)"
|
||||
@change="onChange($event)"
|
||||
@@ -81,6 +82,10 @@ export default {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
step: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: -1,
|
||||
|
||||
@@ -118,6 +118,7 @@
|
||||
:class="'dtc pr2'"
|
||||
:title="$t('people.gifts_add_value')"
|
||||
:required="displayAmount"
|
||||
step=".01"
|
||||
@submit="store"
|
||||
/>
|
||||
</div>
|
||||
@@ -330,7 +331,7 @@ export default {
|
||||
}
|
||||
this.displayComment = this.gift ? this.gift.comment : false;
|
||||
this.displayUrl = this.gift ? this.gift.url : false;
|
||||
this.displayAmount = this.gift ? this.gift.amount : false;
|
||||
this.displayAmount = this.gift ? this.gift.amount != '' : false;
|
||||
this.displayRecipient = this.gift ? (this.gift.recipient ? this.gift.recipient.id !== 0 : false) : false;
|
||||
this.displayUpload= this.gift ? this.gift.photos.length > 0 : false;
|
||||
|
||||
@@ -363,6 +364,7 @@ export default {
|
||||
return vm.storePhoto(response);
|
||||
})
|
||||
.then(response => {
|
||||
//this.update(response);
|
||||
vm.close();
|
||||
vm.$emit('update', response.data.data);
|
||||
return response;
|
||||
@@ -380,6 +382,21 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
update() {
|
||||
this.newGift.contact_id = this.contactId;
|
||||
if (this.newGift) {
|
||||
this.gift.contact_id = this.newGift.contact.id;
|
||||
this.gift.name = this.newGift.name;
|
||||
this.gift.comment = this.newGift.comment;
|
||||
this.gift.url = this.newGift.url;
|
||||
this.gift.amount = this.newGift.amount;
|
||||
this.gift.status = this.newGift.status;
|
||||
this.gift.recipient_id = this.newGift.recipient ? this.newGift.recipient.id : null;
|
||||
this.hasRecipient = this.gift.recipient_id != null;
|
||||
this.gift.date = this.newGift.date;
|
||||
}
|
||||
},
|
||||
|
||||
storePhoto(response) {
|
||||
let vm = this;
|
||||
return this.$refs.upload.forceFileUpload()
|
||||
|
||||
@@ -242,6 +242,7 @@ export default {
|
||||
this.$set(gift, 'comment', response.comment);
|
||||
this.$set(gift, 'url', response.url);
|
||||
this.$set(gift, 'amount', response.amount);
|
||||
this.$set(gift, 'amount_with_currency', response.amount_with_currency);
|
||||
this.$set(gift, 'status', response.status);
|
||||
this.$set(gift, 'recipient', response.recipient);
|
||||
this.$set(gift, 'date', response.date);
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
<div class="table-cell debt-nature">
|
||||
@if ($debt->in_debt == 'yes')
|
||||
{{ trans('people.debt_you_owe', [
|
||||
'amount' => App\Helpers\MoneyHelper::format($debt->amount)
|
||||
'amount' => $debt->displayValue
|
||||
]) }}
|
||||
@else
|
||||
{{ trans('people.debt_they_owe', [
|
||||
'name' => $contact->first_name,
|
||||
'amount' => App\Helpers\MoneyHelper::format($debt->amount)
|
||||
'amount' => $debt->displayValue
|
||||
]) }}
|
||||
@endif
|
||||
</div>
|
||||
@@ -67,11 +67,11 @@
|
||||
@if ($contact->isOwedMoney())
|
||||
{{ trans('people.debt_they_owe', [
|
||||
'name' => $contact->first_name,
|
||||
'amount' => App\Helpers\MoneyHelper::format($contact->totalOutstandingDebtAmount())
|
||||
'amount' => App\Helpers\MoneyHelper::format($contact->totalOutstandingDebtAmount(), Auth::user()->currency)
|
||||
]) }}
|
||||
@else
|
||||
{{ trans('people.debt_you_owe', [
|
||||
'amount' => App\Helpers\MoneyHelper::format(-$contact->totalOutstandingDebtAmount())
|
||||
'amount' => App\Helpers\MoneyHelper::format(-$contact->totalOutstandingDebtAmount(), Auth::user()->currency)
|
||||
]) }}
|
||||
@endif
|
||||
</strong>
|
||||
|
||||
@@ -157,6 +157,7 @@ class ApiDebtsTest extends ApiTestCase
|
||||
public function it_creates_a_debt()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$user->locale = 'fr';
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
@@ -185,8 +186,9 @@ class ApiDebtsTest extends ApiTestCase
|
||||
'id' => $debt_id,
|
||||
'in_debt' => 'yes',
|
||||
'status' => 'inprogress',
|
||||
'amount' => 42,
|
||||
'amount_with_currency' => '$42.00',
|
||||
'amount' => '42.00',
|
||||
'value' => '42,00',
|
||||
'amount_with_currency' => '42,00'.chr(0xA0).'$US',
|
||||
'reason' => 'that\'s why',
|
||||
]);
|
||||
|
||||
@@ -197,7 +199,7 @@ class ApiDebtsTest extends ApiTestCase
|
||||
'id' => $debt_id,
|
||||
'in_debt' => 'yes',
|
||||
'status' => 'inprogress',
|
||||
'amount' => 42,
|
||||
'amount' => 4200,
|
||||
'reason' => 'that\'s why',
|
||||
]);
|
||||
}
|
||||
@@ -246,6 +248,7 @@ class ApiDebtsTest extends ApiTestCase
|
||||
public function it_updates_a_debt()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$user->locale = 'fr';
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
@@ -258,7 +261,7 @@ class ApiDebtsTest extends ApiTestCase
|
||||
'contact_id' => $contact->id,
|
||||
'in_debt' => 'yes',
|
||||
'status' => 'completed',
|
||||
'amount' => 142,
|
||||
'amount' => 142.01,
|
||||
'reason' => 'voilà',
|
||||
]);
|
||||
|
||||
@@ -273,7 +276,9 @@ class ApiDebtsTest extends ApiTestCase
|
||||
'id' => $debt_id,
|
||||
'in_debt' => 'yes',
|
||||
'status' => 'completed',
|
||||
'amount' => 142,
|
||||
'amount' => '142.01',
|
||||
'value' => '142,01',
|
||||
'amount_with_currency' => '142,01'.chr(0xA0).'$US',
|
||||
'reason' => 'voilà',
|
||||
]);
|
||||
|
||||
@@ -284,7 +289,7 @@ class ApiDebtsTest extends ApiTestCase
|
||||
'id' => $debt_id,
|
||||
'in_debt' => 'yes',
|
||||
'status' => 'completed',
|
||||
'amount' => 142,
|
||||
'amount' => 14201,
|
||||
'reason' => 'voilà',
|
||||
]);
|
||||
}
|
||||
|
||||
+5
-72
@@ -2,80 +2,13 @@
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Tests\Traits\Asserts;
|
||||
use Tests\Traits\ApiSignIn;
|
||||
use Illuminate\Testing\TestResponse;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiTestCase extends TestCase
|
||||
{
|
||||
use ApiSignIn;
|
||||
|
||||
/**
|
||||
* Test that the response contains a not found notification.
|
||||
*
|
||||
* @param TestResponse $response
|
||||
*/
|
||||
public function expectNotFound(TestResponse $response)
|
||||
{
|
||||
$response->assertStatus(404);
|
||||
|
||||
$response->assertJson([
|
||||
'error' => [
|
||||
'message' => 'The resource has not been found',
|
||||
'error_code' => 31,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the response contains a not authorized notification.
|
||||
*
|
||||
* @param TestResponse $response
|
||||
*/
|
||||
public function expectNotAuthorized(TestResponse $response)
|
||||
{
|
||||
$response->assertStatus(401);
|
||||
|
||||
$response->assertJson([
|
||||
'error' => [
|
||||
'message' => 'Not authorized',
|
||||
'error_code' => 42,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the response contains a data error notification.
|
||||
*
|
||||
* @param TestResponse $response
|
||||
* @param string|array $message
|
||||
*/
|
||||
public function expectDataError(TestResponse $response, $message = '')
|
||||
{
|
||||
$response->assertStatus(422);
|
||||
|
||||
$response->assertJson([
|
||||
'error' => [
|
||||
'message' => $message,
|
||||
'error_code' => 32,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the response contains an invalid parameter notification.
|
||||
*
|
||||
* @param TestResponse $response
|
||||
* @param string|array $message
|
||||
*/
|
||||
public function expectInvalidParameter(TestResponse $response, $message = '')
|
||||
{
|
||||
$response->assertStatus(422);
|
||||
|
||||
$response->assertJson([
|
||||
'error' => [
|
||||
'message' => $message,
|
||||
'error_code' => 41,
|
||||
],
|
||||
]);
|
||||
}
|
||||
use ApiSignIn,
|
||||
Asserts,
|
||||
DatabaseTransactions;
|
||||
}
|
||||
|
||||
@@ -2,15 +2,20 @@
|
||||
|
||||
namespace Tests\Browser\Auth;
|
||||
|
||||
use Tests\TestCase;
|
||||
use GuzzleHttp\Client;
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\User\User;
|
||||
use Tests\Traits\Asserts;
|
||||
use Tests\Traits\ApiSignIn;
|
||||
use Illuminate\Testing\TestResponse;
|
||||
use Laravel\Passport\ClientRepository;
|
||||
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
|
||||
|
||||
class AuthControllerTest extends ApiTestCase
|
||||
class AuthControllerTest extends TestCase
|
||||
{
|
||||
use ApiSignIn,
|
||||
Asserts;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
@@ -29,28 +34,39 @@ class AuthControllerTest extends ApiTestCase
|
||||
|
||||
public function test_oauth_login()
|
||||
{
|
||||
$client = (new ClientRepository())->createPasswordGrantClient(
|
||||
null, config('app.name'), config('app.url')
|
||||
);
|
||||
$repository = new ClientRepository();
|
||||
$client = null;
|
||||
try {
|
||||
$client = $repository->createPasswordGrantClient(
|
||||
null, config('app.name'), config('app.url')
|
||||
);
|
||||
|
||||
$this->setEnvironmentValue([
|
||||
'MOBILE_CLIENT_ID' => $client->id,
|
||||
'MOBILE_CLIENT_SECRET' => $client->secret,
|
||||
]);
|
||||
$this->setEnvironmentValue([
|
||||
'MOBILE_CLIENT_ID' => $client->id,
|
||||
'MOBILE_CLIENT_SECRET' => $client->secret,
|
||||
]);
|
||||
|
||||
$userPassword = 'password';
|
||||
$user = factory(User::class)->create([
|
||||
'password' => bcrypt($userPassword),
|
||||
]);
|
||||
$userPassword = 'password';
|
||||
$user = factory(User::class)->create([
|
||||
'password' => bcrypt($userPassword),
|
||||
]);
|
||||
|
||||
$response = $this->postClient(self::OAUTH_LOGIN_URL, [
|
||||
'email' => $user->email,
|
||||
'password' => $userPassword,
|
||||
]);
|
||||
$response = $this->postClient(self::OAUTH_LOGIN_URL, [
|
||||
'email' => $user->email,
|
||||
'password' => $userPassword,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure($this->jsonStructureOAuthLogin);
|
||||
$response->assertJsonStructure($this->jsonStructureOAuthLogin);
|
||||
} finally {
|
||||
if ($client) {
|
||||
$repository->delete($client);
|
||||
}
|
||||
if ($user) {
|
||||
$user->account->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function test_oauth_login_wrong_mail()
|
||||
@@ -76,29 +92,40 @@ class AuthControllerTest extends ApiTestCase
|
||||
|
||||
public function test_oauth_login_2fa()
|
||||
{
|
||||
$client = (new ClientRepository())->createPasswordGrantClient(
|
||||
null, config('app.name'), config('app.url')
|
||||
);
|
||||
$repository = new ClientRepository();
|
||||
$client = null;
|
||||
try {
|
||||
$client = $repository->createPasswordGrantClient(
|
||||
null, config('app.name'), config('app.url')
|
||||
);
|
||||
|
||||
$this->setEnvironmentValue([
|
||||
'MOBILE_CLIENT_ID' => $client->id,
|
||||
'MOBILE_CLIENT_SECRET' => $client->secret,
|
||||
]);
|
||||
$this->setEnvironmentValue([
|
||||
'MOBILE_CLIENT_ID' => $client->id,
|
||||
'MOBILE_CLIENT_SECRET' => $client->secret,
|
||||
]);
|
||||
|
||||
$userPassword = 'password';
|
||||
$user = factory(User::class)->create([
|
||||
'password' => bcrypt($userPassword),
|
||||
'google2fa_secret' => 'UFKZDTYO64WDEZPPQEO4HF3PC5UUTFLE',
|
||||
]);
|
||||
$userPassword = 'password';
|
||||
$user = factory(User::class)->create([
|
||||
'password' => bcrypt($userPassword),
|
||||
'google2fa_secret' => 'UFKZDTYO64WDEZPPQEO4HF3PC5UUTFLE',
|
||||
]);
|
||||
|
||||
$response = $this->postClient(self::OAUTH_LOGIN_URL, [
|
||||
'email' => $user->email,
|
||||
'password' => $userPassword,
|
||||
]);
|
||||
$response = $this->postClient(self::OAUTH_LOGIN_URL, [
|
||||
'email' => $user->email,
|
||||
'password' => $userPassword,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertSee('Two Factor Authentication');
|
||||
$response->assertSee('Two Factor Authentication');
|
||||
} finally {
|
||||
if ($client) {
|
||||
$repository->delete($client);
|
||||
}
|
||||
if ($user) {
|
||||
$user->account->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getActualConnection()
|
||||
|
||||
@@ -332,11 +332,13 @@ class ContactTest extends FeatureTestCase
|
||||
'reason' => $this->faker->sentence(),
|
||||
];
|
||||
|
||||
$this->post(
|
||||
$response = $this->post(
|
||||
route('people.debts.store', $contact),
|
||||
$debt
|
||||
);
|
||||
$response->assertStatus(302);
|
||||
|
||||
$debt['amount'] = $debt['amount'] * 100;
|
||||
$this->assertDatabaseHas('debts',
|
||||
$debt + [
|
||||
'contact_id' => $contact->id,
|
||||
@@ -354,11 +356,13 @@ class ContactTest extends FeatureTestCase
|
||||
'reason' => $this->faker->sentence(),
|
||||
];
|
||||
|
||||
$this->post(
|
||||
$response = $this->post(
|
||||
route('people.debts.store', $contact),
|
||||
$debt
|
||||
);
|
||||
$response->assertStatus(302);
|
||||
|
||||
$debt['amount'] = $debt['amount'] * 100;
|
||||
$this->assertDatabaseHas('debts',
|
||||
$debt + [
|
||||
'contact_id' => $contact->id,
|
||||
@@ -668,11 +672,9 @@ class ContactTest extends FeatureTestCase
|
||||
$user->save();
|
||||
|
||||
$gift = factory(Gift::class)->make();
|
||||
$gift->value = '100';
|
||||
$gift->amount = '100';
|
||||
|
||||
$this->assertEquals(
|
||||
'$100.00',
|
||||
$gift->amount
|
||||
);
|
||||
$this->assertEquals('100.00', $gift->amount);
|
||||
$this->assertEquals('$100.00', $gift->displayValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,26 +3,12 @@
|
||||
namespace Tests;
|
||||
|
||||
use Tests\Traits\SignIn;
|
||||
use Illuminate\Testing\TestResponse;
|
||||
use Tests\Traits\Asserts;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class FeatureTestCase extends TestCase
|
||||
{
|
||||
use SignIn;
|
||||
|
||||
/**
|
||||
* Test that the response contains a not found notification.
|
||||
*
|
||||
* @param TestResponse $response
|
||||
*/
|
||||
public function expectNotFound(TestResponse $response)
|
||||
{
|
||||
$response->assertStatus(404);
|
||||
|
||||
$response->assertJson([
|
||||
'error' => [
|
||||
'message' => 'The resource has not been found',
|
||||
'error_code' => 31,
|
||||
],
|
||||
]);
|
||||
}
|
||||
use SignIn,
|
||||
Asserts,
|
||||
DatabaseTransactions;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Traits;
|
||||
|
||||
use Illuminate\Testing\TestResponse;
|
||||
|
||||
trait Asserts
|
||||
{
|
||||
/**
|
||||
* Test that the response contains a not found notification.
|
||||
*
|
||||
* @param TestResponse $response
|
||||
*/
|
||||
public function expectNotFound(TestResponse $response)
|
||||
{
|
||||
$response->assertStatus(404);
|
||||
|
||||
$response->assertJson([
|
||||
'error' => [
|
||||
'message' => 'The resource has not been found',
|
||||
'error_code' => 31,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the response contains a not authorized notification.
|
||||
*
|
||||
* @param TestResponse $response
|
||||
*/
|
||||
public function expectNotAuthorized(TestResponse $response)
|
||||
{
|
||||
$response->assertStatus(401);
|
||||
|
||||
$response->assertJson([
|
||||
'error' => [
|
||||
'message' => 'Not authorized',
|
||||
'error_code' => 42,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the response contains a data error notification.
|
||||
*
|
||||
* @param TestResponse $response
|
||||
* @param string|array $message
|
||||
*/
|
||||
public function expectDataError(TestResponse $response, $message = '')
|
||||
{
|
||||
$response->assertStatus(422);
|
||||
|
||||
$response->assertJson([
|
||||
'error' => [
|
||||
'message' => $message,
|
||||
'error_code' => 32,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the response contains an invalid parameter notification.
|
||||
*
|
||||
* @param TestResponse $response
|
||||
* @param string|array $message
|
||||
*/
|
||||
public function expectInvalidParameter(TestResponse $response, $message = '')
|
||||
{
|
||||
$response->assertStatus(422);
|
||||
|
||||
$response->assertJson([
|
||||
'error' => [
|
||||
'message' => $message,
|
||||
'error_code' => 41,
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,12 @@ use App\Models\User\User;
|
||||
use App\Helpers\AuditLogHelper;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Models\Instance\AuditLog;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class AuditLogHelperTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_prepares_a_collection_of_audit_logs_for_the_settings_page()
|
||||
{
|
||||
|
||||
@@ -16,9 +16,9 @@ class InstanceHelperTest extends TestCase
|
||||
/** @test */
|
||||
public function it_gets_the_number_of_paid_subscribers()
|
||||
{
|
||||
$account = factory(Account::class)->create(['stripe_id' => 'id292839']);
|
||||
$account = factory(Account::class)->create();
|
||||
$account = factory(Account::class)->create(['stripe_id' => 'id2sdf92839']);
|
||||
factory(Account::class)->create(['stripe_id' => 'id292839']);
|
||||
factory(Account::class)->create();
|
||||
factory(Account::class)->create(['stripe_id' => 'id2sdf92839']);
|
||||
|
||||
$this->assertEquals(
|
||||
2,
|
||||
|
||||
@@ -19,8 +19,12 @@ class MoneyHelperTest extends TestCase
|
||||
$currency = new Currency();
|
||||
$currency->iso = 'EUR';
|
||||
|
||||
$this->assertEquals('€500.00', MoneyHelper::format(500, $currency));
|
||||
$this->assertEquals('€5,038.29', MoneyHelper::format(5038.29, $currency));
|
||||
$this->assertEquals('€500.00', MoneyHelper::format(50000, $currency));
|
||||
$this->assertEquals('€5,038.29', MoneyHelper::format(503829, $currency));
|
||||
$this->assertEquals('500.00', MoneyHelper::getValue(50000, $currency));
|
||||
$this->assertEquals('5038.29', MoneyHelper::getValue(503829, $currency));
|
||||
$this->assertEquals(500, MoneyHelper::exchangeValue(50000, $currency));
|
||||
$this->assertEquals(5038.29, MoneyHelper::exchangeValue(503829, $currency));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
@@ -31,7 +35,12 @@ class MoneyHelperTest extends TestCase
|
||||
$currency = new Currency();
|
||||
$currency->iso = 'EUR';
|
||||
|
||||
$this->assertEquals('500,00 €', MoneyHelper::format(500, $currency));
|
||||
$this->assertEquals('500,00 €', MoneyHelper::format(50000, $currency));
|
||||
$this->assertEquals('5 038,29 €', MoneyHelper::format(503829, $currency));
|
||||
$this->assertEquals('500,00', MoneyHelper::getValue(50000, $currency));
|
||||
$this->assertEquals('5038,29', MoneyHelper::getValue(503829, $currency));
|
||||
$this->assertEquals(500, MoneyHelper::exchangeValue(50000, $currency));
|
||||
$this->assertEquals(5038.29, MoneyHelper::exchangeValue(503829, $currency));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
@@ -42,6 +51,10 @@ class MoneyHelperTest extends TestCase
|
||||
|
||||
$this->assertEquals('¥500', MoneyHelper::format(500, $currency));
|
||||
$this->assertEquals('¥5,038', MoneyHelper::format(5038, $currency));
|
||||
$this->assertEquals('500', MoneyHelper::getValue(500, $currency));
|
||||
$this->assertEquals('5038', MoneyHelper::getValue(5038, $currency));
|
||||
$this->assertEquals(500, MoneyHelper::exchangeValue(500, $currency));
|
||||
$this->assertEquals(5038, MoneyHelper::exchangeValue(5038, $currency));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
@@ -53,8 +66,12 @@ class MoneyHelperTest extends TestCase
|
||||
]);
|
||||
$this->actingAs($user);
|
||||
|
||||
$this->assertEquals('£75.00', MoneyHelper::format(75));
|
||||
$this->assertEquals('£2,734.12', MoneyHelper::format(2734.12));
|
||||
$this->assertEquals('£75.00', MoneyHelper::format(7500, $currency));
|
||||
$this->assertEquals('£2,734.12', MoneyHelper::format(273412, $currency));
|
||||
$this->assertEquals('75.00', MoneyHelper::getValue(7500, $currency));
|
||||
$this->assertEquals('2734.12', MoneyHelper::getValue(273412, $currency));
|
||||
$this->assertEquals(75, MoneyHelper::exchangeValue(7500, $currency));
|
||||
$this->assertEquals(2734.12, MoneyHelper::exchangeValue(273412, $currency));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
@@ -80,6 +97,18 @@ class MoneyHelperTest extends TestCase
|
||||
]);
|
||||
$this->actingAs($user);
|
||||
|
||||
$this->assertEquals('R$12,345.67', MoneyHelper::format(12345.67));
|
||||
$this->assertEquals('R$12,345.67', MoneyHelper::format(1234567, $currency));
|
||||
$this->assertEquals('12345.67', MoneyHelper::getValue(1234567, $currency));
|
||||
$this->assertEquals(12345.67, MoneyHelper::exchangeValue(1234567, $currency));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_parse_an_input_value()
|
||||
{
|
||||
$currency = new Currency();
|
||||
$currency->iso = 'EUR';
|
||||
|
||||
$this->assertEquals(50000, MoneyHelper::parseInput('500.00', $currency));
|
||||
$this->assertEquals(503829, MoneyHelper::parseInput('5038.29', $currency));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -623,7 +623,7 @@ class ContactTest extends FeatureTestCase
|
||||
'contact_id' => $contact->id,
|
||||
]));
|
||||
|
||||
$this->assertEquals(200, $contact->totalOutstandingDebtAmount());
|
||||
$this->assertEquals(20000, $contact->totalOutstandingDebtAmount());
|
||||
|
||||
$contact->debts()->save(new Debt([
|
||||
'in_debt' => 'yes',
|
||||
@@ -632,7 +632,7 @@ class ContactTest extends FeatureTestCase
|
||||
'contact_id' => $contact->id,
|
||||
]));
|
||||
|
||||
$this->assertEquals(100, $contact->totalOutstandingDebtAmount());
|
||||
$this->assertEquals(10000, $contact->totalOutstandingDebtAmount());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Tests\Unit\Models;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User\User;
|
||||
use App\Models\Contact\Gift;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
@@ -106,12 +107,15 @@ class GiftTest extends TestCase
|
||||
/** @test */
|
||||
public function it_gets_the_value()
|
||||
{
|
||||
$user = factory(User::class)->create();
|
||||
$this->be($user);
|
||||
$gift = factory(Gift::class)->make([
|
||||
'value' => 100,
|
||||
'account_id' => $user->account_id,
|
||||
'amount' => 100,
|
||||
]);
|
||||
|
||||
$this->assertEquals(
|
||||
'100',
|
||||
'100.00',
|
||||
$gift->amount
|
||||
);
|
||||
}
|
||||
|
||||
@@ -425,6 +425,9 @@ class UserTest extends TestCase
|
||||
config(['monica.signup_double_optin' => true]);
|
||||
Notification::fake();
|
||||
|
||||
// Creating a fake account
|
||||
factory(Account::class)->create();
|
||||
|
||||
$user = factory(User::class)->create([]);
|
||||
$user->sendEmailVerificationNotification();
|
||||
|
||||
|
||||
@@ -84,6 +84,9 @@ class EmailChangeTest extends TestCase
|
||||
NotificationFacade::fake();
|
||||
config(['monica.signup_double_optin' => true]);
|
||||
|
||||
// Creating a fake account
|
||||
factory(Account::class)->create();
|
||||
|
||||
$user = factory(User::class)->create([]);
|
||||
|
||||
$request = [
|
||||
@@ -114,6 +117,9 @@ class EmailChangeTest extends TestCase
|
||||
NotificationFacade::fake();
|
||||
config(['monica.signup_double_optin' => true]);
|
||||
|
||||
// Creating a fake account
|
||||
factory(Account::class)->create();
|
||||
|
||||
$user = factory(User::class)->create([]);
|
||||
|
||||
$request = [
|
||||
|
||||
Reference in New Issue
Block a user