diff --git a/code/app/Console/Commands/CheckFees.php b/code/app/Console/Commands/CheckFees.php index cd3602be..fe4115d9 100644 --- a/code/app/Console/Commands/CheckFees.php +++ b/code/app/Console/Commands/CheckFees.php @@ -4,8 +4,8 @@ use Illuminate\Console\Command; -use DB; -use Log; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; use App\Gas; use App\User; diff --git a/code/app/Services/BookingsService.php b/code/app/Services/BookingsService.php index f8a972cd..237931b8 100644 --- a/code/app/Services/BookingsService.php +++ b/code/app/Services/BookingsService.php @@ -13,7 +13,7 @@ use App\BookedProductComponent; use App\ModifierType; use App\ModifiedValue; - +use App\Exceptions\IllegalArgumentException; use App\Events\BookingDelivered; class BookingsService extends BaseService @@ -394,15 +394,44 @@ public function handleBookingUpdate($request, $user, $order, $target_user, $deli return $booking; } - public function bookingUpdate(array $request, $aggregate, $target_user, $delivering) + /* + Il controllo sul credito a disposizione viene fatto soprattutto + client-side, in fase di prenotazione; qui rifaccio il controllo per + prevenire eventuali problemi + */ + private function checkAvailableCredit($user) { - DB::transaction(function() use ($request, $aggregate, $target_user, $delivering) { - $orders = $aggregate->orders()->with(['products', 'bookings', 'modifiers'])->get(); - $user = $this->testAccess($target_user, $orders, $delivering); + if ($user->gas->restrict_booking_to_credit) { + /* + Questa funzione viene invocata dopo aver salvato la + prenotazione, nel contesto di una transazione, dunque il + bilancio attivo dell'utente giĆ  prevede la prenotazione stessa e + pertanto, per essere valido, deve essere superiore a 0 + */ + $current_active_balance = $user->activeBalance(); - foreach($orders as $order) { - $this->handleBookingUpdate($request, $user, $order, $target_user, $delivering); + if ($current_active_balance < 0) { + DB::rollback(); + throw new IllegalArgumentException(_i('Credito non sufficiente'), 1); } - }, 3); + } + } + + public function bookingUpdate(array $request, $aggregate, $target_user, $delivering) + { + DB::beginTransaction(); + + $orders = $aggregate->orders()->with(['products', 'bookings', 'modifiers'])->get(); + $user = $this->testAccess($target_user, $orders, $delivering); + + foreach($orders as $order) { + $this->handleBookingUpdate($request, $user, $order, $target_user, $delivering); + } + + if ($delivering == false) { + $this->checkAvailableCredit($target_user); + } + + DB::commit(); } } diff --git a/code/tests/Services/BookingsServiceTest.php b/code/tests/Services/BookingsServiceTest.php index 72bac5c0..246ef4f3 100644 --- a/code/tests/Services/BookingsServiceTest.php +++ b/code/tests/Services/BookingsServiceTest.php @@ -7,6 +7,7 @@ use Illuminate\Support\Collection; use App\Exceptions\AuthException; +use App\Exceptions\IllegalArgumentException; use App\Movement; class BookingsServiceTest extends TestCase @@ -406,6 +407,55 @@ public function testManualShippingMinus() $this->handlingTotalManual(-10); } + private function enforceBalance($user, $amount) + { + $currency = defaultCurrency(); + $balance = $user->currentBalance($currency); + $balance->bank = $amount; + $balance->save(); + + $user = $user->fresh(); + + $current = $user->currentBalanceAmount(); + $this->assertEquals($amount, $current); + + return $user; + } + + public function testInsufficientCredit() + { + $this->gas->setConfig('restrict_booking_to_credit', true); + + $this->actingAs($this->userWithBasePerms); + + list($data, $booked_count, $total) = $this->randomQuantities($this->sample_order->products); + $this->userWithBasePerms = $this->enforceBalance($this->userWithBasePerms, $total + 10); + + $this->nextRound(); + + $data['action'] = 'booked'; + $booking = $this->updateAndFetch($data, $this->sample_order, $this->userWithBasePerms, false); + $this->assertNotNull($booking); + $this->assertEquals($booking->status, 'pending'); + $this->assertEquals($booking->products()->count(), $booked_count); + $this->assertEquals($booking->getValue('booked', true), $total); + + list($data, $booked_count, $total) = $this->randomQuantities($this->sample_order->products); + $this->userWithBasePerms = $this->enforceBalance($this->userWithBasePerms, $total - 10); + + $this->nextRound(); + + $data['action'] = 'booked'; + + try { + $this->updateAndFetch($data, $this->sample_order, $this->userWithBasePerms, false); + $this->fail('should never run'); + } + catch(IllegalArgumentException $e) { + // good boy + } + } + /* I test per prenotazioni fatte da un amico sono fatti in ModifiersServiceTest