$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; } $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 Carbon $date * @param Journal $journal * @param Carbon|null $start_date * @param null $transaction_group * @return Money */ public function getCreditBalanceBetween( Carbon $date, Journal $journal=null, Carbon $start_date=null, $transaction_group=null ): Money { $where = [ ['post_date', '<=', $date] ]; if($journal) { $where['journal_id'] = $journal->id; } if ($start_date) { $where[] = ['post_date', '>=', $start_date]; } if ($transaction_group) { $where['transaction_group'] = $transaction_group; } $balance = $this ->findWhere($where, ['id', 'credit']) ->sum('credit') ?: 0; return new Money($balance); } /** * @param Carbon $date * @param Journal $journal * @param Carbon|null $start_date * @param null $transaction_group * @return Money */ public function getDebitBalanceBetween( Carbon $date, Journal $journal=null, Carbon $start_date=null, $transaction_group=null ): Money { $where = [ ['post_date', '<=', $date] ]; if ($journal) { $where['journal_id'] = $journal->id; } if($start_date) { $where[] = ['post_date', '>=', $start_date]; } if($transaction_group) { $where['transaction_group'] = $transaction_group; } $balance = $this ->findWhere($where, ['id', 'debit']) ->sum('debit') ?: 0; return new Money($balance); } /** * Return all transactions for a given object * @param $object * @param null $journal * @return array * @throws \UnexpectedValueException * @throws \InvalidArgumentException */ public function getAllForObject($object, $journal=null) { $where = [ 'ref_class' => \get_class($object), 'ref_class_id' => $object->id, ]; if($journal) { $where['journal_id'] = $journal->id; } $transactions = $this->whereOrder($where, [ 'credit' => 'desc', 'debit' => 'desc' ])->get(); return [ 'credits' => new Money($transactions->sum('credit')), 'debits' => new Money($transactions->sum('debit')), 'transactions' => $transactions, ]; } /** * Delete all transactions for a given object * @param $object * @param null $journal * @return void */ public function deleteAllForObject($object, $journal = null) { $where = [ 'ref_class' => \get_class($object), 'ref_class_id' => $object->id, ]; if ($journal) { $where['journal_id'] = $journal->id; } $this->deleteWhere($where); } }