diff --git a/src/Fields/Price.php b/src/Fields/Price.php index 7b5bb9e2..8b261682 100644 --- a/src/Fields/Price.php +++ b/src/Fields/Price.php @@ -3,10 +3,10 @@ namespace Cone\Bazar\Fields; use Cone\Bazar\Bazar; +use Cone\Bazar\Support\Currency; use Cone\Root\Fields\Meta; use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Request; -use Illuminate\Support\Number; class Price extends Meta { @@ -29,7 +29,7 @@ public function __construct(string $label, ?string $currency = null) $this->field->min(0); $this->field->format(function (Request $request, Model $model, mixed $value): ?string { - return is_null($value) ? null : Number::currency($value, $this->currency); + return is_null($value) ? null : (new Currency($value, $this->currency))->format(); }); } diff --git a/src/Models/Item.php b/src/Models/Item.php index 512a4e4d..70168582 100644 --- a/src/Models/Item.php +++ b/src/Models/Item.php @@ -5,6 +5,7 @@ use Cone\Bazar\Database\Factories\ItemFactory; use Cone\Bazar\Interfaces\Buyable; use Cone\Bazar\Interfaces\Models\Item as Contract; +use Cone\Bazar\Support\Currency; use Cone\Bazar\Traits\InteractsWithTaxes; use Cone\Root\Traits\InteractsWithProxy; use Illuminate\Database\Eloquent\Casts\Attribute; @@ -208,7 +209,7 @@ public function getPrice(): float */ public function getFormattedPrice(): string { - return Number::currency($this->getPrice(), $this->itemable->getCurrency()); + return (new Currency($this->getPrice(), $this->itemable->getCurrency()))->format(); } /** @@ -224,7 +225,7 @@ public function getTotal(): float */ public function getFormattedTotal(): string { - return Number::currency($this->getTotal(), $this->itemable->getCurrency()); + return (new Currency($this->getTotal(), $this->itemable->getCurrency()))->format(); } /** @@ -240,7 +241,7 @@ public function getSubtotal(): float */ public function getFormattedSubtotal(): string { - return Number::currency($this->getSubtotal(), $this->itemable->getCurrency()); + return (new Currency($this->getSubtotal(), $this->itemable->getCurrency()))->format(); } /** diff --git a/src/Models/Shipping.php b/src/Models/Shipping.php index 038b38c5..1e1053af 100644 --- a/src/Models/Shipping.php +++ b/src/Models/Shipping.php @@ -4,6 +4,7 @@ use Cone\Bazar\Database\Factories\ShippingFactory; use Cone\Bazar\Interfaces\Models\Shipping as Contract; +use Cone\Bazar\Support\Currency; use Cone\Bazar\Support\Facades\Shipping as Manager; use Cone\Bazar\Traits\Addressable; use Cone\Bazar\Traits\InteractsWithTaxes; @@ -214,7 +215,7 @@ public function getPrice(): float */ public function getFormattedPrice(): string { - return Number::currency($this->getPrice(), $this->shippable->getCurrency()); + return (new Currency($this->getPrice(), $this->shippable->getCurrency()))->format(); } /** @@ -230,7 +231,7 @@ public function getTotal(): float */ public function getFormattedTotal(): string { - return Number::currency($this->getTotal(), $this->shippable->getCurrency()); + return (new Currency($this->getTotal(), $this->shippable->getCurrency()))->format(); } /** @@ -246,7 +247,7 @@ public function getSubtotal(): float */ public function getFormattedSubtotal(): string { - return Number::currency($this->getSubtotal(), $this->shippable->getCurrency()); + return (new Currency($this->getSubtotal(), $this->shippable->getCurrency()))->format(); } /** diff --git a/src/Support/Currency.php b/src/Support/Currency.php new file mode 100644 index 00000000..51097c83 --- /dev/null +++ b/src/Support/Currency.php @@ -0,0 +1,94 @@ +value = $value; + $this->currency = $currency ?: Bazar::getCurrency(); + $this->precision = $precision; + $this->locale = $locale ?: App::getLocale(); + } + + /** + * Set the formatter callback. + */ + public static function formatUsing(Closure $callback): void + { + static::$formatter = $callback; + } + + /** + * Format the currency. + */ + public function format(): string + { + $formatter = new NumberFormatter($this->locale, NumberFormatter::CURRENCY); + + if (! is_null($this->precision)) { + $formatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $this->precision); + } + + if (! is_null(static::$formatter)) { + call_user_func_array(static::$formatter, [$formatter, $this->value, $this->currency]); + } + + return $formatter->formatCurrency($this->value, $this->currency); + } + + /** + * Get the JSON serializable format of the currency. + */ + public function jsonSerialize(): mixed + { + return $this->format(); + } + + /** + * Convert the currency to string. + */ + public function __toString(): string + { + return $this->format(); + } +} diff --git a/src/Traits/HasPrices.php b/src/Traits/HasPrices.php index 110f3a48..5ebde25d 100644 --- a/src/Traits/HasPrices.php +++ b/src/Traits/HasPrices.php @@ -5,8 +5,8 @@ use Cone\Bazar\Bazar; use Cone\Bazar\Models\Price; use Cone\Bazar\Relations\Prices; +use Cone\Bazar\Support\Currency; use Illuminate\Database\Eloquent\Casts\Attribute; -use Illuminate\Support\Number; trait HasPrices { @@ -69,7 +69,7 @@ public function getFormattedPrice(?string $currency = null): ?string $price = $this->getPrice($currency); - return is_null($price) ? null : Number::currency($price, $currency); + return is_null($price) ? null : (new Currency($price, $currency))->format(); } /** diff --git a/src/Traits/InteractsWithDiscounts.php b/src/Traits/InteractsWithDiscounts.php index 6d78e1b7..af2e3441 100644 --- a/src/Traits/InteractsWithDiscounts.php +++ b/src/Traits/InteractsWithDiscounts.php @@ -2,9 +2,9 @@ namespace Cone\Bazar\Traits; +use Cone\Bazar\Support\Currency; use Cone\Bazar\Support\Facades\Discount; use Illuminate\Database\Eloquent\Casts\Attribute; -use Illuminate\Support\Number; trait InteractsWithDiscounts { @@ -35,7 +35,7 @@ public function getDiscount(): float */ public function getFormattedDiscount(): string { - return Number::currency($this->getDiscount(), $this->currency); + return (new Currency($this->getDiscount(), $this->currency))->format(); } /** diff --git a/src/Traits/InteractsWithItems.php b/src/Traits/InteractsWithItems.php index 9f260454..a5f694c3 100644 --- a/src/Traits/InteractsWithItems.php +++ b/src/Traits/InteractsWithItems.php @@ -7,6 +7,7 @@ use Cone\Bazar\Interfaces\LineItem; use Cone\Bazar\Models\Item; use Cone\Bazar\Models\Shipping; +use Cone\Bazar\Support\Currency; use Cone\Bazar\Support\Facades\Shipping as ShippingManager; use Cone\Root\Interfaces\Models\User; use Illuminate\Database\Eloquent\Casts\Attribute; @@ -17,7 +18,6 @@ use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Facades\App; -use Illuminate\Support\Number; trait InteractsWithItems { @@ -241,7 +241,7 @@ public function getTotal(): float */ public function getFormattedTotal(): string { - return Number::currency($this->getTotal(), $this->getCurrency()); + return (new Currency($this->getTotal(), $this->getCurrency()))->format(); } /** @@ -261,7 +261,7 @@ public function getSubtotal(): float */ public function getFormattedSubtotal(): string { - return Number::currency($this->getSubtotal(), $this->getCurrency()); + return (new Currency($this->getSubtotal(), $this->getCurrency()))->format(); } /** @@ -281,7 +281,7 @@ public function getFeeTotal(): float */ public function getFormattedFeeTotal(): string { - return Number::currency($this->getFeeTotal(), $this->getCurrency()); + return (new Currency($this->getFeeTotal(), $this->getCurrency()))->format(); } /** @@ -301,7 +301,7 @@ public function getTax(): float */ public function getFormattedTax(): string { - return Number::currency($this->getTax(), $this->getCurrency()); + return (new Currency($this->getTax(), $this->getCurrency()))->format(); } /** diff --git a/src/Traits/InteractsWithTaxes.php b/src/Traits/InteractsWithTaxes.php index 8c29e728..e2635a9a 100644 --- a/src/Traits/InteractsWithTaxes.php +++ b/src/Traits/InteractsWithTaxes.php @@ -5,9 +5,9 @@ use Cone\Bazar\Bazar; use Cone\Bazar\Models\Item; use Cone\Bazar\Models\Shipping; +use Cone\Bazar\Support\Currency; use Cone\Bazar\Support\Facades\Tax; use Illuminate\Database\Eloquent\Casts\Attribute; -use Illuminate\Support\Number; trait InteractsWithTaxes { @@ -46,7 +46,7 @@ public function getFormattedTax(): string $currency = $this->shippable->currency; } - return Number::currency($this->getTax(), $currency); + return (new Currency($this->getTax(), $currency))->format(); } /** diff --git a/tests/Models/ItemTest.php b/tests/Models/ItemTest.php index 08963487..54297e8b 100644 --- a/tests/Models/ItemTest.php +++ b/tests/Models/ItemTest.php @@ -6,9 +6,9 @@ use Cone\Bazar\Models\Cart; use Cone\Bazar\Models\Item; use Cone\Bazar\Models\Product; +use Cone\Bazar\Support\Currency; use Cone\Bazar\Support\Facades\Tax; use Cone\Bazar\Tests\TestCase; -use Illuminate\Support\Number; class ItemTest extends TestCase { @@ -35,7 +35,10 @@ public function setUp(): void public function test_item_is_taxable(): void { $this->assertInstanceOf(Taxable::class, $this->item); - $this->assertSame(Number::currency($this->item->tax, $this->item->itemable->currency), $this->item->getFormattedTax()); + $this->assertSame( + (new Currency($this->item->tax, $this->item->itemable->currency))->format(), + $this->item->getFormattedTax() + ); $this->assertSame($this->item->getFormattedTax(), $this->item->formattedTax); } @@ -43,7 +46,8 @@ public function test_item_has_price_attribute(): void { $this->assertSame($this->item->price, $this->item->getPrice()); $this->assertSame( - Number::currency($this->item->price, $this->item->itemable->currency), $this->item->getFormattedPrice() + (new Currency($this->item->price, $this->item->itemable->currency))->format(), + $this->item->getFormattedPrice() ); $this->assertSame($this->item->getFormattedPrice(), $this->item->formattedPrice); } @@ -56,14 +60,14 @@ public function test_item_has_total_attribute(): void ); $this->assertSame($this->item->getTotal(), $this->item->total); $this->assertSame( - Number::currency($this->item->total, $this->item->itemable->currency), + (new Currency($this->item->total, $this->item->itemable->currency))->format(), $this->item->getFormattedTotal() ); $this->assertSame($this->item->getFormattedTotal(), $this->item->formattedTotal); $this->assertSame($this->item->price * $this->item->quantity, $this->item->getSubtotal()); $this->assertSame($this->item->getSubtotal(), $this->item->subtotal); $this->assertSame( - Number::currency($this->item->subtotal, $this->item->itemable->currency), + (new Currency($this->item->subtotal, $this->item->itemable->currency))->format(), $this->item->getFormattedSubtotal() ); $this->assertSame($this->item->getFormattedSubtotal(), $this->item->formattedSubtotal); diff --git a/tests/Models/ShippingTest.php b/tests/Models/ShippingTest.php index eb39189f..5b9106ce 100644 --- a/tests/Models/ShippingTest.php +++ b/tests/Models/ShippingTest.php @@ -7,11 +7,11 @@ use Cone\Bazar\Models\Cart; use Cone\Bazar\Models\Order; use Cone\Bazar\Models\Shipping; +use Cone\Bazar\Support\Currency; use Cone\Bazar\Support\Facades\Shipping as ShippingManager; use Cone\Bazar\Support\Facades\Tax; use Cone\Bazar\Tests\TestCase; use Cone\Bazar\Tests\User; -use Illuminate\Support\Number; class ShippingTest extends TestCase { @@ -88,7 +88,8 @@ public function testt_is_taxable(): void $this->assertInstanceOf(Taxable::class, $this->shipping); $this->assertSame($this->shipping->price * 0.1, $this->shipping->tax); $this->assertSame( - Number::currency($this->shipping->tax, $this->shipping->shippable->currency), $this->shipping->getFormattedTax() + (new Currency($this->shipping->tax, $this->shipping->shippable->currency))->format(), + $this->shipping->getFormattedTax() ); $this->assertSame($this->shipping->getFormattedTax(), $this->shipping->formattedTax); } @@ -101,14 +102,14 @@ public function testt_has_total_attribute(): void ); $this->assertSame($this->shipping->getTotal(), $this->shipping->total); $this->assertSame( - Number::currency($this->shipping->total, $this->shipping->shippable->currency), + (new Currency($this->shipping->total, $this->shipping->shippable->currency))->format(), $this->shipping->getFormattedTotal() ); $this->assertSame($this->shipping->getFormattedTotal(), $this->shipping->formattedTotal); $this->assertSame($this->shipping->cost, $this->shipping->getSubtotal()); $this->assertSame($this->shipping->getSubtotal(), $this->shipping->subtotal); $this->assertSame( - Number::currency($this->shipping->subtotal, $this->shipping->shippable->currency), + (new Currency($this->shipping->subtotal, $this->shipping->shippable->currency))->format(), $this->shipping->getFormattedSubtotal() ); $this->assertSame($this->shipping->getFormattedSubtotal(), $this->shipping->formattedSubtotal);