abather / mini-accounting
为任何模型创建账户以便进行提款和存款。
Requires
- php: ^8.1
- illuminate/contracts: ^10.0
- laravel/framework: ^10.10
- spatie/laravel-package-tools: ^1.14.0
Requires (Dev)
- larastan/larastan: ^2.0.1
- laravel/pint: ^1.0
- nunomaduro/collision: ^7.8
- orchestra/testbench: ^8.18
- pestphp/pest: ^2.20
- pestphp/pest-plugin-arch: ^2.0
- pestphp/pest-plugin-laravel: ^2.0
- phpstan/extension-installer: ^1.1
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.0
README
将账户添加到您的模型并跟踪交易
要无缝地将账户功能集成到您的Laravel模型中并跟踪交易,请按照以下步骤操作。
安装
首先通过Composer安装此包
composer require abather/mini-accounting
然后,发布并运行迁移
php artisan vendor:publish --tag="mini-accounting-migrations"
php artisan migrate
您还可以发布配置文件
php artisan vendor:publish --tag="mini-accounting-config"
已发布的配置文件(config/mini-accounting.php)内容如下所示
return [ "prevent_duplication" => true, "currency_precision" => 2 ];
用法
此包链接两个实体:Accountable(具有账户的模型)和Referencable(触发账户存取的文档)。
Accountable
要使模型成为Accountable,请使用HasAccountMovement特质
<?php namespace App\Models; use Abather\MiniAccounting\Traits\HasAccountMovement; use Illuminate\Database\Eloquent\Model; class System extends Model { use HasAccountMovement; // Your code }
现在您可以通过引用任何引用模型从它存入或取出任何金额
$system->deposit("Description Of The Transaction", 350, $bill);
您还可以向任何交易提供备注或额外数据(JSON格式)
$system->deposit("Description Of The Transaction", 350, $bill, "Extra Notes", $json);
要获取模型当前余额
$system->balance
您还可以获取模型每月末的余额
$system->balanceAtEndOfMonth(10) // Returns the system balance at the end of month 10
您还可以为此函数传递年份,如果您不是今年其他年份,例如 balanceAtEndOfMonth(6, 1990)
您也可以获取任何给定年份的余额
$system->balanceAtEndOfYear() // Returns the system balance at the end of this year
作为月末余额,您可以指定年份 balanceAtEndOfYear(1990)
Referencable
使用Referencable特质和实现Referencable接口使任何模型成为可引用的
<?php namespace App\Models; use Abather\MiniAccounting\Contracts\Referencable; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Bill extends Model implements Referencable { use \Abather\MiniAccounting\Traits\Referencable; use HasFactory; public function defaultTransactions(): array { return []; } }
定义defaultTransactions(): array方法。此方法将在后面进行描述。类似于Accountable模型,您可以从可引用模型中存入和取出,同时影响不同的账户。例如,当用户从市场购买时,账单将把金额存入市场的账户,并从用户的账户中取出相同金额
$bill = Bill::first(); $bill->deposit("Deposit", $bill->amount, $bill->market); $bill->withdraw("Withdraw", $bill->amount, $bill->user);
假设您还有由账单引起的其他交易,例如佣金,您的代码将是
$bill = Bill::first(); $bill->deposit("Deposit", $bill->amount, $bill->market); $bill->withdraw("Withdraw", $bill->amount, $bill->user); $bill->withdraw("Withdraw", $bill->amount * 0.1, $bill->market); $bill->deposit("Deposit", $bill->amount * 0.1, $system);
为了简化,使用defaultTransactions方法为每个可引用模型定义默认交易
public function defaultTransactions(): array { return [ Withdraw::make($this, "description") ->setAccount(Account::make(\App\Models\User::class)->relationship("user")) ->setCalculation(Equal::make($this, "amount")), Deposit::make($this, "any description") ->setAccount(Account::make(\App\Models\Market::class)->relationship("market")) ->setCalculation(Equal::make($this, "amount")), Withdraw::make($this, "other description") ->setAccount(Account::make(\App\Models\Market::class)->relationship("market")) ->setCalculation(Percentage::make($this, "amount") ->factor(StaticFactor::make(10)) ), Deposit::make($this, "other description") ->setAccount(Account::make(\App\Models\System::class, System::first())) ->setCalculation(Percentage::make($this, "amount") ->factor(DynamicFactor::make($this, 'percentage')) ), ]; }
对于每个对象(无论是Deposit还是Withdraw),设置受影响的账户和确定交易金额的计算方法。
- 您可以使用元数据与交易一起使用
$transaction->data = [ 'foo' => 'bar' ]; $transaction->data // ['foo' => 'bar']
- 您还可以通过
->setNote("note")向交易添加备注
账户
以三种方式引用所需的账户:从当前模型建立直接关系,使用当前模型的外键,或提供任何ID进行引用
Account::make(\App\Models\Market::class)->relationship("market");
在此示例中,在make方法中指定模型;在计算过程中,账户将是与当前实体链接的市场($bill->market)。其他设置包括
variable('market_id'):提供任何指向实体的键($bill->market_id)。static(3):锁定ID为3的记录。此外,传递第二个参数到make()方法以指定引用的实体
Account::make(\App\Models\Market::class, $this->market)
这样,您就不需要提供任何其他函数。
计算
对于计算,请使用以下对象
Abather\MiniAccounting\Objects\Calculations\EqualAbather\MiniAccounting\Objects\Calculations\SubtractionAbather\MiniAccounting\Objects\Calculations\AdditionAbather\MiniAccounting\Objects\Calculations\Percentage
对于每个对象,提供 make($resource, $attribute)。在我们之前的例子中,make($this, "amount") 表示计算将在 $bill->amount 上进行。除了 Equal 之外,您还必须定义 factor,这是每个方程的另一方。《factor》可以是动态值或静态值。
StaticFactor::make(10):方程的另一边是 10(例如,$bill->amount - 10)。DynamicFactor::make($this, 'percentage'):方程的另一边是$bill->percentage。
定义 defaultTransactions() 后,通过调用 executeDefaultTransactions() 来使用它。您可以定义尽可能多的 transactions 方法。请注意,每个方法的名字应以 Transactions 结尾,并且您可以通过在方法名前加上 "execute" 来运行这些交易(例如,cancelTransactions() 使用 executeCancelTransactions() 来运行交易)。
注意:如果您在 Accountable 或 Referencable 模型中使用 __call($method, $parameters),请添加以下行
您的 Accountable 或 Referencable 模型中,请添加以下行
- Accountable
public function __call($method, $parameters) { if (in_array($method, ["deposit", 'withdraw'])) { return $this->createAccountMovement(strtoupper($method), ...$parameters); } // Your code ... return parent::__call($method, $parameters); }
- Referencable
public function __call($method, $parameters) { if (str_starts_with($method, "execute") && str_ends_with($method, "Transactions")) { $method = str_replace("execute", "", $method); $method = lcfirst($method); return $this->executeTransactions($method); } if (in_array($method, ["deposit", 'withdraw'])) { return $this->createAccountMovement(strtoupper($method), ...$parameters); } // Your code ... return parent::__call($method, $parameters); }
本文档适用于 Laravel 包,旨在通过将模型与其账户链接来增强模型的功能。此外,它还建立了与其他模型之间的联系,用作参考文档,例如账单或退款。
测试
composer test
变更日志
有关最近更改的更多信息,请参阅 变更日志
贡献
有关详细信息,请参阅 贡献指南
鸣谢
许可
MIT 许可证(MIT)。有关更多信息,请参阅 许可文件