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; } }