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

2.0 #81

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open

2.0 #81

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
92adac0
Add money cast and livewire synthesizer
pelmered Nov 7, 2024
886de6a
Add money cast and livewire synthesizer
pelmered Nov 7, 2024
8185f68
Merge branch '2.0' into money-cast-support
pelmered Nov 7, 2024
fba3a57
Code style
pelmered Nov 7, 2024
7b48478
Merge pull request #68 from pelmered/money-cast-support
pelmered Nov 7, 2024
15106a1
[WIP] Upgrade guide
pelmered Nov 8, 2024
50ae1ee
Replace PHPStan with Larastan
pelmered Nov 8, 2024
799ce98
Currency case + type hints
pelmered Nov 8, 2024
bcc5a17
Update readme
pelmered Dec 4, 2024
041375b
Add support for money cast on model
pelmered Dec 4, 2024
570536a
Merge main into 2.0
pelmered Dec 4, 2024
8463bb0
Redo: Move formatters into a folder on 2.0 branch
pelmered Dec 4, 2024
8169d85
Reorginze tests
pelmered Dec 26, 2024
a3e5dee
Remove debug code
pelmered Dec 26, 2024
e40ce7b
Merge pull request #76 from pelmered/feature/add-suport-for-money-cas…
pelmered Dec 26, 2024
c721c9b
Fix coverage report path
pelmered Dec 4, 2024
bf82d77
Style fixes
pelmered Dec 4, 2024
e552460
Add type hints
pelmered Dec 4, 2024
de3fa61
Improve validation rules and the tests
pelmered Dec 4, 2024
1545b6b
Refactor MoneyFormatterTest and make it more like Pest tests
pelmered Dec 5, 2024
3f6c398
Improve short formatter
pelmered Dec 5, 2024
c72772e
Revert back to calling the parameter decimals instead of precision to…
pelmered Dec 5, 2024
f51eb81
Type fixes + lint
pelmered Dec 5, 2024
91db28b
Add hideCurrencySymbol method on column and entry
pelmered Dec 5, 2024
127bc20
Lint
pelmered Dec 5, 2024
119fe6d
Add money cast and livewire synthesizer
pelmered Nov 7, 2024
0fd6106
Code style
pelmered Nov 7, 2024
1b8e77b
Currency case + type hints
pelmered Nov 8, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
run: composer update --prefer-stable --prefer-dist --no-interaction

- name: Execute tests
run: vendor/bin/pest --coverage-clover=reports/coverage/clover.xml
run: vendor/bin/pest --coverage-clover=reports/coverage/test-coverage-clover.xml

- name: Execute type coverage tests
run: vendor/bin/pest --type-coverage --type-coverage-json=reports/coverage/pest-types-coverage.json
Expand Down
36 changes: 32 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,15 @@ This package would give "1 234,56 kr", while most other solutions probably would
composer require pelmered/filament-money-field
```

## Configure your locale
## Upgrade to 2.* from 1.*

### Set the default currency and locale
See [upgrade guide](UPGRADE.md).

## Configuration

### Configure your locale

#### Set the default currency and locale

**Set the default options for currency and locale so that you don't have to set them for every field.**

Expand All @@ -67,7 +73,7 @@ php artisan vendor:publish --provider="Pelmered\FilamentMoneyField\FilamentMoney
```


### Decimals and significant digits
#### Decimals and significant digits

The number of decimals and significant digits can be set in the config file. Defaults to 2.

Expand All @@ -78,6 +84,7 @@ MONEY_DECIMAL_DIGITS=2 // Gives 2 decimals, e.g. $1,234.56
```

For significant digits, use negative values. For example -2 will give you 2 significant digits.
This is only for displaying the amount. The amount will always be saved with full precision.

```env
//with input 12345678
Expand All @@ -93,6 +100,15 @@ MoneyEntry::make('price')->decimals(2);
MoneyColumn::make('price')->decimals(-2);
```

### Configuration for saving currency per field in database (Recommended, especially for multi-currency applications)

#### Migrations

TODO: Add docs

#### Casts

TODO: Add docs

## Usage

Expand Down Expand Up @@ -137,7 +153,19 @@ MoneyColumn::make('price')
->locale('sv_SE'),

MoneyColumn::make('price')
->short(), // Short fromat, e.g. $1.23M instead of $1,234,567.89
->short(), // Short format, e.g. $1.23M instead of $1,234,567.89

MoneyColumn::make('price')
->short()
->hideCurrencySymbol(), // Short format without currency symbol, e.g. 1.23M instead of $1.23M

MoneyColumn::make('price')
->decimals(4)
->short(), // $1.2345M

MoneyColumn::make('price')
->decimals(-3) // 3 significant digits
->short(), // $1.23K or $23.1M
```

### InfoList
Expand Down
20 changes: 20 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

# Upgrade from 1.*

### For full support, add Money casts for your money fields.

Each money column needs a corresponding currency column with the name {money_column}_currency

For new columns
```
Schema::table('tablename', function (Blueprint $table) {
$table->money('price'); // This will create two columns, 'price' (integer) and 'price_currency' (char(3))
});
```
For changing existing columns, in this case a column called `price`.
```
Schema::table('tablename', function (Blueprint $table) {
$table->char('price_currency', 3)->after('price')->change();
$this->index(['price', 'price_currency']);
});
```
7 changes: 5 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@
"require-dev": {
"filament/filament": "^3.2",
"orchestra/testbench": "^9.0",
"phpstan/phpstan": "^1.12.2",
"nunomaduro/collision": "^8.0",
"laravel/pint": "^1.16",
"pestphp/pest": "^3.0",
"pestphp/pest-plugin-drift": "^3.0",
"pestphp/pest-plugin-type-coverage": "^3.0"
"pestphp/pest-plugin-type-coverage": "^3.0",
"larastan/larastan": "^2.0"
},
"extra": {
"laravel": {
Expand Down Expand Up @@ -72,6 +72,9 @@
"coverage": [
"@php vendor/bin/pest --testsuite=default --coverage-clover=coverage.xml --coverage-filter=src --path-coverage"
],
"types": [
"@php vendor/bin/pest --type-coverage"
],
"check" : [
"composer lint",
"composer test"
Expand Down
11 changes: 11 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

includes:
- vendor/larastan/larastan/extension.neon

parameters:

paths:
- src/

# Level 9 is the highest level
level: 8
45 changes: 45 additions & 0 deletions src/Casts/CurrencyCast.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Pelmered\FilamentMoneyField\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;
use Money\Currency;
use Money\Money;
use Spatie\LaravelData\Casts\Cast;

/**
* @implements CastsAttributes<Currency, Currency>
*/
class CurrencyCast implements CastsAttributes
{
/**
* Cast the given value.
*
* @param ?non-empty-string $value
* @param array<string, mixed> $attributes
*/
public function get(Model $model, string $key, mixed $value, array $attributes): ?Currency
{
if ($value === null) {
return null;
}

return new Currency($value);
}

/**
* Prepare the given value for storage.
*
* @param Currency|string $value
* @param array<string, mixed> $attributes
*/
public function set(Model $model, string $key, mixed $value, array $attributes): string
{
if ($value instanceof Currency) {
return $value->getCode();
}

return $value;
}
}
53 changes: 53 additions & 0 deletions src/Casts/MoneyCast.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace Pelmered\FilamentMoneyField\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;
use Money\Currency;
use Money\Money;
use Spatie\LaravelData\Casts\Cast;

/**
* @implements CastsAttributes<Money, Money>
*/
class MoneyCast implements CastsAttributes
{
/**
* Cast the given value.
*
* @param ?int $value
* @param array<string, mixed> $attributes
*/
public function get(Model $model, string $key, mixed $value, array $attributes): ?Money
{
if ($value === null) {
return null;
}

return new Money($value, $this->getCurrencyFromModel($model, $key));
}

/**
* Prepare the given value for storage.
*
* @param Money|string|null $value
* @param array<string, mixed> $attributes
*/
public function set(Model $model, string $key, mixed $value, array $attributes): ?string
{
if ($value instanceof Money) {
//$model->{$key.'_currency'} = $value->getCurrency();
return $value->getAmount();
}

return $value;
}

public function getCurrencyFromModel(Model $model, string $name): Currency
{
$currency = $model->{$name.'_currency'} ?? (string) (config('filament-money-field.default_currency'));

return $currency instanceof Currency ? $currency : new Currency($currency);
}
}
74 changes: 74 additions & 0 deletions src/Casts/MoneySynthesizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace Pelmered\FilamentMoneyField\Casts;

use Livewire\Mechanisms\HandleComponents\Synthesizers\Synth;
use Money\Currency;
use Money\Money;

class MoneySynthesizer extends Synth
{
public static string $key = 'money';

public static function match(mixed $target): bool
{
return $target instanceof Money;
}

/**
* @return array<int, array<string, Currency|string>>
*/
public function dehydrate(Money $target): array
{
return [[
'amount' => $target->getAmount(),
'currency' => $target->getCurrency(),
], []];
}

/**
* @param ?array<string, string> $value*
*/
public function hydrate(?array $value): ?string
{
if ($value === null) {
return null;
}

return $value['amount'];

/*
return new Money(
$value['amount'],
new Currency($value['currency'])
);
*/
}
/*
public function hydrate($value): ?Money
{
if ($value === null) {
return null;
}

return new Money(
$value['amount'],
new Currency($value['currency'])
);
}
*/

/*
public function get(&$target, $key)
{
//dd($target, $key);
return $target->{$key};
}

public function set(&$target, $key, $value)
{
//dd($target, $key, $value);
$target->{$key} = $value;
}
*/
}
5 changes: 5 additions & 0 deletions src/FilamentMoneyFieldServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Pelmered\FilamentMoneyField;

use Livewire\Livewire;
use Pelmered\FilamentMoneyField\Casts\MoneySynthesizer;
use Illuminate\Database\Schema\Blueprint;
use Spatie\LaravelPackageTools\Package;
use Spatie\LaravelPackageTools\PackageServiceProvider;
Expand All @@ -22,11 +24,14 @@ public function boot(): void
__DIR__.'/../config/filament-money-field.php' => config_path('filament-money-field.php'),
], 'config');

Livewire::propertySynthesizer(MoneySynthesizer::class);

Blueprint::macro('money', function (string $name, ?string $indexName = null) {
$this->unsignedBigInteger($name);
$this->string("{$name}_currency");

$this->index([$name, "{$name}_currency"], $indexName);
});

}
}
Loading