$journal->id, 'credit' => $credit ? $credit->getAmount():null, 'debit' => $debit ? $debit->getAmount():null, 'currency' => config('phpvms.currency'), 'memo' => $memo, 'post_date' => $post_date ?: Carbon::now(), 'transaction_group' => $transaction_group, ]; if($reference !== null) { $attrs['ref_class'] = \get_class($reference); $attrs['ref_class_id'] = $reference->id; } try { $transaction = $this->create($attrs); } catch (ValidatorException $e) { throw $e; } # Adjust the balance on the journal if($credit) { $journal->balance->add($credit); } if($debit) { $journal->balance->subtract($debit); } $journal->save(); $journal->refresh(); return $transaction; } /** * @param Journal $journal * @param Carbon|null $date * @return Money * @throws \UnexpectedValueException * @throws \InvalidArgumentException */ public function getBalance(Journal $journal=null, Carbon $date=null) { if(!$date) { $date = Carbon::now(); } $credit = $this->getCreditBalanceBetween($date, $journal); $debit = $this->getDebitBalanceBetween($date, $journal); return $credit->subtract($debit); } /** * Get the credit only balance of the journal based on a given date. * @param Journal $journal * @param Carbon $date * @return Money * @throws \UnexpectedValueException * @throws \InvalidArgumentException */ public function getCreditBalanceBetween( Carbon $date, Journal $journal=null, Carbon $start_date=null ): Money { $where = [ ['post_date', '<=', $date] ]; if($journal) { $where['journal_id'] = $journal->id; } if ($start_date) { $where[] = ['post_date', '>=', $start_date]; } $balance = $this ->findWhere($where, ['id', 'credit']) ->sum('credit') ?: 0; return new Money($balance); } /** * @param Journal $journal * @param Carbon $date * @return Money * @throws \UnexpectedValueException * @throws \InvalidArgumentException */ public function getDebitBalanceBetween( Carbon $date, Journal $journal=null, Carbon $start_date=null ): Money { $where = [ ['post_date', '<=', $date] ]; if ($journal) { $where['journal_id'] = $journal->id; } if($start_date) { $where[] = ['post_date', '>=', $start_date]; } $balance = $this ->findWhere($where, ['id', 'debit']) ->sum('debit') ?: 0; return new Money($balance); } /** * Return all transactions for a given object * @param $object * @return array * @throws \UnexpectedValueException * @throws \InvalidArgumentException */ public function getAllForObject($object) { $transactions = $this->findWhere([ 'ref_class' => \get_class($object), 'ref_class_id' => $object->id, ]); return [ 'credits' => new Money($transactions->sum('credit')), 'debits' => new Money($transactions->sum('debit')), 'transactions' => $transactions, ]; } }