financeSvc = $financeSvc; $this->journalRepo = $journalRepo; } /** * Determine the journal to charge to, otherwise, it's charged * to every airline journal * * @param Expense $expense * * @return \Generator */ protected function findJournals(Expense $expense) { if ($expense->airline_id) { $airline = Airline::find($expense->airline_id)->first(['id', 'icao']); Log::info('Charging to '.$airline->icao); yield $airline->journal; } else { $airlines = Airline::all(['id', 'icao']); foreach ($airlines as $airline) { Log::info('Charging to '.$airline->icao); yield $airline->journal; } } } /** * Get the name of the transaction group from the expense * * @param Expense $expense * * @return array */ protected function getMemoAndGroup(Expense $expense): array { $klass = 'Expense'; if ($expense->ref_model) { $ref = explode('\\', $expense->ref_model); $klass = end($ref); $obj = $expense->getReferencedObject(); } if (empty($obj)) { return [null, null]; } if ($klass === 'Airport') { $memo = "Airport Expense: {$expense->name} ({$expense->ref_model_id})"; $transaction_group = "Airport: {$expense->ref_model_id}"; } 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 * * @param string $type * * @throws \Prettus\Validator\Exceptions\ValidatorException */ public function processExpenses($type = ExpenseType::DAILY): void { $expenses = Expense::where(['type' => $type])->get(); $tag = 'expense_recurring'; if ($type === ExpenseType::DAILY) { $tag = 'expenses_daily'; } elseif ($type === ExpenseType::MONTHLY) { $tag = 'expenses_monthly'; } /** * @var $expenses Expense[] */ foreach ($expenses as $expense) { // Apply the expenses to the appropriate journals $journals = $this->findJournals($expense); foreach ($journals as $journal) { $amount = $expense->amount; // Has this expense already been charged? Check // against this specific journal, on today $w = [ 'journal_id' => $journal->id, 'ref_model' => Expense::class, 'ref_model_id' => $expense->id, ]; $found = JournalTransaction::where($w) ->whereDate('post_date', '=', Carbon::now('UTC')->toDateString()) ->count(['id']); if ($found > 0) { Log::info('Expense "'.$expense->name.'" already charged for today, skipping'); continue; } [$memo, $ta_group] = $this->getMemoAndGroup($expense); if (empty($memo) || empty($ta_group)) { continue; } $this->financeSvc->debitFromJournal( $journal, Money::createFromAmount($amount), $expense, $memo, $ta_group, $tag ); Log::info('Expense memo: "'.$memo.'"; group: "'.$ta_group.'" charged!'); } } } }