diff --git a/composer.json b/composer.json index b87456854..7aa9b6cde 100644 --- a/composer.json +++ b/composer.json @@ -32,17 +32,17 @@ "ramsey/uuid": "^4.0" }, "require-dev": { - "brianium/paratest": "^7.2", - "cknow/laravel-money": "^7.1", - "ergebnis/phpstan-rules": "^1.0", + "brianium/paratest": "^7.3", + "cknow/laravel-money": "^7.2", + "ergebnis/phpstan-rules": "^2.1", "infection/infection": "~0.27", "laravel/cashier": "^15.0", - "nunomaduro/collision": "^7.7", - "nunomaduro/larastan": "^2.6", - "orchestra/testbench": "^8.5", + "nunomaduro/collision": "^7.10", + "nunomaduro/larastan": "^2.7", + "orchestra/testbench": "^8.19", "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^10.2", - "rector/rector": "^0.17", + "phpunit/phpunit": "^10.5", + "rector/rector": "^0.18", "symplify/easy-coding-standard": "^12.0" }, "suggest": { diff --git a/config/config.php b/config/config.php index 5bdcf0ac3..937109a22 100644 --- a/config/config.php +++ b/config/config.php @@ -44,6 +44,7 @@ use Bavix\Wallet\Services\DiscountService; use Bavix\Wallet\Services\EagerLoaderService; use Bavix\Wallet\Services\ExchangeService; +use Bavix\Wallet\Services\FormatterService; use Bavix\Wallet\Services\PrepareService; use Bavix\Wallet\Services\PurchaseService; use Bavix\Wallet\Services\RegulatorService; @@ -110,6 +111,7 @@ 'discount' => DiscountService::class, 'eager_loader' => EagerLoaderService::class, 'exchange' => ExchangeService::class, + 'formatter' => FormatterService::class, 'prepare' => PrepareService::class, 'purchase' => PurchaseService::class, 'tax' => TaxService::class, diff --git a/phpstan.common.neon b/phpstan.common.neon index 8d97ee03a..927803fd1 100644 --- a/phpstan.common.neon +++ b/phpstan.common.neon @@ -1,60 +1,8 @@ includes: - vendor/nunomaduro/larastan/extension.neon + - vendor/ergebnis/phpstan-rules/rules.neon parameters: level: 9 fileExtensions: - php - -parametersSchema: - ergebnis: structure([ - allowAbstractClasses: bool() - classesAllowedToBeExtended: listOf(string()) - classesNotRequiredToBeAbstractOrFinal: listOf(string()) - interfacesImplementedByContainers: listOf(string()) - ]) - -rules: - - Ergebnis\PHPStan\Rules\Closures\NoNullableReturnTypeDeclarationRule - - Ergebnis\PHPStan\Rules\Closures\NoParameterWithNullableTypeDeclarationRule - - Ergebnis\PHPStan\Rules\Expressions\NoCompactRule - - Ergebnis\PHPStan\Rules\Expressions\NoEmptyRule - - Ergebnis\PHPStan\Rules\Expressions\NoErrorSuppressionRule - - Ergebnis\PHPStan\Rules\Expressions\NoEvalRule - - Ergebnis\PHPStan\Rules\Expressions\NoIssetRule - - Ergebnis\PHPStan\Rules\Files\DeclareStrictTypesRule - - Ergebnis\PHPStan\Rules\Functions\NoNullableReturnTypeDeclarationRule - - Ergebnis\PHPStan\Rules\Functions\NoParameterWithNullableTypeDeclarationRule - - Ergebnis\PHPStan\Rules\Functions\NoParameterWithNullDefaultValueRule - - Ergebnis\PHPStan\Rules\Methods\FinalInAbstractClassRule - - Ergebnis\PHPStan\Rules\Methods\NoConstructorParameterWithDefaultValueRule - - Ergebnis\PHPStan\Rules\Methods\PrivateInFinalClassRule - - Ergebnis\PHPStan\Rules\Statements\NoSwitchRule - -services: - - - class: Ergebnis\PHPStan\Rules\Classes\FinalRule - arguments: - allowAbstractClasses: %ergebnis.allowAbstractClasses% - classesNotRequiredToBeAbstractOrFinal: %ergebnis.classesNotRequiredToBeAbstractOrFinal% - tags: - - phpstan.rules.rule - - - - class: Ergebnis\PHPStan\Rules\Classes\NoExtendsRule - arguments: - classesAllowedToBeExtended: %ergebnis.classesAllowedToBeExtended% - tags: - - phpstan.rules.rule - - - - class: Ergebnis\PHPStan\Rules\Classes\PHPUnit\Framework\TestCaseWithSuffixRule - tags: - - phpstan.rules.rule - - - - class: Ergebnis\PHPStan\Rules\Methods\NoParameterWithContainerTypeDeclarationRule - arguments: - interfacesImplementedByContainers: %ergebnis.interfacesImplementedByContainers% - tags: - - phpstan.rules.rule diff --git a/phpstan.src.neon b/phpstan.src.neon index 7952daa9c..d552a5775 100644 --- a/phpstan.src.neon +++ b/phpstan.src.neon @@ -7,24 +7,32 @@ parameters: fileExtensions: - php ergebnis: - allowAbstractClasses: true - classesAllowedToBeExtended: - # laravel - - Illuminate\Support\ServiceProvider - - Illuminate\Database\Eloquent\Model + noParameterWithNullableTypeDeclaration: + enabled: false + noNullableReturnTypeDeclaration: + enabled: false + noParameterWithNullDefaultValue: + enabled: false + final: + allowAbstractClasses: true + classesNotRequiredToBeAbstractOrFinal: + - Bavix\Wallet\Models\Wallet + - Bavix\Wallet\Models\Transfer + - Bavix\Wallet\Models\Transaction + noExtends: + classesAllowedToBeExtended: + # laravel + - Illuminate\Support\ServiceProvider + - Illuminate\Database\Eloquent\Model - # php exceptions - - LogicException - - RuntimeException - - UnderflowException - - UnexpectedValueException - - InvalidArgumentException - - classesNotRequiredToBeAbstractOrFinal: - - Bavix\Wallet\Models\Wallet - - Bavix\Wallet\Models\Transfer - - Bavix\Wallet\Models\Transaction - interfacesImplementedByContainers: - - Psr\Container\ContainerInterface + # php exceptions + - LogicException + - RuntimeException + - UnderflowException + - UnexpectedValueException + - InvalidArgumentException + noParameterWithContainerTypeDeclaration: + interfacesImplementedByContainers: + - Psr\Container\ContainerInterface paths: - src/ diff --git a/phpstan.tests.neon b/phpstan.tests.neon index 85854cf85..a39aa43d5 100644 --- a/phpstan.tests.neon +++ b/phpstan.tests.neon @@ -9,32 +9,41 @@ parameters: fileExtensions: - php ergebnis: - allowAbstractClasses: false - classesAllowedToBeExtended: - # laravel - - Illuminate\Support\ServiceProvider - - Illuminate\Database\Eloquent\Model - - Illuminate\Database\Migrations\Migration - - Illuminate\Database\Eloquent\Factories\Factory + noParameterWithNullableTypeDeclaration: + enabled: false + noNullableReturnTypeDeclaration: + enabled: false + noParameterWithNullDefaultValue: + enabled: false + final: + allowAbstractClasses: false + classesNotRequiredToBeAbstractOrFinal: + - Bavix\Wallet\Models\Wallet + - Bavix\Wallet\Models\Transfer + - Bavix\Wallet\Models\Transaction + noExtends: + classesAllowedToBeExtended: + # laravel + - Illuminate\Support\ServiceProvider + - Illuminate\Database\Eloquent\Model + - Illuminate\Database\Migrations\Migration + - Illuminate\Database\Eloquent\Factories\Factory - # php exceptions - - RuntimeException - - InvalidArgumentException + # php exceptions + - RuntimeException + - InvalidArgumentException - # phpunit - - Orchestra\Testbench\TestCase - - Bavix\Wallet\Test\Infra\TestCase + # phpunit + - Orchestra\Testbench\TestCase + - Bavix\Wallet\Test\Infra\TestCase - # wallet - - Bavix\Wallet\Models\Wallet - - Bavix\Wallet\Models\Transfer - - Bavix\Wallet\Models\Transaction + # wallet + - Bavix\Wallet\Models\Wallet + - Bavix\Wallet\Models\Transfer + - Bavix\Wallet\Models\Transaction - classesNotRequiredToBeAbstractOrFinal: - - Bavix\Wallet\Models\Wallet - - Bavix\Wallet\Models\Transfer - - Bavix\Wallet\Models\Transaction - interfacesImplementedByContainers: - - Psr\Container\ContainerInterface + noParameterWithContainerTypeDeclaration: + interfacesImplementedByContainers: + - Psr\Container\ContainerInterface paths: - tests/ diff --git a/src/Traits/HasWalletFloat.php b/src/Traits/HasWalletFloat.php index 873691c5e..7dc1d5784 100644 --- a/src/Traits/HasWalletFloat.php +++ b/src/Traits/HasWalletFloat.php @@ -15,6 +15,7 @@ use Bavix\Wallet\Models\Transaction; use Bavix\Wallet\Models\Transfer; use Bavix\Wallet\Services\CastServiceInterface; +use Bavix\Wallet\Services\FormatterServiceInterface; use Illuminate\Database\RecordsNotFoundException; /** @@ -147,12 +148,12 @@ public function forceTransferFloat( public function getBalanceFloatAttribute(): string { - $math = app(MathServiceInterface::class); $wallet = app(CastServiceInterface::class)->getWallet($this); - $decimalPlacesValue = $wallet->decimal_places; - $decimalPlaces = $math->powTen($decimalPlacesValue); - return $math->div($wallet->getBalanceAttribute(), $decimalPlaces, $decimalPlacesValue); + return app(FormatterServiceInterface::class)->floatValue( + $wallet->getBalanceAttribute(), + $wallet->decimal_places, + ); } public function getBalanceFloatNumAttribute(): float diff --git a/src/Traits/MorphOneWallet.php b/src/Traits/MorphOneWallet.php index 1b27dbd60..196ba658d 100644 --- a/src/Traits/MorphOneWallet.php +++ b/src/Traits/MorphOneWallet.php @@ -56,10 +56,10 @@ public function wallet(): MorphOne public function getWalletAttribute(): ?WalletModel { - /** @var WalletModel $wallet */ + /** @var WalletModel|null $wallet */ $wallet = $this->getRelationValue('wallet'); - if (! $wallet->relationLoaded('holder')) { + if ($wallet && ! $wallet->relationLoaded('holder')) { $holder = app(CastServiceInterface::class)->getHolder($this); $wallet->setRelation('holder', $holder->withoutRelations()); } diff --git a/src/WalletServiceProvider.php b/src/WalletServiceProvider.php index a7ae10136..bb121d86b 100644 --- a/src/WalletServiceProvider.php +++ b/src/WalletServiceProvider.php @@ -92,6 +92,8 @@ use Bavix\Wallet\Services\EagerLoaderServiceInterface; use Bavix\Wallet\Services\ExchangeService; use Bavix\Wallet\Services\ExchangeServiceInterface; +use Bavix\Wallet\Services\FormatterService; +use Bavix\Wallet\Services\FormatterServiceInterface; use Bavix\Wallet\Services\PrepareService; use Bavix\Wallet\Services\PrepareServiceInterface; use Bavix\Wallet\Services\PurchaseService; @@ -274,6 +276,7 @@ private function services(array $configure, array $cache): void $configure['eager_loader'] ?? EagerLoaderService::class ); $this->app->singleton(ExchangeServiceInterface::class, $configure['exchange'] ?? ExchangeService::class); + $this->app->singleton(FormatterServiceInterface::class, $configure['formatter'] ?? FormatterService::class); $this->app->singleton(PrepareServiceInterface::class, $configure['prepare'] ?? PrepareService::class); $this->app->singleton(PurchaseServiceInterface::class, $configure['purchase'] ?? PurchaseService::class); $this->app->singleton(TaxServiceInterface::class, $configure['tax'] ?? TaxService::class); @@ -466,6 +469,7 @@ private function servicesProviders(): array DiscountServiceInterface::class, EagerLoaderServiceInterface::class, ExchangeServiceInterface::class, + FormatterServiceInterface::class, PrepareServiceInterface::class, PurchaseServiceInterface::class, TaxServiceInterface::class,