diff --git a/.github/ISSUE_TEMPLATE/Bug-Report.yml b/.github/ISSUE_TEMPLATE/Bug-Report.yml index 20c2e9ef7e..523ebc5e26 100644 --- a/.github/ISSUE_TEMPLATE/Bug-Report.yml +++ b/.github/ISSUE_TEMPLATE/Bug-Report.yml @@ -15,7 +15,7 @@ body: Please make sure you've checked these resources before submitting a new issue. If you find an existing issue, please add your context to it instead of opening a new issue. If your issue is more of a question, consider [opening a new discussion](https://github.com/grokability/snipe-it/discussions) or [pop by our Discord](https://discord.gg/yZFtShAcKk) instead of creating an issue. - **Please write your feature request in English.** You can use tools like [DeepL](https://www.deepl.com) or [Google Translate](https://translate.google.com/) to translate if necessary. + **Please write your bug report in English.** You can use tools like [DeepL](https://www.deepl.com) or [Google Translate](https://translate.google.com/) to translate if necessary. **If you choose to upload screenshots or videos (which we always encourage), please make sure they do not contain any sensitive information.** - type: input diff --git a/app/Http/Controllers/Licenses/LicensesController.php b/app/Http/Controllers/Licenses/LicensesController.php index b1728469b4..bdc0dc74e1 100755 --- a/app/Http/Controllers/Licenses/LicensesController.php +++ b/app/Http/Controllers/Licenses/LicensesController.php @@ -256,6 +256,9 @@ class LicensesController extends Controller else { $checkedout_seats_count = ($total_seats_count - $available_seats_count); } + if($license->isInactive()){ + session()->flash('warning', (trans('admin/licenses/message.checkout.license_is_inactive'))); + } $this->authorize('view', $license); return view('licenses.view', compact('license')) diff --git a/app/Http/Transformers/LicenseSeatsTransformer.php b/app/Http/Transformers/LicenseSeatsTransformer.php index 17025e7f9f..d018934e18 100644 --- a/app/Http/Transformers/LicenseSeatsTransformer.php +++ b/app/Http/Transformers/LicenseSeatsTransformer.php @@ -51,7 +51,7 @@ class LicenseSeatsTransformer 'reassignable' => (bool) $seat->license->reassignable, 'notes' => e($seat->notes), 'user_can_checkout' => (($seat->assigned_to == '') && ($seat->asset_id == '')), - 'disabled' => $seat->unreassignable_seat, + 'disabled' => $seat->unreassignable_seat || $seat->license->isInactive(), ]; $permissions_array['available_actions'] = [ diff --git a/app/Http/Transformers/LicensesTransformer.php b/app/Http/Transformers/LicensesTransformer.php index 24822efeca..39079c6ec5 100644 --- a/app/Http/Transformers/LicensesTransformer.php +++ b/app/Http/Transformers/LicensesTransformer.php @@ -54,7 +54,7 @@ class LicensesTransformer 'updated_at' => Helper::getFormattedDateObject($license->updated_at, 'datetime'), 'deleted_at' => Helper::getFormattedDateObject($license->deleted_at, 'datetime'), 'user_can_checkout' => (bool) ($license->free_seats_count > 0), - + 'disabled' => $license->isInactive(), ]; $permissions_array['available_actions'] = [ diff --git a/app/Models/License.php b/app/Models/License.php index ecd1b003e3..d6621a5277 100755 --- a/app/Models/License.php +++ b/app/Models/License.php @@ -14,6 +14,7 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Session; use Watson\Validating\ValidatingTrait; + class License extends Depreciable { use HasFactory; @@ -296,6 +297,18 @@ class License extends Depreciable } $this->attributes['termination_date'] = $value; } + + public function isInactive(): bool +{ + $day = now()->startOfDay(); + + $expired = $this->expiration_date && $this->asDateTime($this->expiration_date)->startofDay()->lessThanOrEqualTo($day); + + $terminated = $this->termination_date && $this->asDateTime($this->termination_date)->startofDay()->lessThanOrEqualTo($day); + + + return $expired || $terminated; +} /** * Sets free_seat_count attribute * @@ -596,7 +609,7 @@ class License extends Depreciable { $count = 0; if (!$license->reassignable) { - $count = licenseSeat::query()->where('unreassignable_seat', '=', true) + $count = LicenseSeat::query()->where('unreassignable_seat', '=', true) ->where('license_id', '=', $license->id) ->count(); } @@ -711,6 +724,7 @@ class License extends Depreciable ->whereNull('deleted_at') ->whereRaw('DATE_SUB(`expiration_date`,INTERVAL '.$days.' DAY) <= DATE(NOW()) ') ->where('expiration_date', '>', date('Y-m-d')) + ->where('termination_date', '>', date('Y-m-d')) ->orderBy('expiration_date', 'ASC') ->get(); } diff --git a/app/Presenters/LicensePresenter.php b/app/Presenters/LicensePresenter.php index b0518ef264..a1edf2cf76 100644 --- a/app/Presenters/LicensePresenter.php +++ b/app/Presenters/LicensePresenter.php @@ -202,7 +202,7 @@ class LicensePresenter extends Presenter 'switchable' => false, 'title' => trans('general.checkin').'/'.trans('general.checkout'), 'visible' => true, - 'formatter' => 'licensesInOutFormatter', + 'formatter' => 'licenseInOutFormatter', 'printIgnore' => true, ]; diff --git a/resources/lang/en-US/admin/licenses/message.php b/resources/lang/en-US/admin/licenses/message.php index 9a0219d857..29ab06cbd9 100644 --- a/resources/lang/en-US/admin/licenses/message.php +++ b/resources/lang/en-US/admin/licenses/message.php @@ -46,6 +46,7 @@ return array( 'not_enough_seats' => 'Not enough license seats available for checkout', 'mismatch' => 'The license seat provided does not match the license', 'unavailable' => 'This seat is not available for checkout.', + 'license_is_inactive' => 'This license is expired or terminated.', ), 'checkin' => array( diff --git a/resources/views/partials/bootstrap-table.blade.php b/resources/views/partials/bootstrap-table.blade.php index b325e89f1b..7c3468537d 100644 --- a/resources/views/partials/bootstrap-table.blade.php +++ b/resources/views/partials/bootstrap-table.blade.php @@ -556,21 +556,30 @@ } } - + function licenseInOutFormatter(value, row) { + if(row.disabled || row.user_can_checkout === false) { + return '{{ trans('general.checkout') }}'; + } else + // The user is allowed to check the license seat out and it's available + if ((row.available_actions.checkout === true) && (row.user_can_checkout === true)) { + return '{{ trans('general.checkout') }}'; + } + } // We need a special formatter for license seats, since they don't work exactly the same // Checkouts need the license ID, checkins need the specific seat ID function licenseSeatInOutFormatter(value, row) { + if (row.disabled && (row.assigned_user || row.assigned_asset)) { + return '{{ trans('general.checkin') }}'; + } if(row.disabled) { return '{{ trans('general.checkout') }}'; - } else + } // The user is allowed to check the license seat out and it's available - if ((row.available_actions.checkout === true) && (row.user_can_checkout === true) && ((!row.asset_id) && (!row.assigned_to))) { + if ((row.available_actions.checkout === true) && (row.user_can_checkout === true) && ((!row.assigned_asset) && (!row.assigned_user))) { return '{{ trans('general.checkout') }}'; } - else { - return '{{ trans('general.checkin') }}'; - } + } function genericCheckinCheckoutFormatter(destination) {