From 60f5278c47aaaa7f1742b60a94db5fc10362de75 Mon Sep 17 00:00:00 2001 From: Roberto Guido Date: Sat, 9 Dec 2023 14:56:39 +0100 Subject: [PATCH] limite esplicito di credito per prenotazioni. closes #230 --- code/app/Console/Commands/FixDatabase.php | 55 ++---------- code/app/Formatters/GenericProductFormat.php | 85 ++++++++----------- code/app/Gas.php | 2 + code/app/Helpers/Components.php | 2 - .../Http/Controllers/VariantsController.php | 16 +--- code/app/Models/Concerns/BookerTrait.php | 4 +- code/app/Observers/UserObserver.php | 5 +- .../Config/RestrictedBookingToCredit.php | 25 +++++- code/app/Services/BookingsService.php | 6 +- code/config/larastrap.php | 6 +- code/resources/views/booking/edit.blade.php | 6 +- code/resources/views/gas/orders.blade.php | 6 +- code/tests/Services/BookingsServiceTest.php | 28 +++++- 13 files changed, 119 insertions(+), 127 deletions(-) diff --git a/code/app/Console/Commands/FixDatabase.php b/code/app/Console/Commands/FixDatabase.php index ef24ac67f..61b186dfb 100644 --- a/code/app/Console/Commands/FixDatabase.php +++ b/code/app/Console/Commands/FixDatabase.php @@ -34,56 +34,17 @@ public function handle() Artisan::call('db:seed', ['--force' => true, '--class' => 'ModifierTypesSeeder']); /* - Per fixare gli URL dei listini autogenerati ed erroneamente - sovrascritti - */ - foreach(Supplier::all() as $supplier) { - $attachments = $supplier->attachments; - - $pdf = $attachments->firstWhere('name', 'Listino PDF (autogenerato)'); - if ($pdf) { - $pdf->url = route('suppliers.catalogue', ['id' => $supplier->id, 'format' => 'pdf']); - $pdf->save(); - } - - $csv = $attachments->firstWhere('name', 'Listino CSV (autogenerato)'); - if ($csv) { - $csv->url = route('suppliers.catalogue', ['id' => $supplier->id, 'format' => 'csv']); - $csv->save(); - } - } - - /* - Per non attivare il tour di onboarding per gli utenti esistenti - */ - User::query()->update(['tour' => true]); - - /* - Per impostare un default sull'approvazione manuale delle - registrazioni pubbliche degli utenti + Per revisionare le configurazioni relative ai limiti di credito per + permettere le prenotazioni */ foreach(Gas::all() as $gas) { - $registrations_info = $gas->public_registrations; - if (isset($registrations_info['manual']) == false) { - $registrations_info['manual'] = false; - $gas->setConfig('public_registrations', $registrations_info); - } - } - - /* - Per azzerare le vecchie configurazioni Satispay non compatibili con - la nuova implementazione - */ - foreach(Gas::all() as $gas) { - $satispay_info = $gas->satispay; - if (isset($satispay_info['public']) == false) { - $satispay_info = (object) [ - 'public' => '', - 'secret' => '', - 'key' => '', + $restriction_info = $gas->getConfig('restrict_booking_to_credit'); + if (is_array($restriction_info) == false) { + $restriction_info = (object) [ + 'enabled' => $restriction_info, + 'limit' => 0, ]; - - $gas->setConfig('satispay', $satispay_info); + $gas->setConfig('restrict_booking_to_credit', $restriction_info); } } diff --git a/code/app/Formatters/GenericProductFormat.php b/code/app/Formatters/GenericProductFormat.php index f1d6e7941..f847c56b3 100644 --- a/code/app/Formatters/GenericProductFormat.php +++ b/code/app/Formatters/GenericProductFormat.php @@ -1,59 +1,44 @@ (object) [ - 'name' => _i('Nome'), - 'checked' => true, - ], - 'supplier_code' => (object) [ - 'name' => _i('Codice Fornitore'), - ], - 'measure' => (object) [ - 'name' => _i('Unità di Misura'), - ], - 'category' => (object) [ - 'name' => _i('Categoria'), - ], - 'price' => (object) [ - 'name' => _i('Prezzo Unitario'), - 'checked' => true, - ], - 'active' => (object) [ - 'name' => _i('Ordinabile'), - ], - 'vat_rate' => (object) [ - 'name' => _i('Aliquota IVA'), - ], - 'portion_quantity' => (object) [ - 'name' => _i('Pezzatura'), - ], - 'variable' => (object) [ - 'name' => _i('Variabile'), - ], - 'package_size' => (object) [ - 'name' => _i('Dimensione Confezione'), - ], - 'weight' => (object) [ - 'name' => _i('Peso'), - ], - 'multiple' => (object) [ - 'name' => _i('Multiplo'), - ], - 'min_quantity' => (object) [ - 'name' => _i('Minimo'), - ], - 'max_quantity' => (object) [ - 'name' => _i('Massimo Consigliato'), - ], - 'max_available' => (object) [ - 'name' => _i('Disponibile'), - ], + protected static function genericColumns() + { + $attributes = [ + 'name' => _i('Nome'), + 'supplier_code' => _i('Codice Fornitore'), + 'measure' => _i('Unità di Misura'), + 'category' => _i('Categoria'), + 'price' => _i('Prezzo Unitario'), + 'active' => _i('Ordinabile'), + 'vat_rate' => _i('Aliquota IVA'), + 'portion_quantity' => _i('Pezzatura'), + 'variable' => _i('Variabile'), + 'package_size' => _i('Dimensione Confezione'), + 'weight' => _i('Peso'), + 'multiple' => _i('Multiplo'), + 'min_quantity' => _i('Minimo'), + 'max_quantity' => _i('Massimo Consigliato'), + 'max_available' => _i('Disponibile'), + ]; + + $ret = []; + $checked_by_default = ['name', 'price']; + foreach($attributes as $attr => $label) { + $ret[$attr] = (object) [ + 'name' => $label, + 'checked' => in_array($attr, $checked_by_default), ]; } + + return $ret; + } } diff --git a/code/app/Gas.php b/code/app/Gas.php index 07d85032a..ca64eb9c8 100644 --- a/code/app/Gas.php +++ b/code/app/Gas.php @@ -103,6 +103,8 @@ public function hasFeature($name) return (!empty($obj->extra_invoicing['taxcode']) || !empty($obj->extra_invoicing['vat'])); case 'public_registrations': return $obj->public_registrations['enabled']; + case 'restrict_booking_to_credit': + return $obj->restrict_booking_to_credit['enabled']; case 'auto_aggregates': return Aggregate::has('orders', '>=', aggregatesConvenienceLimit())->count() > 3; case 'send_order_reminder': diff --git a/code/app/Helpers/Components.php b/code/app/Helpers/Components.php index 0bd5d3a4c..80e7e6cb4 100644 --- a/code/app/Helpers/Components.php +++ b/code/app/Helpers/Components.php @@ -115,8 +115,6 @@ function formatObjectsToComponent($component, $params) function formatPriceToComponent($component, $params) { - $value = printablePrice($params['value']); - if (isset($params['currency']) == false) { $currency = defaultCurrency()->symbol; } diff --git a/code/app/Http/Controllers/VariantsController.php b/code/app/Http/Controllers/VariantsController.php index 7f6b9012e..5ef265d48 100644 --- a/code/app/Http/Controllers/VariantsController.php +++ b/code/app/Http/Controllers/VariantsController.php @@ -68,15 +68,7 @@ public function matrix(Request $request, $id) private function transformFromSimplified($request, $product) { $original_combinations = $request->input('combination', []); - - $ids = array_map(function($item) { - if (Str::startsWith($item, 'new_')) { - return ''; - } - else { - return $item; - } - }, $original_combinations); + $ids = array_map(fn($item) => Str::startsWith($item, 'new_') ? '' : $item, $original_combinations); $values = $request->input('value', []); @@ -87,11 +79,7 @@ private function transformFromSimplified($request, $product) 'value' => $values, ]); - $combinations = []; - - foreach($values as $value) { - $combinations[] = $variant->values()->where('value', $value)->first()->id; - } + $combinations = array_map(fn($v) => $variant->values()->where('value', $v)->first()->id, $values); /* Ai nuovi valori dinamicamente immessi nella tabella aggiungo un diff --git a/code/app/Models/Concerns/BookerTrait.php b/code/app/Models/Concerns/BookerTrait.php index db3b024c3..1fbd6089e 100644 --- a/code/app/Models/Concerns/BookerTrait.php +++ b/code/app/Models/Concerns/BookerTrait.php @@ -36,12 +36,12 @@ public function getLastBookingAttribute() public function canBook() { - if ($this->gas->restrict_booking_to_credit) { + if ($this->gas->hasFeature('restrict_booking_to_credit')) { if ($this->isFriend()) { return $this->parent->canBook(); } else { - return $this->activeBalance() > 0; + return $this->activeBalance() > $this->gas->restrict_booking_to_credit['limit']; } } else { diff --git a/code/app/Observers/UserObserver.php b/code/app/Observers/UserObserver.php index 1e00a0428..c30949cab 100644 --- a/code/app/Observers/UserObserver.php +++ b/code/app/Observers/UserObserver.php @@ -12,7 +12,10 @@ class UserObserver { private function checkUsername($user) { - $test = User::withTrashed()->where('id', '!=', $user->id)->where('username', $user->username)->first(); + /* + Lo username deve essere univoco per tutti gli utenti di tutti i GAS + */ + $test = User::withTrashed()->withoutGlobalScopes()->where('id', '!=', $user->id)->where('username', $user->username)->first(); if ($test != null) { throw new IllegalArgumentException(_i('Username già assegnato'), 'username'); } diff --git a/code/app/Parameters/Config/RestrictedBookingToCredit.php b/code/app/Parameters/Config/RestrictedBookingToCredit.php index 10c60eaee..daec3508f 100644 --- a/code/app/Parameters/Config/RestrictedBookingToCredit.php +++ b/code/app/Parameters/Config/RestrictedBookingToCredit.php @@ -11,11 +11,32 @@ public function identifier() public function type() { - return 'boolean'; + return 'object'; } public function default() { - return 0; + return (object) [ + 'enabled' => false, + 'limit' => 0, + ]; + } + + public function handleSave($gas, $request) + { + if ($request->has('enable_restrict_booking_to_credit')) { + $restriction_info = (object) [ + 'enabled' => true, + 'limit' => $request->input('restrict_booking_to_credit->limit', 0), + ]; + } + else { + $restriction_info = (object) [ + 'enabled' => false, + 'limit' => 0, + ]; + } + + $gas->setConfig('restrict_booking_to_credit', $restriction_info); } } diff --git a/code/app/Services/BookingsService.php b/code/app/Services/BookingsService.php index 237931b81..ff2db37ae 100644 --- a/code/app/Services/BookingsService.php +++ b/code/app/Services/BookingsService.php @@ -401,16 +401,16 @@ public function handleBookingUpdate($request, $user, $order, $target_user, $deli */ private function checkAvailableCredit($user) { - if ($user->gas->restrict_booking_to_credit) { + if ($user->gas->hasFeature('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 + pertanto, per essere valido, deve essere superiore al limite */ $current_active_balance = $user->activeBalance(); - if ($current_active_balance < 0) { + if ($current_active_balance < $user->gas->restrict_booking_to_credit['limit']) { DB::rollback(); throw new IllegalArgumentException(_i('Credito non sufficiente'), 1); } diff --git a/code/config/larastrap.php b/code/config/larastrap.php index 2aa028336..7064dde1d 100644 --- a/code/config/larastrap.php +++ b/code/config/larastrap.php @@ -66,7 +66,11 @@ 'tabpane' => [ 'reviewCallback' => 'formatTabLabel', - ] + ], + + 'collapse' => [ + 'classes' => ['mb-2'], + ], ], 'customs' => [ diff --git a/code/resources/views/booking/edit.blade.php b/code/resources/views/booking/edit.blade.php index 5aa4ff264..ae715fdd5 100644 --- a/code/resources/views/booking/edit.blade.php +++ b/code/resources/views/booking/edit.blade.php @@ -40,8 +40,8 @@ - @if($user->gas->restrict_booking_to_credit) - + @if($user->gas->hasFeature('restrict_booking_to_credit')) + @endif
@@ -214,7 +214,7 @@ 'skip_cells' => 3 ]) - @if($user->gas->restrict_booking_to_credit) + @if($user->gas->hasFeature('restrict_booking_to_credit'))   diff --git a/code/resources/views/gas/orders.blade.php b/code/resources/views/gas/orders.blade.php index 8c04fcc72..b560b27e5 100644 --- a/code/resources/views/gas/orders.blade.php +++ b/code/resources/views/gas/orders.blade.php @@ -4,7 +4,11 @@
- + + + + + gas->setConfig('restrict_booking_to_credit', true); + $this->gas->setConfig('restrict_booking_to_credit', (object) [ + 'enabled' => true, + 'limit' => 0, + ]); $this->actingAs($this->userWithBasePerms); @@ -467,6 +473,26 @@ public function testInsufficientCredit() } } + /* + Prenotazione con limiti di credito diversi da 0 abilitati + */ + public function testInsufficientCreditWithLimit() + { + $this->gas->setConfig('restrict_booking_to_credit', (object) [ + 'enabled' => true, + 'limit' => -20, + ]); + + $this->actingAs($this->userWithBasePerms); + + list($data, $booked_count, $total) = $this->randomQuantities($this->sample_order->products); + $this->userWithBasePerms = $this->enforceBalance($this->userWithBasePerms, $total - 10); + + $data['action'] = 'booked'; + $booking = $this->updateAndFetch($data, $this->sample_order, $this->userWithBasePerms, false); + $this->assertNotNull($booking); + } + /* I test per prenotazioni fatte da un amico sono fatti in ModifiersServiceTest