2018-03-17 09:12:56 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Services\Finance;
|
|
|
|
|
2019-07-16 03:44:31 +08:00
|
|
|
use App\Contracts\Service;
|
2018-03-17 09:12:56 +08:00
|
|
|
use App\Models\Airline;
|
|
|
|
use App\Models\Enums\ExpenseType;
|
|
|
|
use App\Models\Expense;
|
|
|
|
use App\Models\JournalTransaction;
|
|
|
|
use App\Repositories\JournalRepository;
|
2019-11-27 22:19:20 +08:00
|
|
|
use App\Services\FinanceService;
|
2018-03-17 09:12:56 +08:00
|
|
|
use App\Support\Money;
|
2019-11-27 22:19:20 +08:00
|
|
|
use Carbon\Carbon;
|
|
|
|
use Illuminate\Support\Facades\Log;
|
2018-03-17 09:12:56 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Process all of the daily expenses and charge them
|
|
|
|
*/
|
2018-03-20 09:50:40 +08:00
|
|
|
class RecurringFinanceService extends Service
|
2018-03-17 09:12:56 +08:00
|
|
|
{
|
2019-11-27 22:19:20 +08:00
|
|
|
private $financeSvc;
|
2018-03-17 09:12:56 +08:00
|
|
|
private $journalRepo;
|
|
|
|
|
2019-11-27 22:19:20 +08:00
|
|
|
public function __construct(JournalRepository $journalRepo, FinanceService $financeSvc)
|
2018-03-17 09:12:56 +08:00
|
|
|
{
|
2019-11-27 22:19:20 +08:00
|
|
|
$this->financeSvc = $financeSvc;
|
2018-03-17 09:12:56 +08:00
|
|
|
$this->journalRepo = $journalRepo;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determine the journal to charge to, otherwise, it's charged
|
|
|
|
* to every airline journal
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-17 09:12:56 +08:00
|
|
|
* @param Expense $expense
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-17 09:12:56 +08:00
|
|
|
* @return \Generator
|
|
|
|
*/
|
|
|
|
protected function findJournals(Expense $expense)
|
|
|
|
{
|
2018-03-20 09:50:40 +08:00
|
|
|
if ($expense->airline_id) {
|
2018-03-17 09:12:56 +08:00
|
|
|
$airline = Airline::find($expense->airline_id)->first(['id', 'icao']);
|
2018-03-20 09:50:40 +08:00
|
|
|
Log::info('Charging to '.$airline->icao);
|
2018-03-17 09:12:56 +08:00
|
|
|
yield $airline->journal;
|
|
|
|
} else {
|
|
|
|
$airlines = Airline::all(['id', 'icao']);
|
2018-03-20 09:50:40 +08:00
|
|
|
foreach ($airlines as $airline) {
|
|
|
|
Log::info('Charging to '.$airline->icao);
|
2018-03-17 09:12:56 +08:00
|
|
|
yield $airline->journal;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the name of the transaction group from the expense
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-17 09:12:56 +08:00
|
|
|
* @param Expense $expense
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-17 09:12:56 +08:00
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
protected function getMemoAndGroup(Expense $expense): array
|
|
|
|
{
|
|
|
|
$klass = 'Expense';
|
2018-04-02 03:32:01 +08:00
|
|
|
if ($expense->ref_model) {
|
|
|
|
$ref = explode('\\', $expense->ref_model);
|
2018-03-17 09:12:56 +08:00
|
|
|
$klass = end($ref);
|
2018-04-02 11:26:20 +08:00
|
|
|
$obj = $expense->getReferencedObject();
|
2018-03-17 09:12:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if ($klass === 'Airport') {
|
2018-04-02 03:32:01 +08:00
|
|
|
$memo = "Airport Expense: {$expense->name} ({$expense->ref_model_id})";
|
|
|
|
$transaction_group = "Airport: {$expense->ref_model_id}";
|
2018-03-17 09:12:56 +08:00
|
|
|
} elseif ($klass === 'Subfleet') {
|
|
|
|
$memo = "Subfleet Expense: {$expense->name}";
|
|
|
|
$transaction_group = "Subfleet: {$expense->name}";
|
|
|
|
} elseif ($klass === 'Aircraft') {
|
|
|
|
$memo = "Aircraft Expense: {$expense->name} ({$obj->name})";
|
|
|
|
$transaction_group = "Aircraft: {$expense->name} ({$obj->name}-{$obj->registration})";
|
|
|
|
} else {
|
|
|
|
$memo = "Expense: {$expense->name}";
|
|
|
|
$transaction_group = "Expense: {$expense->name}";
|
|
|
|
}
|
|
|
|
|
|
|
|
return [$memo, $transaction_group];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run all of the daily expense/financials
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2019-11-27 22:19:20 +08:00
|
|
|
* @param string $type
|
2018-08-27 00:40:04 +08:00
|
|
|
*
|
2018-03-17 09:12:56 +08:00
|
|
|
* @throws \Prettus\Validator\Exceptions\ValidatorException
|
|
|
|
*/
|
2018-03-20 09:50:40 +08:00
|
|
|
public function processExpenses($type = ExpenseType::DAILY): void
|
2018-03-17 09:12:56 +08:00
|
|
|
{
|
|
|
|
$expenses = Expense::where(['type' => $type])->get();
|
|
|
|
|
|
|
|
$tag = 'expense_recurring';
|
2018-03-20 09:50:40 +08:00
|
|
|
if ($type === ExpenseType::DAILY) {
|
2018-03-17 09:12:56 +08:00
|
|
|
$tag = 'expenses_daily';
|
|
|
|
} elseif ($type === ExpenseType::MONTHLY) {
|
2019-11-27 22:19:20 +08:00
|
|
|
$tag = 'expenses_monthly';
|
2018-03-17 09:12:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var $expenses Expense[]
|
|
|
|
*/
|
|
|
|
foreach ($expenses as $expense) {
|
2018-08-27 00:40:04 +08:00
|
|
|
// Apply the expenses to the appropriate journals
|
2018-03-17 09:12:56 +08:00
|
|
|
$journals = $this->findJournals($expense);
|
2018-03-20 09:50:40 +08:00
|
|
|
foreach ($journals as $journal) {
|
2018-03-17 09:12:56 +08:00
|
|
|
$amount = $expense->amount;
|
|
|
|
|
2018-08-27 00:40:04 +08:00
|
|
|
// Has this expense already been charged? Check
|
|
|
|
// against this specific journal, on today
|
2018-03-17 09:12:56 +08:00
|
|
|
$w = [
|
2018-03-20 09:50:40 +08:00
|
|
|
'journal_id' => $journal->id,
|
2018-04-02 03:32:01 +08:00
|
|
|
'ref_model' => Expense::class,
|
|
|
|
'ref_model_id' => $expense->id,
|
2018-03-17 09:12:56 +08:00
|
|
|
];
|
|
|
|
|
2018-03-18 11:20:08 +08:00
|
|
|
$found = JournalTransaction::where($w)
|
2019-11-27 22:19:20 +08:00
|
|
|
->whereDate('post_date', '=', Carbon::now('UTC')->toDateString())
|
2018-03-18 11:20:08 +08:00
|
|
|
->count(['id']);
|
|
|
|
|
2018-03-20 09:50:40 +08:00
|
|
|
if ($found > 0) {
|
2018-03-17 09:12:56 +08:00
|
|
|
Log::info('Expense "'.$expense->name.'" already charged for today, skipping');
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
[$memo, $ta_group] = $this->getMemoAndGroup($expense);
|
|
|
|
|
2019-11-27 22:19:20 +08:00
|
|
|
$this->financeSvc->debitFromJournal(
|
2018-03-17 09:12:56 +08:00
|
|
|
$journal,
|
|
|
|
Money::createFromAmount($amount),
|
|
|
|
$expense,
|
|
|
|
$memo,
|
|
|
|
$ta_group,
|
|
|
|
$tag
|
|
|
|
);
|
|
|
|
|
2018-03-20 09:50:40 +08:00
|
|
|
Log::info('Expense memo: "'.$memo.'"; group: "'.$ta_group.'" charged!');
|
2018-03-17 09:12:56 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|