diff --git a/app/Repositories/ExpenseRepository.php b/app/Repositories/ExpenseRepository.php index 2b9e17c5bc35..d8df5f6fba30 100644 --- a/app/Repositories/ExpenseRepository.php +++ b/app/Repositories/ExpenseRepository.php @@ -1,4 +1,5 @@ fill($data); - if (! $expense->id) { + if (!$expense->id) { $expense = $this->processExchangeRates($data, $expense); } - $expense->number = empty($expense->number) ? $this->getNextExpenseNumber($expense) : $expense->number; + if (empty($expense->number)) + $expense = $this->findAndSaveNumber($expense); + $expense->save(); if (array_key_exists('documents', $data)) { @@ -54,6 +60,7 @@ class ExpenseRepository extends BaseRepository * Store expenses in bulk. * * @param array $expense + * * @return \App\Models\Expense|null */ public function create($expense): ?Expense @@ -64,7 +71,7 @@ class ExpenseRepository extends BaseRepository ); } - public function processExchangeRates($data, $expense) + public function processExchangeRates($data, $expense): Expense { if (array_key_exists('exchange_rate', $data) && isset($data['exchange_rate']) && $data['exchange_rate'] != 1) { return $expense; @@ -83,4 +90,35 @@ class ExpenseRepository extends BaseRepository 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; + } }