abather/mini-accounting

为任何模型创建账户以便进行提款和存款。

1.0.0 2023-12-21 07:07 UTC

This package is auto-updated.

Last update: 2024-09-24 07:42:32 UTC


README

Latest Version on Packagist Total Downloads

将账户添加到您的模型并跟踪交易

要无缝地将账户功能集成到您的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() 来运行交易)。

注意:如果您在 AccountableReferencable 模型中使用 __call($method, $parameters),请添加以下行

您的 AccountableReferencable 模型中,请添加以下行

  • 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)。有关更多信息,请参阅 许可文件