origami/money

为Laravel项目提供的货币处理和格式化包

2.1.0 2024-05-28 12:20 UTC

This package is auto-updated.

Last update: 2024-08-31 13:16:40 UTC


README

本包是Laravel项目的货币助手,也是moneyphp/money的包装器。

安装

通过Composer安装此包。

composer require origami/money

要求

  • 本包旨在与Laravel >= 8协同工作。
  • 需要PHP扩展ext-intl

配置

首先,发布默认配置。

php artisan vendor:publish --tag="money-config"

这将向config/money.php添加一个新的配置文件,其中包含一个default_currency值。

使用方法

值对象

Origami\Money\Money值对象类是一个助手,它使用来自moneyphp/moneyMoney\Money对象。这使我们能够添加一些辅助方法(例如格式化)并对我们的实现有更明确的观点。由于这是一个final class,该类不扩展Money\Money - 而是使用一个内部属性。

Money\Money类似,每个Origami\Money\Money对象都需要一个

  • $amount,以货币的最小单位(例如分)表示
  • $currency,货币的ISO-4217 3位代码。

例如

$money = new Origami\Money\Money(100, 'GBP') // £1
$money = new Origami\Money\Money(50000, 'USD') // $500
$money = Origami\Money\Money::make(1000000, 'USD') // $10,000

您也可以传递一个moneyphp对象

$currency = new Money\Currency('GBP');
$base = new Money\Money(100, $currency);
$money = new Origami\Money\Money($base, $currency);

可用方法

实例

Money\Money对象创建实例

Origami\Money\Money::instance(new Money\Money(500, new Money\Currency('GBP')));

复制

创建实例的副本

$money = new Origami\Money\Money(500, 'GBP'); // £5
$another = $money->copy();
$andAnother = $money->clone(); // Alias for above

asBase

获取底层的Money\Money对象

$money = new Origami\Money\Money(500, 'GBP'); // £5
$base = $money->asBase(); // Money\Money

isSameCurrency

$gbp = new Origami\Money\Money(500, 'GBP'); // £5
$usd = new Origami\Money\Money(500, 'USD'); // $5
$money->isSameCurrency(); // false

equals

$first = new Origami\Money\Money(500, 'GBP'); // £5
$second = Origami\Money\Money::make(500, 'GBP'); // £5
$money->equals(); // true

greaterThan / gt

$first = new Origami\Money\Money(500, 'GBP'); // £5
$second = new Origami\Money\Money(600, 'GBP'); // £6
$second->greaterThan($first); // true
$second->gt($first); // Alias for above

greaterThanOrEqual / gte

$first = new Origami\Money\Money(500, 'GBP'); // £5
$second = new Origami\Money\Money(500, 'GBP'); // £5
$second->greaterThanOrEqual($first); // true
$second->gte($first); // Alias for above

lessThan / lt

$first = new Origami\Money\Money(500, 'GBP'); // £5
$second = new Origami\Money\Money(600, 'GBP'); // £6
$second->lessThan($first); // false
$second->lt($first); // Alias for above

lessThanOrEqual / lte

$first = new Origami\Money\Money(500, 'GBP'); // £5
$second = new Origami\Money\Money(500, 'GBP'); // £5
$second->lessThanOrEqual($first); // true
$second->lte($first); // Alias for above

isZero

$first = new Origami\Money\Money(500, 'GBP'); // £5
$zero = new Origami\Money\Money(0, 'GBP'); // £0
$first->isZero(); // false
$zero->isZero(); // true

isPositive

$first = new Origami\Money\Money(500, 'GBP'); // £5
$first->isPositive(); // true

isNegative

$first = new Origami\Money\Money(500, 'GBP'); // £5
$first->isNegative(); // false

percentageOf

$first = new Origami\Money\Money(500, 'GBP'); // £5
$second = new Origami\Money\Money(1000, 'GBP'); // £10
$first->percentageOf($second); // 50

$overflow参数设置为false以避免超过100

$first = new Origami\Money\Money(1000, 'GBP'); // £10
$second = new Origami\Money\Money(500, 'GBP'); // £5
$first->percentageOf($second, false); // 100

getAmount

返回integer

$money = new Origami\Money\Money(500, 'GBP'); // £5
$amount = $money->getAmount(); // 500

getCurrency

返回Money\Money货币值对象

$money = new Origami\Money\Money(500, 'GBP'); // £5
$currency = $money->getCurrency(); // `Money\Currency('GBP')`

getCurrencyCode

$money = new Origami\Money\Money(500, 'GBP'); // £5
$currency = $money->getCurrencyCode(); // "GBP"

add

$first = new Origami\Money\Money(500, 'GBP'); // £5
$second = new Origami\Money\Money(400, 'GBP'); // £4
$first->add($second); // `Origami\Money(900, 'GBP')`

subtract

$first = new Origami\Money\Money(500, 'GBP'); // £5
$second = new Origami\Money\Money(400, 'GBP'); // £4
$first->add($second); // `Origami\Money(100, 'GBP')`

multiply

$money = new Origami\Money\Money(500, 'GBP'); // £5
$money->multiply(2); // `Origami\Money(1000, 'GBP')`

divide

$money = new Origami\Money\Money(500, 'GBP'); // £5
$money->divide(2); // `Origami\Money(250, 'GBP')`

mod

模运算

$money = new Origami\Money\Money(830, 'GBP'); // £8.30
$divisor = new Origami\Money\Money(300, 'GBP'); // £3.00
$money->add($divisor); // `Origami\Money(230, 'GBP')`

ratioOf

提供与另一个Money对象比较的比率

$three = new Origami\Money\Money(300, 'GBP'); // £3
$six = new Origami\Money\Money(600, 'GBP'); // £6
$three->ratioOf($six); // 0.5

absolute

$money = new Origami\Money\Money(-500, 'GBP'); // -£5
$money->absolute(); // `Origami\Money(500, 'GBP')`

negative

$money = new Origami\Money\Money(500, 'GBP'); // £5
$money->negative(); // `Origami\Money(-500, 'GBP')`

格式化

字符串

使用Intl格式化器进行货币符号和分隔符。

$money = new Origami\Money\Money(500, 'GBP');
$money->format(); // Outputs: £5.00
(string) $money; // Outputs: £5.00 (uses `__toString()`)
app('origami-money.formatter')->format($money) // Outputs: £5.00

字符串整洁(无尾随零)

只有当小数位为零时,才删除尾随零。

$money = new Origami\Money\Money(500, 'GBP');
$money->formatNeat(); // Outputs: £5
app('origami-money.formatter')->formatNeat($money) // Outputs: £5

小数

$money = new Origami\Money\Money(500, 'GBP');
$money->formatDecimal(); // Outputs: 5.00
$money->toDecimal(); // Alias for above
app('origami-money.formatter')->formatDecimal($money) // Outputs: 5.00

Blade指令

您可以在Blade视图中使用以下指令

@money($money)
// same as `$money->format()`
@moneyNeat($money)
// same as `$money->formatNeat()`

Eloquent属性转换

您很可能会在Eloquent模型中存储您的货币值。本包提供了一个用于您的自定义Laravel转换Origami\Money\Casts\Money

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Origami\Money\Casts\Money;

class Invoice extends Model
{
    protected $fillable = ['description','total', 'currency'];

    protected $casts = ['total' => Money::class];
}

在上面的示例中,您可以使用货币对象设置total属性

$currency = 'USD';
$invoice = new Invoice(['currency' => $currency, 'total' => new Origami\Money\Money(70000, $currency)]);

在上面的示例中,$invoice->total将是一个实例

Origami\Money\Money {
  -money: Money\Money {
    -amount: "70000",
    -currency: Money\Currency {
      -code: "GBP",
    },
  },
}

您还可以在设置转换属性时使用浮点数、字符串或整数值 - 例如来自控制器。

$input = [
    'currency' => 'GBP',
    'total' => '10.50',
];

$invoice = new Invoice($input);

重要:此操作将使用Origami\Money\MoneyHelper@input方法(最终使用Origami\Money\MoneyHelper@adjustAmount),假设金额以美元或英镑等给出,将其转换为货币的最小单位。

您的模型应该具有一个 currency 属性或者一个 getCurrencyCode 方法,该方法返回 ISO-4217 代码。否则,此包将默认使用配置文件中设置的 default_currency

因此上述内容转换为

Origami\Money\Money {
  -money: Money\Money {
    -amount: "1050",
    -currency: Money\Currency {
      -code: "GBP",
    },
  },
}

如果您的控制器或其他方法已经期望用户输入的是分而不是美元,您应该不使用强制类型转换,或者改为传递一个 Origami\Money\Money 对象而不是数值金额(这将进行转换)。

版本

  • v2.* - 版本 2 对包进行了破坏性重构,以包括更好的格式化和辅助值对象类。
  • v1.-* - 版本 1 提供了基本的格式化,并与 Laravel 6-9 兼容。

作者

许可证

查看许可证