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\Equal
Abather\MiniAccounting\Objects\Calculations\Subtraction
Abather\MiniAccounting\Objects\Calculations\Addition
Abather\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)。有关更多信息,请参阅 许可文件