fill($data); if (!$expense->id) { $expense = $this->processExchangeRates($data, $expense); } if (empty($expense->number)) { $expense = $this->findAndSaveNumber($expense); } $expense->saveQuietly(); if (array_key_exists('documents', $data)) { $this->saveDocuments($data['documents'], $expense); } return $expense; } /** * Store expenses in bulk. * * @param array $expense * * @return \App\Models\Expense|null */ public function create($expense): ?Expense { return $this->save( $expense, ExpenseFactory::create(auth()->user()->company()->id, auth()->user()->id) ); } /** * @param mixed $data * @param mixed $expense * @return Expense * @throws InvalidFormatException */ public function processExchangeRates($data, $expense): Expense { if (array_key_exists('exchange_rate', $data) && isset($data['exchange_rate']) && $data['exchange_rate'] != 1) { return $expense; } $expense_currency = $data['currency_id']; $company_currency = $expense->company->settings->currency_id; if ($company_currency != $expense_currency) { $exchange_rate = new CurrencyApi(); $expense->exchange_rate = $exchange_rate->exchangeRate($expense_currency, $company_currency, Carbon::parse($expense->date)); return $expense; } return $expense; } public function delete($expense) :Expense { if ($expense->transaction()->exists()) { $exp_ids = collect(explode(',', $expense->transaction->expense_id))->filter(function ($id) use ($expense) { return $id != $expense->hashed_id; })->implode(','); $expense->transaction_id = null; $expense->saveQuietly(); $expense->transaction->expense_id = $exp_ids; $expense->transaction->saveQuietly(); } parent::delete($expense); return $expense; } /** * Handle race conditions when creating expense numbers * * @param Expense $expense * @return \App\Models\Expense */ private function findAndSaveNumber($expense): Expense { $x = 1; do { try { $expense->number = $this->getNextExpenseNumber($expense); $expense->saveQuietly(); $this->completed = false; } catch (QueryException $e) { $x++; if ($x > 50) { $this->completed = false; } } } while ($this->completed); return $expense; } }