Skip to content

Commit 0e957ca

Browse files
committed
Merge remote-tracking branch 'origin/develop'
2 parents 85c728f + b67f808 commit 0e957ca

File tree

17 files changed

+205
-76
lines changed

17 files changed

+205
-76
lines changed

app/Console/Commands/SendExpirationAlerts.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace App\Console\Commands;
44

5+
use App\Helpers\Helper;
56
use App\Mail\ExpiringAssetsMail;
67
use App\Mail\ExpiringLicenseMail;
78
use App\Models\Asset;
@@ -57,14 +58,27 @@ public function handle()
5758
if ($assets->count() > 0) {
5859
$this->info(trans_choice('mail.assets_warrantee_alert', $assets->count(), ['count' => $assets->count(), 'threshold' => $alert_interval]));
5960
Mail::to($recipients)->send(new ExpiringAssetsMail($assets, $alert_interval));
61+
62+
$this->table(
63+
['ID', 'Tag', 'Model', 'Model Number', 'EOL', 'EOL Months', 'Warranty Expires', 'Warranty Months'],
64+
$assets->map(fn($item) => ['ID' => $item->id, 'Tag' => $item->asset_tag, 'Model' => $item->model->name, 'Model Number' => $item->model->model_number, 'EOL' => $item->asset_eol_date, 'EOL Months' => $item->model->eol, 'Warranty Expires' => $item->warranty_expires, 'Warranty Months' => $item->warranty_months])
65+
);
6066
}
6167

6268
// Expiring licenses
6369
$licenses = License::getExpiringLicenses($alert_interval);
6470
if ($licenses->count() > 0) {
6571
$this->info(trans_choice('mail.license_expiring_alert', $licenses->count(), ['count' => $licenses->count(), 'threshold' => $alert_interval]));
6672
Mail::to($recipients)->send(new ExpiringLicenseMail($licenses, $alert_interval));
73+
74+
$this->table(
75+
['ID', 'Name', 'Expires', 'Termination Date'],
76+
$licenses->map(fn($item) => ['ID' => $item->id, 'Name' => $item->name, 'Expires' => $item->expiration_date, 'Termination Date' => $item->termination_date])
77+
);
6778
}
79+
80+
81+
6882
} else {
6983
if ($settings->alert_email == '') {
7084
$this->error('Could not send email. No alert email configured in settings');

app/Http/Controllers/Licenses/LicensesController.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,9 @@ public function show(License $license)
256256
else {
257257
$checkedout_seats_count = ($total_seats_count - $available_seats_count);
258258
}
259+
if($license->isInactive()){
260+
session()->flash('warning', (trans('admin/licenses/message.checkout.license_is_inactive')));
261+
}
259262

260263
$this->authorize('view', $license);
261264
return view('licenses.view', compact('license'))

app/Http/Transformers/LicenseSeatsTransformer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function transformLicenseSeat(LicenseSeat $seat)
5151
'reassignable' => (bool) $seat->license->reassignable,
5252
'notes' => e($seat->notes),
5353
'user_can_checkout' => (($seat->assigned_to == '') && ($seat->asset_id == '')),
54-
'disabled' => $seat->unreassignable_seat,
54+
'disabled' => $seat->unreassignable_seat || $seat->license->isInactive(),
5555
];
5656

5757
$permissions_array['available_actions'] = [

app/Http/Transformers/LicensesTransformer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function transformLicense(License $license)
5454
'updated_at' => Helper::getFormattedDateObject($license->updated_at, 'datetime'),
5555
'deleted_at' => Helper::getFormattedDateObject($license->deleted_at, 'datetime'),
5656
'user_can_checkout' => (bool) ($license->free_seats_count > 0),
57-
57+
'disabled' => $license->isInactive(),
5858
];
5959

6060
$permissions_array['available_actions'] = [

app/Mail/CheckoutAccessoryMail.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function envelope(): Envelope
4343

4444
return new Envelope(
4545
from: $from,
46-
subject: trans('mail.Accessory_Checkout_Notification'),
46+
subject: trans_choice('mail.Accessory_Checkout_Notification', $this->checkout_qty),
4747
);
4848
}
4949

@@ -83,17 +83,19 @@ public function content(): Content
8383
],
8484
);
8585
}
86+
8687
private function introductionLine(): string
8788
{
8889
if ($this->target instanceof Location) {
89-
return trans('mail.new_item_checked_location', ['location' => $this->target->name ]);
90+
return trans_choice('mail.new_item_checked_location', $this->checkout_qty, ['location' => $this->target->name]);
9091
}
92+
9193
if ($this->requiresAcceptance()) {
92-
return trans('mail.new_item_checked_with_acceptance');
94+
return trans_choice('mail.new_item_checked_with_acceptance', $this->checkout_qty);
9395
}
9496

9597
if (!$this->requiresAcceptance()) {
96-
return trans('mail.new_item_checked');
98+
return trans_choice('mail.new_item_checked', $this->checkout_qty);
9799
}
98100

99101
// we shouldn't get here but let's send a default message just in case

app/Mail/CheckoutAssetMail.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,15 @@ private function getSubject(): string
138138
private function introductionLine(): string
139139
{
140140
if ($this->firstTimeSending && $this->target instanceof Location) {
141-
return trans('mail.new_item_checked_location', ['location' => $this->target->name ]);
141+
return trans_choice('mail.new_item_checked_location', 1, ['location' => $this->target->name]);
142142
}
143+
143144
if ($this->firstTimeSending && $this->requiresAcceptance()) {
144-
return trans('mail.new_item_checked_with_acceptance');
145+
return trans_choice('mail.new_item_checked_with_acceptance', 1);
145146
}
146147

147148
if ($this->firstTimeSending && !$this->requiresAcceptance()) {
148-
return trans('mail.new_item_checked');
149+
return trans_choice('mail.new_item_checked', 1);
149150
}
150151

151152
if (!$this->firstTimeSending && $this->requiresAcceptance()) {

app/Models/Asset.php

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,6 @@ public function declinedCheckout(User $declinedBy, $signature)
161161
'eol_explicit',
162162
'last_audit_date',
163163
'next_audit_date',
164-
'asset_eol_date',
165164
'last_checkin',
166165
'last_checkout',
167166
];
@@ -826,19 +825,24 @@ public function model()
826825
*/
827826
public static function getExpiringWarrantee($days = 30)
828827
{
829-
$days = (is_null($days)) ? 30 : $days;
830828

831-
return self::where('archived', '=', '0') // this can stay for right now, as `archived` defaults to 0 at the db level, but should probably be replaced with assetstatus->archived?
832-
->whereNotNull('warranty_months')
833-
->whereNotNull('purchase_date')
834-
->whereNull('deleted_at')
829+
return self::where('archived', '=', '0')
835830
->NotArchived()
836-
->whereRaw(
837-
'DATE_ADD(`purchase_date`, INTERVAL `warranty_months` MONTH) <= DATE_ADD(NOW(), INTERVAL '
838-
. $days
839-
. ' DAY) AND DATE_ADD(`purchase_date`, INTERVAL `warranty_months` MONTH) > NOW()'
840-
)
841-
->orderByRaw('DATE_ADD(`purchase_date`,INTERVAL `warranty_months` MONTH)')
831+
->whereNull('deleted_at')
832+
833+
// Check for manual asset EOL first
834+
->where(function ($query) use ($days) {
835+
$query->whereNotNull('asset_eol_date')
836+
->whereBetween('asset_eol_date', [Carbon::now(), Carbon::now()->addDays($days)]);
837+
})
838+
// Otherwise use the warranty months + purchase date + threshold
839+
->orWhere(function ($query) use ($days) {
840+
$query->whereNotNull('purchase_date')
841+
->whereNotNull('warranty_months')
842+
->whereDate('purchase_date', '<=', Carbon::now()->addMonths('assets.warranty_months')->addDays($days));
843+
})
844+
->orderBy('asset_eol_date', 'ASC')
845+
->orderBy('purchase_date', 'ASC')
842846
->get();
843847
}
844848

app/Models/License.php

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Illuminate\Support\Facades\Session;
1515
use Watson\Validating\ValidatingTrait;
1616

17+
1718
class License extends Depreciable
1819
{
1920
use HasFactory;
@@ -296,6 +297,18 @@ public function setTerminationDateAttribute($value)
296297
}
297298
$this->attributes['termination_date'] = $value;
298299
}
300+
301+
public function isInactive(): bool
302+
{
303+
$day = now()->startOfDay();
304+
305+
$expired = $this->expiration_date && $this->asDateTime($this->expiration_date)->startofDay()->lessThanOrEqualTo($day);
306+
307+
$terminated = $this->termination_date && $this->asDateTime($this->termination_date)->startofDay()->lessThanOrEqualTo($day);
308+
309+
310+
return $expired || $terminated;
311+
}
299312
/**
300313
* Sets free_seat_count attribute
301314
*
@@ -596,7 +609,7 @@ public static function unReassignableCount($license) : int
596609
{
597610
$count = 0;
598611
if (!$license->reassignable) {
599-
$count = licenseSeat::query()->where('unreassignable_seat', '=', true)
612+
$count = LicenseSeat::query()->where('unreassignable_seat', '=', true)
600613
->where('license_id', '=', $license->id)
601614
->count();
602615
}
@@ -695,23 +708,45 @@ public function freeSeats()
695708
}
696709

697710
/**
698-
* Returns expiring licenses
711+
* Returns expiring licenses.
712+
*
713+
* This checks if:
699714
*
700-
* @todo should refactor. I don't like get() in model methods
715+
* 1) The license has not been deleted
716+
* 2) The expiration date is between now and the number of days specified
717+
* 3) There is an expiration date set and the termination date has not passed
718+
* 4) The license termination date is null or has not passed
701719
*
702720
* @author A. Gianotto <[email protected]>
703721
* @since [v1.0]
704722
* @return \Illuminate\Database\Eloquent\Relations\Relation
723+
* @see \App\Console\Commands\SendExpiringLicenseNotifications
705724
*/
706725
public static function getExpiringLicenses($days = 60)
707726
{
708-
$days = (is_null($days)) ? 60 : $days;
709727

710-
return self::whereNotNull('expiration_date')
711-
->whereNull('deleted_at')
712-
->whereRaw('DATE_SUB(`expiration_date`,INTERVAL '.$days.' DAY) <= DATE(NOW()) ')
713-
->where('expiration_date', '>', date('Y-m-d'))
728+
return self::whereNull('deleted_at')
729+
730+
// The termination date is null or within range
731+
->where(function ($query) use ($days) {
732+
$query->whereNull('termination_date')
733+
->orWhereBetween('termination_date', [Carbon::now(), Carbon::now()->addDays($days)]);
734+
})
735+
->where(function ($query) use ($days) {
736+
$query->whereNotNull('expiration_date')
737+
// Handle expired licenses without termination dates
738+
->where(function ($query) use ($days) {
739+
$query->whereNull('termination_date')
740+
->whereBetween('expiration_date', [Carbon::now(), Carbon::now()->addDays($days)]);
741+
})
742+
743+
// Handle expired licenses with termination dates in the future
744+
->orWhere(function ($query) use ($days) {
745+
$query->whereBetween('termination_date', [Carbon::now(), Carbon::now()->addDays($days)]);
746+
});
747+
})
714748
->orderBy('expiration_date', 'ASC')
749+
->orderBy('termination_date', 'ASC')
715750
->get();
716751
}
717752

app/Presenters/LicensePresenter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ public static function dataTableLayout()
202202
'switchable' => false,
203203
'title' => trans('general.checkin').'/'.trans('general.checkout'),
204204
'visible' => true,
205-
'formatter' => 'licensesInOutFormatter',
205+
'formatter' => 'licenseInOutFormatter',
206206
'printIgnore' => true,
207207
];
208208

resources/lang/en-US/admin/licenses/message.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
'not_enough_seats' => 'Not enough license seats available for checkout',
4747
'mismatch' => 'The license seat provided does not match the license',
4848
'unavailable' => 'This seat is not available for checkout.',
49+
'license_is_inactive' => 'This license is expired or terminated.',
4950
),
5051

5152
'checkin' => array(

0 commit comments

Comments
 (0)