2016-03-25 01:18:05 -07:00
< ? php
2021-06-10 13:15:52 -07:00
2016-03-25 01:18:05 -07:00
namespace App\Models ;
2022-08-29 11:26:47 -07:00
use App\Helpers\Helper ;
2018-07-16 14:13:07 -07:00
use App\Models\Traits\Searchable ;
2016-12-23 17:52:00 -08:00
use App\Presenters\Presentable ;
2017-01-10 16:19:18 -08:00
use Carbon\Carbon ;
2024-05-29 04:38:15 -07:00
use Illuminate\Support\Facades\DB ;
2021-06-10 13:19:27 -07:00
use Illuminate\Database\Eloquent\Factories\HasFactory ;
2016-03-25 01:18:05 -07:00
use Illuminate\Database\Eloquent\SoftDeletes ;
2017-01-10 16:19:18 -08:00
use Illuminate\Support\Facades\Auth ;
use Illuminate\Support\Facades\Session ;
2016-09-06 19:39:42 -07:00
use Watson\Validating\ValidatingTrait ;
2016-03-25 01:18:05 -07:00
class License extends Depreciable
{
2021-06-10 13:17:44 -07:00
use HasFactory ;
2021-06-10 13:16:56 -07:00
protected $presenter = \App\Presenters\LicensePresenter :: class ;
2018-05-08 00:14:38 -07:00
2016-03-25 01:18:05 -07:00
use SoftDeletes ;
use CompanyableTrait ;
2016-12-23 17:52:00 -08:00
use Loggable , Presentable ;
2016-03-25 01:18:05 -07:00
protected $injectUniqueIdentifier = true ;
use ValidatingTrait ;
2017-11-09 13:27:58 -08:00
// We set these as protected dates so that they will be easily accessible via Carbon
2021-06-10 13:17:18 -07:00
2016-03-25 01:18:05 -07:00
public $timestamps = true ;
protected $guarded = 'id' ;
protected $table = 'licenses' ;
2020-04-22 06:37:40 -07:00
2023-10-31 05:24:48 -07:00
2020-04-22 06:37:40 -07:00
protected $casts = [
2023-04-11 23:35:41 -07:00
'purchase_date' => 'date' ,
'expiration_date' => 'date' ,
'termination_date' => 'date' ,
2020-04-22 06:37:40 -07:00
'category_id' => 'integer' ,
'company_id' => 'integer' ,
];
2021-06-10 13:15:52 -07:00
protected $rules = [
2016-03-25 01:18:05 -07:00
'name' => 'required|string|min:3|max:255' ,
2022-01-10 10:54:57 -08:00
'seats' => 'required|min:1|integer' ,
2017-09-27 22:11:20 -07:00
'license_email' => 'email|nullable|max:120' ,
'license_name' => 'string|nullable|max:100' ,
'notes' => 'string|nullable' ,
2018-05-16 18:35:11 -07:00
'category_id' => 'required|exists:categories,id' ,
2016-12-14 11:12:21 -08:00
'company_id' => 'integer|nullable' ,
2022-05-10 16:26:06 -07:00
'purchase_cost' => 'numeric|nullable|gte:0' ,
2024-07-24 12:13:01 -07:00
'purchase_date' => 'date_format:Y-m-d|nullable|max:10|required_with:depreciation_id' ,
2023-04-12 08:26:36 -07:00
'expiration_date' => 'date_format:Y-m-d|nullable|max:10' ,
'termination_date' => 'date_format:Y-m-d|nullable|max:10' ,
2024-02-28 03:08:47 -08:00
'min_amt' => 'numeric|nullable|gte:0' ,
2021-06-10 13:15:52 -07:00
];
2016-03-25 01:18:05 -07:00
2021-06-10 13:15:52 -07:00
/**
* The attributes that are mass assignable .
*
* @ var array
*/
2017-01-10 16:19:18 -08:00
protected $fillable = [
2018-02-25 12:10:02 -08:00
'company_id' ,
'depreciation_id' ,
'expiration_date' ,
'license_email' ,
'license_name' , //actually licensed_to
'maintained' ,
'manufacturer_id' ,
2018-05-04 21:01:38 -07:00
'category_id' ,
2017-01-10 16:19:18 -08:00
'name' ,
2018-02-25 12:10:02 -08:00
'notes' ,
2017-01-10 16:19:18 -08:00
'order_number' ,
2018-02-25 12:10:02 -08:00
'purchase_cost' ,
'purchase_date' ,
'purchase_order' ,
'reassignable' ,
2017-01-10 16:19:18 -08:00
'seats' ,
2018-02-25 12:10:02 -08:00
'serial' ,
2017-01-10 16:19:18 -08:00
'supplier_id' ,
'termination_date' ,
2024-04-22 17:58:49 -07:00
'free_seat_count' ,
2018-02-25 12:10:02 -08:00
'user_id' ,
2024-02-28 03:08:47 -08:00
'min_amt' ,
2017-01-10 16:19:18 -08:00
];
2018-07-16 14:13:07 -07:00
use Searchable ;
2021-06-10 13:15:52 -07:00
2018-07-16 14:13:07 -07:00
/**
* The attributes that should be included when searching the model .
2021-06-10 13:15:52 -07:00
*
2018-07-16 14:13:07 -07:00
* @ var array
*/
protected $searchableAttributes = [
2021-06-10 13:15:52 -07:00
'name' ,
'serial' ,
'notes' ,
'order_number' ,
'purchase_order' ,
'purchase_cost' ,
2018-07-16 14:13:07 -07:00
'purchase_date' ,
'expiration_date' ,
];
/**
* The relations and their attributes that should be included when searching the model .
2021-06-10 13:15:52 -07:00
*
2018-07-16 14:13:07 -07:00
* @ var array
*/
protected $searchableRelations = [
2023-04-18 02:06:32 -07:00
'manufacturer' => [ 'name' ],
'company' => [ 'name' ],
'category' => [ 'name' ],
'depreciation' => [ 'name' ],
2018-08-01 00:06:41 -07:00
];
2024-04-22 17:58:49 -07:00
protected $appends = [ 'free_seat_count' ];
2018-07-16 14:13:07 -07:00
2018-08-01 00:06:41 -07:00
/**
* Update seat counts when the license is updated
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v3 . 0 ]
*/
2017-01-10 16:19:18 -08:00
public static function boot ()
{
parent :: boot ();
// We need to listen for created for the initial setup so that we have a license ID.
static :: created ( function ( $license ) {
$newSeatCount = $license -> getAttributes ()[ 'seats' ];
2021-06-10 13:15:52 -07:00
2023-01-04 13:02:53 -08:00
return static :: adjustSeatCount ( $license , 0 , $newSeatCount );
2017-01-10 16:19:18 -08:00
});
// However, we listen for updating to be able to prevent the edit if we cannot delete enough seats.
static :: updating ( function ( $license ) {
$newSeatCount = $license -> getAttributes ()[ 'seats' ];
2023-01-04 13:02:53 -08:00
//$oldSeatCount = isset($license->getOriginal()['seats']) ? $license->getOriginal()['seats'] : 0;
/*
That previous method * did * mostly work , but if you ever managed to get your $license -> seats value out of whack
with your actual count of license_seats * records * , you would never manage to get back 'into whack' .
The below method actually grabs a count of existing license_seats records , so it will be more accurate .
This means that if your license_seats are out of whack , you can change the quantity and hit 'save' and it
will manage to 'true up' and make your counts line up correctly .
*/
$oldSeatCount = $license -> license_seats_count ;
2021-06-10 13:15:52 -07:00
2017-01-10 16:19:18 -08:00
return static :: adjustSeatCount ( $license , $oldSeatCount , $newSeatCount );
});
}
2018-08-01 00:06:41 -07:00
/**
* Balance seat counts
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2017-01-10 16:19:18 -08:00
public static function adjustSeatCount ( $license , $oldSeats , $newSeats )
{
// If the seats haven't changed, continue on happily.
2021-06-10 13:15:52 -07:00
if ( $oldSeats == $newSeats ) {
2017-01-10 16:19:18 -08:00
return true ;
}
// On Create, we just make one for each of the seats.
$change = abs ( $oldSeats - $newSeats );
if ( $oldSeats > $newSeats ) {
$license -> load ( 'licenseseats.user' );
2018-05-04 21:01:38 -07:00
2017-01-10 16:19:18 -08:00
// Need to delete seats... lets see if if we have enough.
$seatsAvailableForDelete = $license -> licenseseats -> reject ( function ( $seat ) {
2021-06-10 13:15:52 -07:00
return (( bool ) $seat -> assigned_to ) || (( bool ) $seat -> asset_id );
2017-01-10 16:19:18 -08:00
});
if ( $change > $seatsAvailableForDelete -> count ()) {
Session :: flash ( 'error' , trans ( 'admin/licenses/message.assoc_users' ));
2021-06-10 13:15:52 -07:00
2017-01-10 16:19:18 -08:00
return false ;
}
2021-06-10 13:15:52 -07:00
for ( $i = 1 ; $i <= $change ; $i ++ ) {
2017-01-10 16:19:18 -08:00
$seatsAvailableForDelete -> pop () -> delete ();
}
// Log Deletion of seats.
$logAction = new Actionlog ;
2021-06-10 13:15:52 -07:00
$logAction -> item_type = self :: class ;
2017-01-10 16:19:18 -08:00
$logAction -> item_id = $license -> id ;
$logAction -> user_id = Auth :: id () ? : 1 ; // We don't have an id while running the importer from CLI.
$logAction -> note = " deleted ${ change } seats " ;
2021-06-10 13:15:52 -07:00
$logAction -> target_id = null ;
2017-01-10 16:19:18 -08:00
$logAction -> logaction ( 'delete seats' );
2021-06-10 13:15:52 -07:00
2017-01-10 16:19:18 -08:00
return true ;
}
// Else we're adding seats.
2022-01-10 10:54:57 -08:00
//Create enough seats for the change.
$licenseInsert = [];
for ( $i = $oldSeats ; $i < $newSeats ; $i ++ ) {
$licenseInsert [] = [
'user_id' => Auth :: id (),
'license_id' => $license -> id ,
'created_at' => now (),
'updated_at' => now ()
];
}
//Chunk and use DB transactions to prevent timeouts.
2022-04-12 13:04:57 -07:00
2022-01-10 10:54:57 -08:00
collect ( $licenseInsert ) -> chunk ( 1000 ) -> each ( function ( $chunk ) {
DB :: transaction ( function () use ( $chunk ) {
LicenseSeat :: insert ( $chunk -> toArray ());
});
2017-01-10 16:19:18 -08:00
});
2022-01-10 10:54:57 -08:00
// On initial create, we shouldn't log the addition of seats.
2017-01-10 16:19:18 -08:00
if ( $license -> id ) {
//Log the addition of license to the log.
$logAction = new Actionlog ();
2021-06-10 13:15:52 -07:00
$logAction -> item_type = self :: class ;
2017-01-10 16:19:18 -08:00
$logAction -> item_id = $license -> id ;
$logAction -> user_id = Auth :: id () ? : 1 ; // Importer.
$logAction -> note = " added ${ change } seats " ;
2021-06-10 13:15:52 -07:00
$logAction -> target_id = null ;
2017-01-10 16:19:18 -08:00
$logAction -> logaction ( 'add seats' );
}
2021-06-10 13:15:52 -07:00
2017-01-10 16:19:18 -08:00
return true ;
}
2018-08-01 00:06:41 -07:00
/**
* Sets the attribute for whether or not the license is maintained
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v1 . 0 ]
* @ return mixed
*/
2017-01-10 16:19:18 -08:00
public function setMaintainedAttribute ( $value )
{
$this -> attributes [ 'maintained' ] = filter_var ( $value , FILTER_VALIDATE_BOOLEAN );
}
2018-08-01 00:06:41 -07:00
/**
* Sets the reassignable attribute
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v1 . 0 ]
* @ return mixed
*/
2017-01-10 16:19:18 -08:00
public function setReassignableAttribute ( $value )
{
$this -> attributes [ 'reassignable' ] = filter_var ( $value , FILTER_VALIDATE_BOOLEAN );
}
2018-08-01 00:06:41 -07:00
/**
* Sets expiration date attribute
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v1 . 0 ]
* @ return mixed
*/
2016-12-26 15:17:46 -08:00
public function setExpirationDateAttribute ( $value )
{
2016-12-29 14:02:18 -08:00
if ( $value == '' || $value == '0000-00-00' ) {
2016-12-26 15:17:46 -08:00
$value = null ;
2017-01-10 16:19:18 -08:00
} else {
$value = ( new Carbon ( $value )) -> toDateString ();
2016-12-26 15:17:46 -08:00
}
$this -> attributes [ 'expiration_date' ] = $value ;
}
2018-08-01 00:06:41 -07:00
/**
* Sets termination date attribute
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
* @ return mixed
*/
2016-12-26 15:17:46 -08:00
public function setTerminationDateAttribute ( $value )
{
2016-12-29 14:02:18 -08:00
if ( $value == '' || $value == '0000-00-00' ) {
2016-12-26 15:17:46 -08:00
$value = null ;
2017-01-10 16:19:18 -08:00
} else {
$value = ( new Carbon ( $value )) -> toDateString ();
2016-12-26 15:17:46 -08:00
}
$this -> attributes [ 'termination_date' ] = $value ;
}
2024-04-22 17:58:49 -07:00
/**
* Sets free_seat_count attribute
*
* @ author G . Martinez
* @ since [ v6 . 3 ]
* @ return mixed
*/
public function getFreeSeatCountAttribute (){
return $this -> attributes [ 'free_seat_count' ] = $this -> remaincount ();
}
2016-12-26 15:17:46 -08:00
2018-08-01 00:06:41 -07:00
/**
* Establishes the license -> company relationship
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-03-25 01:18:05 -07:00
public function company ()
{
2021-06-10 13:16:56 -07:00
return $this -> belongsTo ( \App\Models\Company :: class , 'company_id' );
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the license -> category relationship
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v4 . 4.0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2018-05-04 21:01:38 -07:00
public function category ()
{
2021-06-10 13:16:56 -07:00
return $this -> belongsTo ( \App\Models\Category :: class , 'category_id' );
2018-05-04 21:01:38 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the license -> manufacturer relationship
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-08-16 18:49:54 -07:00
public function manufacturer ()
{
2021-06-10 13:16:56 -07:00
return $this -> belongsTo ( \App\Models\Manufacturer :: class , 'manufacturer_id' );
2016-08-16 18:49:54 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Determine whether the user should be emailed on checkin / checkout
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
2021-06-10 13:15:52 -07:00
* @ return bool
2018-08-01 00:06:41 -07:00
*/
2018-05-04 21:01:38 -07:00
public function checkin_email ()
{
2023-09-06 10:54:11 -07:00
if ( $this -> category ) {
return $this -> category -> checkin_email ;
}
return false ;
2018-05-04 21:01:38 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Determine whether the user should be required to accept the license
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v4 . 0 ]
2021-06-10 13:15:52 -07:00
* @ return bool
2018-08-01 00:06:41 -07:00
*/
2018-05-04 21:01:38 -07:00
public function requireAcceptance ()
{
2023-09-06 10:54:11 -07:00
if ( $this -> category ) {
return $this -> category -> require_acceptance ;
}
return false ;
2018-05-04 21:01:38 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Checks for a category - specific EULA , and if that doesn ' t exist ,
* checks for a settings level EULA
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
* @ return string | false
*/
2018-05-04 21:01:38 -07:00
public function getEula ()
{
2023-09-06 10:54:11 -07:00
if ( $this -> category ){
if ( $this -> category -> eula_text ) {
return Helper :: parseEscapedMarkedown ( $this -> category -> eula_text );
} elseif ( $this -> category -> use_default_eula == '1' ) {
return Helper :: parseEscapedMarkedown ( Setting :: getSettings () -> default_eula_text );
}
2018-05-04 21:01:38 -07:00
}
2023-09-06 10:54:11 -07:00
return false ;
2018-05-04 21:01:38 -07:00
}
2016-03-25 01:18:05 -07:00
/**
2018-08-01 00:06:41 -07:00
* Establishes the license -> assigned user relationship
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
2016-03-25 01:18:05 -07:00
*/
public function assignedusers ()
{
2022-10-16 23:10:09 -07:00
return $this -> belongsToMany ( \App\Models\User :: class , 'license_seats' , 'license_id' , 'assigned_to' );
2016-03-25 01:18:05 -07:00
}
/**
2018-08-01 00:06:41 -07:00
* Establishes the license -> action logs relationship
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-03-25 01:18:05 -07:00
public function assetlog ()
{
2021-06-10 13:16:56 -07:00
return $this -> hasMany ( \App\Models\Actionlog :: class , 'item_id' )
2021-06-10 13:15:52 -07:00
-> where ( 'item_type' , '=' , self :: class )
2016-03-25 01:18:05 -07:00
-> orderBy ( 'created_at' , 'desc' );
}
/**
2018-08-01 00:06:41 -07:00
* Establishes the license -> action logs -> uploads relationship
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-03-25 01:18:05 -07:00
public function uploads ()
{
2021-06-10 13:16:56 -07:00
return $this -> hasMany ( \App\Models\Actionlog :: class , 'item_id' )
2021-06-10 13:15:52 -07:00
-> where ( 'item_type' , '=' , self :: class )
2016-03-25 01:18:05 -07:00
-> where ( 'action_type' , '=' , 'uploaded' )
-> whereNotNull ( 'filename' )
-> orderBy ( 'created_at' , 'desc' );
}
/**
2018-08-01 00:06:41 -07:00
* Establishes the license -> admin user relationship
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-03-25 01:18:05 -07:00
public function adminuser ()
{
2021-06-10 13:16:56 -07:00
return $this -> belongsTo ( \App\Models\User :: class , 'user_id' );
2016-03-25 01:18:05 -07:00
}
/**
2018-08-01 00:06:41 -07:00
* Returns the total number of all license seats
*
* @ todo this can probably be refactored at some point . We don ' t need counting methods .
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
* @ return int
*/
2016-03-25 01:18:05 -07:00
public static function assetcount ()
{
return LicenseSeat :: whereNull ( 'deleted_at' )
2023-04-18 02:06:32 -07:00
-> count ();
2016-03-25 01:18:05 -07:00
}
/**
2018-08-01 00:06:41 -07:00
* Return the number of seats for this asset
*
* @ todo this can also probably be refactored at some point .
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-03-25 01:18:05 -07:00
public function totalSeatsByLicenseID ()
{
return LicenseSeat :: where ( 'license_id' , '=' , $this -> id )
2023-04-18 02:06:32 -07:00
-> whereNull ( 'deleted_at' )
-> count ();
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the license -> seat relationship
*
* We do this to eager load the " count " of seats from the controller .
* Otherwise calling " count() " on each model results in n + 1 sadness .
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2023-04-18 02:06:32 -07:00
public function licenseSeatsRelation ()
2016-10-28 14:15:13 -07:00
{
return $this -> hasMany ( LicenseSeat :: class ) -> whereNull ( 'deleted_at' ) -> selectRaw ( 'license_id, count(*) as count' ) -> groupBy ( 'license_id' );
}
2023-04-18 02:06:32 -07:00
/**
* Sets the license seat count attribute
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
* @ return int
*/
public function getLicenseSeatsCountAttribute ()
{
if ( $this -> licenseSeatsRelation -> first ()) {
return $this -> licenseSeatsRelation -> first () -> count ;
}
return 0 ;
}
2016-03-25 01:18:05 -07:00
/**
2023-04-18 02:06:32 -07:00
* Returns the number of total available seats across all licenses
2018-08-01 00:06:41 -07:00
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
* @ return int
*/
2023-04-18 02:06:32 -07:00
public static function availassetcount ()
2016-03-25 01:18:05 -07:00
{
return LicenseSeat :: whereNull ( 'assigned_to' )
2023-04-18 01:01:44 -07:00
-> whereNull ( 'asset_id' )
-> whereNull ( 'deleted_at' )
-> count ();
2016-03-25 01:18:05 -07:00
}
2024-04-22 17:58:49 -07:00
/**
* Returns the available seats remaining
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
* @ return int
*/
2023-04-18 02:06:32 -07:00
2016-03-25 01:18:05 -07:00
/**
2018-08-01 00:06:41 -07:00
* Returns the number of total available seats for this license
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v2 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
2016-03-25 01:18:05 -07:00
*/
2016-10-28 14:15:13 -07:00
public function availCount ()
2016-03-25 01:18:05 -07:00
{
2023-04-18 02:06:32 -07:00
return $this -> licenseSeatsRelation ()
2017-11-02 19:16:09 -07:00
-> whereNull ( 'asset_id' )
-> whereNull ( 'assigned_to' )
2017-11-02 21:07:59 -07:00
-> whereNull ( 'deleted_at' );
2016-10-28 14:15:13 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Sets the available seats attribute
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v3 . 0 ]
* @ return mixed
*/
2016-10-28 14:15:13 -07:00
public function getAvailSeatsCountAttribute ()
{
if ( $this -> availCount -> first ()) {
return $this -> availCount -> first () -> count ;
}
return 0 ;
2016-03-25 01:18:05 -07:00
}
/**
2018-08-01 00:06:41 -07:00
* Retuns the number of assigned seats for this asset
2016-03-25 01:18:05 -07:00
*
2018-08-01 00:06:41 -07:00
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
2016-03-25 01:18:05 -07:00
*/
2016-10-28 14:15:13 -07:00
public function assignedCount ()
2016-03-25 01:18:05 -07:00
{
2023-04-18 02:06:32 -07:00
return $this -> licenseSeatsRelation () -> where ( function ( $query ) {
2016-10-28 14:15:13 -07:00
$query -> whereNotNull ( 'assigned_to' )
2023-04-18 02:06:32 -07:00
-> orWhereNotNull ( 'asset_id' );
2016-10-28 14:15:13 -07:00
});
}
2016-03-25 01:18:05 -07:00
2018-08-01 00:06:41 -07:00
/**
* Sets the assigned seats attribute
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v1 . 0 ]
* @ return int
*/
2016-10-28 14:15:13 -07:00
public function getAssignedSeatsCountAttribute ()
{
if ( $this -> assignedCount -> first ()) {
return $this -> assignedCount -> first () -> count ;
}
2016-03-25 01:18:05 -07:00
2016-10-28 14:15:13 -07:00
return 0 ;
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Calculates the number of remaining seats
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v1 . 0 ]
* @ return int
*/
2016-03-25 01:18:05 -07:00
public function remaincount ()
{
2016-10-28 14:15:13 -07:00
$total = $this -> licenseSeatsCount ;
2021-06-10 13:15:52 -07:00
$taken = $this -> assigned_seats_count ;
$diff = ( $total - $taken );
2024-04-22 17:58:49 -07:00
return ( int ) $diff ;
2016-03-25 01:18:05 -07:00
}
/**
2018-08-01 00:06:41 -07:00
* Returns the total number of seats for this license
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v1 . 0 ]
* @ return int
2016-03-25 01:18:05 -07:00
*/
public function totalcount ()
{
2021-06-10 13:15:52 -07:00
$avail = $this -> availSeatsCount ;
$taken = $this -> assignedcount ();
$diff = ( $avail + $taken );
2016-03-25 01:18:05 -07:00
return $diff ;
}
/**
2018-08-01 00:06:41 -07:00
* Establishes the license -> seats relationship
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v1 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
2016-03-25 01:18:05 -07:00
*/
public function licenseseats ()
{
2021-06-10 13:16:56 -07:00
return $this -> hasMany ( \App\Models\LicenseSeat :: class );
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the license -> supplier relationship
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v1 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-03-25 01:18:05 -07:00
public function supplier ()
{
2021-06-10 13:16:56 -07:00
return $this -> belongsTo ( \App\Models\Supplier :: class , 'supplier_id' );
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Gets the next available free seat - used by
2017-09-25 21:40:43 -07:00
* the API to populate next_seat
2018-08-01 00:06:41 -07:00
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v3 . 0 ]
* @ return mixed
2017-09-25 21:40:43 -07:00
*/
2016-03-25 01:18:05 -07:00
public function freeSeat ()
{
2017-11-20 19:21:05 -08:00
return $this -> licenseseats ()
2023-04-18 02:06:32 -07:00
-> whereNull ( 'deleted_at' )
-> where ( function ( $query ) {
$query -> whereNull ( 'assigned_to' )
-> whereNull ( 'asset_id' );
})
-> orderBy ( 'id' , 'asc' )
-> first ();
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the license -> free seats relationship
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v1 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2017-11-02 19:16:09 -07:00
public function freeSeats ()
{
2021-06-10 13:16:56 -07:00
return $this -> hasMany ( \App\Models\LicenseSeat :: class ) -> whereNull ( 'assigned_to' ) -> whereNull ( 'deleted_at' ) -> whereNull ( 'asset_id' );
2017-11-02 19:16:09 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Returns expiring licenses
*
* @ todo should refactor . I don ' t like get () in model methods
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since [ v1 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-03-25 01:18:05 -07:00
public static function getExpiringLicenses ( $days = 60 )
{
2022-01-18 12:34:14 -08:00
$days = ( is_null ( $days )) ? 60 : $days ;
2021-06-10 13:15:52 -07:00
return self :: whereNotNull ( 'expiration_date' )
2023-04-18 02:06:32 -07:00
-> whereNull ( 'deleted_at' )
2023-10-18 13:25:34 -07:00
-> whereRaw ( 'DATE_SUB(`expiration_date`,INTERVAL ' . $days . ' DAY) <= DATE(NOW()) ' )
2023-04-18 02:06:32 -07:00
-> where ( 'expiration_date' , '>' , date ( 'Y-m-d' ))
-> orderBy ( 'expiration_date' , 'ASC' )
-> get ();
2016-03-25 01:18:05 -07:00
}
2016-11-11 19:46:18 -08:00
/**
* Query builder scope to order on manufacturer
*
2018-08-01 00:06:41 -07:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
* @ param string $order Order
2016-11-11 19:46:18 -08:00
*
2018-08-01 00:06:41 -07:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-11-11 19:46:18 -08:00
*/
public function scopeOrderManufacturer ( $query , $order )
{
return $query -> leftJoin ( 'manufacturers' , 'licenses.manufacturer_id' , '=' , 'manufacturers.id' ) -> select ( 'licenses.*' )
-> orderBy ( 'manufacturers.name' , $order );
}
2017-08-10 14:38:04 -07:00
/**
* Query builder scope to order on supplier
*
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2018-08-01 00:06:41 -07:00
* @ param string $order Order
2017-08-10 14:38:04 -07:00
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderSupplier ( $query , $order )
{
return $query -> leftJoin ( 'suppliers' , 'licenses.supplier_id' , '=' , 'suppliers.id' ) -> select ( 'licenses.*' )
-> orderBy ( 'suppliers.name' , $order );
}
2016-11-11 19:46:18 -08:00
/**
* Query builder scope to order on company
*
2018-08-01 00:06:41 -07:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-11-11 19:46:18 -08:00
* @ param text $order Order
*
2018-08-01 00:06:41 -07:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-11-11 19:46:18 -08:00
*/
public function scopeOrderCompany ( $query , $order )
{
return $query -> leftJoin ( 'companies as companies' , 'licenses.company_id' , '=' , 'companies.id' ) -> select ( 'licenses.*' )
-> orderBy ( 'companies.name' , $order );
}
2024-07-26 02:24:13 -07:00
/**
* Query builder scope to order on the user that created it
*
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
* @ param text $order Order
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderCreatedBy ( $query , $order )
{
return $query -> leftJoin ( 'users as users_sort' , 'licenses.user_id' , '=' , 'users_sort.id' ) -> select ( 'licenses.*' ) -> orderBy ( 'users_sort.first_name' , $order ) -> orderBy ( 'users_sort.last_name' , $order );
}
2023-04-18 02:06:32 -07:00
}