登录
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
namespace app\common\traits;
|
||||
|
||||
use app\common\model\VehMoneyValue;
|
||||
use support\Db;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
trait HasMoneyJournal
|
||||
{
|
||||
/**
|
||||
* 【抽象方法】必须由使用该 trait 的模型实现
|
||||
* 返回当前模型对应的金额“业务场景”标识
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected static function moneyObjectScene(): string;
|
||||
|
||||
/** 所有关联金额记录(append-only 全部历史) */
|
||||
public function moneyJournal(): HasMany
|
||||
{
|
||||
return $this->hasMany(VehMoneyValue::class, 'object_id')
|
||||
->where('object_scene', static::moneyObjectScene());
|
||||
}
|
||||
|
||||
/** 取某费项的“最新记录”(按时间/id 倒序) */
|
||||
public function moneyLatest(string $field): ?VehMoneyValue
|
||||
{
|
||||
return $this->moneyJournal()
|
||||
->where('field', $field)
|
||||
->orderByDesc('created_at')
|
||||
->orderByDesc('id')
|
||||
->first();
|
||||
}
|
||||
|
||||
/** 追加一行金额 */
|
||||
public function addMoney(string $field, string $currency, $amount, ?string $rate = null, ?string $remark = null): VehMoneyValue
|
||||
{
|
||||
$now = time();
|
||||
/** @var VehMoneyValue $row */
|
||||
$row = $this->moneyJournal()->create([
|
||||
'object_scene' => static::moneyObjectScene(),
|
||||
'object_id' => $this->id,
|
||||
'field' => $field,
|
||||
'currency' => strtoupper($currency),
|
||||
'amount' => (string)$amount,
|
||||
'exchange_rate' => $rate,
|
||||
'remark' => $remark,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
]);
|
||||
return $row;
|
||||
}
|
||||
|
||||
/** 批量追加:['unit_price'=>['currency'=>'USD','amount'=>'2199.00','rate'=>'7.2','remark'=>'...'], ...] */
|
||||
public function addMoneyBatch(array $payload): array
|
||||
{
|
||||
return Db::transaction(function () use ($payload) {
|
||||
$out = [];
|
||||
foreach ($payload as $field => $cfg) {
|
||||
$out[$field] = $this->addMoney(
|
||||
$field,
|
||||
$cfg['currency'] ?? 'CNY',
|
||||
$cfg['amount'] ?? '0.00',
|
||||
$cfg['rate'] ?? null,
|
||||
$cfg['remark'] ?? null
|
||||
);
|
||||
}
|
||||
return $out;
|
||||
});
|
||||
}
|
||||
|
||||
/** 把若干费项按各自汇率换到结算币并求和(无 rate 的跳过) */
|
||||
public function sumToSettlement(array $fields, int $scale = 2): string
|
||||
{
|
||||
$sum = '0.00';
|
||||
foreach ($fields as $f) {
|
||||
$row = $this->moneyLatest($f);
|
||||
if ($row) {
|
||||
$v = $row->amountInSettlement($scale);
|
||||
if ($v !== null) $sum = bcadd($sum, $v, $scale);
|
||||
}
|
||||
}
|
||||
return $sum;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user