2018-03-01 08:01:32 +08:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Based on https://github.com/scottlaurent/accounting
|
|
|
|
* With modifications for phpVMS
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace App\Models;
|
|
|
|
|
2019-07-16 03:44:31 +08:00
|
|
|
use App\Contracts\Model;
|
2018-03-01 08:01:32 +08:00
|
|
|
use App\Support\Money;
|
|
|
|
use Carbon\Carbon;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class Journal
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-20 09:50:40 +08:00
|
|
|
* @property mixed id
|
|
|
|
* @property Money $balance
|
|
|
|
* @property string $currency
|
|
|
|
* @property Carbon $updated_at
|
|
|
|
* @property Carbon $post_date
|
|
|
|
* @property Carbon $created_at
|
2018-03-06 09:55:48 +08:00
|
|
|
* @property \App\Models\Enums\JournalType type
|
2018-03-20 09:50:40 +08:00
|
|
|
* @property mixed morphed_type
|
|
|
|
* @property mixed morphed_id
|
2018-03-01 08:01:32 +08:00
|
|
|
*/
|
2018-03-20 09:50:40 +08:00
|
|
|
class Journal extends Model
|
2018-03-01 08:01:32 +08:00
|
|
|
{
|
|
|
|
protected $table = 'journals';
|
|
|
|
|
2018-03-21 08:40:19 +08:00
|
|
|
protected $fillable = [
|
2018-03-06 09:55:48 +08:00
|
|
|
'ledger_id',
|
|
|
|
'journal_type',
|
|
|
|
'balance',
|
|
|
|
'currency',
|
|
|
|
'morphed_type',
|
|
|
|
'morphed_id',
|
|
|
|
];
|
|
|
|
|
2018-03-01 08:01:32 +08:00
|
|
|
protected $dates = [
|
2018-03-19 09:37:35 +08:00
|
|
|
'created_at',
|
2018-03-01 08:01:32 +08:00
|
|
|
'deleted_at',
|
2018-08-27 00:40:04 +08:00
|
|
|
'updated_at',
|
2018-03-01 08:01:32 +08:00
|
|
|
];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get all of the morphed models.
|
|
|
|
*/
|
|
|
|
public function morphed()
|
|
|
|
{
|
|
|
|
return $this->morphTo();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Relationship
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-01 08:01:32 +08:00
|
|
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
|
|
*/
|
|
|
|
public function ledger()
|
|
|
|
{
|
|
|
|
return $this->belongsTo(Ledger::class);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Relationship
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-01 08:01:32 +08:00
|
|
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
|
|
|
*/
|
|
|
|
public function transactions()
|
|
|
|
{
|
|
|
|
return $this->hasMany(JournalTransaction::class);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $currency
|
|
|
|
*/
|
|
|
|
public function setCurrency($currency)
|
|
|
|
{
|
|
|
|
$this->currency = $currency;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Ledger $ledger
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-01 08:01:32 +08:00
|
|
|
* @return Journal
|
|
|
|
*/
|
|
|
|
public function assignToLedger(Ledger $ledger)
|
|
|
|
{
|
|
|
|
$ledger->journals()->save($this);
|
2018-03-20 09:50:40 +08:00
|
|
|
|
2018-03-01 08:01:32 +08:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @throws \UnexpectedValueException
|
|
|
|
* @throws \InvalidArgumentException
|
|
|
|
*/
|
|
|
|
public function resetCurrentBalances()
|
|
|
|
{
|
|
|
|
$this->balance = $this->getBalance();
|
|
|
|
$this->save();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param $value
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-01 08:01:32 +08:00
|
|
|
* @throws \UnexpectedValueException
|
|
|
|
* @throws \InvalidArgumentException
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
|
|
|
* @return Money
|
2018-03-01 08:01:32 +08:00
|
|
|
*/
|
|
|
|
public function getBalanceAttribute($value): Money
|
|
|
|
{
|
|
|
|
return new Money($value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param $value
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-01 08:01:32 +08:00
|
|
|
* @throws \UnexpectedValueException
|
|
|
|
* @throws \InvalidArgumentException
|
|
|
|
*/
|
|
|
|
public function setBalanceAttribute($value): void
|
|
|
|
{
|
|
|
|
$value = ($value instanceof Money)
|
|
|
|
? $value
|
|
|
|
: new Money($value);
|
|
|
|
|
2018-03-20 09:50:40 +08:00
|
|
|
$this->attributes['balance'] = $value ? (int) $value->getAmount() : null;
|
2018-03-01 08:01:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Journal $object
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-01 08:01:32 +08:00
|
|
|
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
|
|
|
*/
|
|
|
|
public function transactionsReferencingObjectQuery($object)
|
|
|
|
{
|
|
|
|
return $this
|
|
|
|
->transactions()
|
2018-04-02 03:32:01 +08:00
|
|
|
->where('ref_model', \get_class($object))
|
|
|
|
->where('ref_model_id', $object->id);
|
2018-03-01 08:01:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the credit only balance of the journal based on a given date.
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-01 08:01:32 +08:00
|
|
|
* @param Carbon $date
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-01 08:01:32 +08:00
|
|
|
* @throws \UnexpectedValueException
|
|
|
|
* @throws \InvalidArgumentException
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
|
|
|
* @return Money
|
2018-03-01 08:01:32 +08:00
|
|
|
*/
|
|
|
|
public function getCreditBalanceOn(Carbon $date)
|
|
|
|
{
|
|
|
|
$balance = $this->transactions()
|
|
|
|
->where('post_date', '<=', $date)
|
|
|
|
->sum('credit') ?: 0;
|
|
|
|
|
|
|
|
return new Money($balance);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the balance of the journal based on a given date.
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-01 08:01:32 +08:00
|
|
|
* @param Carbon $date
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-01 08:01:32 +08:00
|
|
|
* @throws \UnexpectedValueException
|
|
|
|
* @throws \InvalidArgumentException
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
|
|
|
* @return Money
|
2018-03-01 08:01:32 +08:00
|
|
|
*/
|
|
|
|
public function getBalanceOn(Carbon $date)
|
|
|
|
{
|
|
|
|
return $this->getCreditBalanceOn($date)
|
2018-03-20 09:50:40 +08:00
|
|
|
->subtract($this->getDebitBalanceOn($date));
|
2018-03-01 08:01:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the balance of the journal as of right now, excluding future transactions.
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-01 08:01:32 +08:00
|
|
|
* @throws \UnexpectedValueException
|
|
|
|
* @throws \InvalidArgumentException
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
|
|
|
* @return Money
|
2018-03-01 08:01:32 +08:00
|
|
|
*/
|
|
|
|
public function getCurrentBalance()
|
|
|
|
{
|
|
|
|
return $this->getBalanceOn(Carbon::now());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the balance of the journal. This "could" include future dates.
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-01 08:01:32 +08:00
|
|
|
* @throws \UnexpectedValueException
|
|
|
|
* @throws \InvalidArgumentException
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
|
|
|
* @return Money
|
2018-03-01 08:01:32 +08:00
|
|
|
*/
|
|
|
|
public function getBalance()
|
|
|
|
{
|
|
|
|
$balance = $this
|
|
|
|
->transactions()
|
|
|
|
->sum('credit') - $this->transactions()->sum('debit');
|
|
|
|
|
|
|
|
return new Money($balance);
|
|
|
|
}
|
|
|
|
}
|