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 ;
2018-09-10 07:40:26 -07:00
use App\Events\CheckoutableCheckedOut ;
2020-04-29 07:59:00 -07:00
use App\Exceptions\CheckoutNotAllowed ;
2022-08-29 11:26:47 -07:00
use App\Helpers\Helper ;
2016-09-06 19:39:42 -07:00
use App\Http\Traits\UniqueUndeletedTrait ;
2018-07-28 04:09:21 -07:00
use App\Models\Traits\Acceptable ;
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 ;
2024-06-05 02:56:54 -07:00
use App\Presenters\AssetPresenter ;
2024-05-29 04:38:15 -07:00
use Illuminate\Support\Facades\Auth ;
2016-12-23 17:52:00 -08:00
use Carbon\Carbon ;
2024-05-29 04:38:15 -07:00
use Illuminate\Support\Facades\DB ;
2018-07-16 14:13:07 -07:00
use Illuminate\Database\Eloquent\Builder ;
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 ;
2018-09-29 21:33:52 -07:00
use Illuminate\Support\Facades\Storage ;
2016-03-25 01:18:05 -07:00
use Watson\Validating\ValidatingTrait ;
2024-06-05 02:56:54 -07:00
use Illuminate\Database\Eloquent\Casts\Attribute ;
use Illuminate\Database\Eloquent\Model ;
2016-03-25 01:18:05 -07:00
2016-04-07 13:21:09 -07:00
/**
* Model for Assets .
*
* @ version v1 . 0
*/
2016-03-25 01:18:05 -07:00
class Asset extends Depreciable
{
2021-06-10 13:17:44 -07:00
2024-06-05 02:56:54 -07:00
protected $presenter = AssetPresenter :: class ;
2024-08-10 09:00:20 -07:00
protected $with = [ 'model' , 'admin' ];
2021-10-20 17:26:41 -07:00
2021-06-15 01:32:44 -07:00
use CompanyableTrait ;
2023-11-15 10:50:40 -08:00
use HasFactory , Loggable , Requestable , Presentable , SoftDeletes , ValidatingTrait , UniqueUndeletedTrait ;
2016-03-25 01:18:05 -07:00
2023-02-06 12:44:02 -08:00
public const LOCATION = 'location' ;
public const ASSET = 'asset' ;
public const USER = 'user' ;
2018-03-25 13:46:57 -07:00
2018-07-28 04:09:21 -07:00
use Acceptable ;
2018-03-25 13:46:57 -07:00
/**
2018-07-28 04:09:21 -07:00
* Run after the checkout acceptance was declined by the user
2018-07-27 16:16:42 -07:00
*
2018-07-28 04:09:21 -07:00
* @ param User $acceptedBy
* @ param string $signature
*/
2021-06-10 13:15:52 -07:00
public function declinedCheckout ( User $declinedBy , $signature )
{
2018-07-27 16:16:42 -07:00
$this -> assigned_to = null ;
$this -> assigned_type = null ;
$this -> accepted = null ;
2018-07-28 04:09:21 -07:00
$this -> save ();
2018-07-27 16:16:42 -07:00
}
2018-03-25 13:46:57 -07:00
/**
* The database table used by the model .
*
* @ var string
*/
2016-03-25 01:18:05 -07:00
protected $table = 'assets' ;
2024-05-28 10:03:19 -07:00
/**
* Leaving this commented out , since we need to test further , but this would eager load the model relationship every single
* time the asset model is loaded .
*/
// protected $with = ['model'];
2018-03-25 13:46:57 -07:00
/**
* Whether the model should inject it ' s identifier to the unique
* validation rules before attempting validation . If this property
* is not set in the model it will default to true .
*
2021-06-10 13:15:52 -07:00
* @ var bool
2018-03-25 13:46:57 -07:00
*/
2016-03-25 01:18:05 -07:00
protected $injectUniqueIdentifier = true ;
2017-03-03 17:30:19 -08:00
2020-04-22 06:37:40 -07:00
protected $casts = [
2023-01-24 17:37:15 -08:00
'purchase_date' => 'date' ,
2023-10-13 11:32:09 -07:00
'eol_explicit' => 'boolean' ,
2021-06-10 13:17:18 -07:00
'last_checkout' => 'datetime' ,
2023-08-21 11:57:33 -07:00
'last_checkin' => 'datetime' ,
2024-04-26 11:01:05 -07:00
'expected_checkin' => 'datetime:m-d-Y' ,
2021-06-10 13:17:18 -07:00
'last_audit_date' => 'datetime' ,
2024-04-26 11:01:05 -07:00
'next_audit_date' => 'datetime:m-d-Y' ,
2020-04-22 06:37:40 -07:00
'model_id' => 'integer' ,
'status_id' => 'integer' ,
'company_id' => 'integer' ,
'location_id' => 'integer' ,
'rtd_company_id' => 'integer' ,
'supplier_id' => 'integer' ,
2023-03-29 19:37:26 -07:00
'created_at' => 'datetime' ,
'updated_at' => 'datetime' ,
'deleted_at' => 'datetime' ,
2020-04-22 06:37:40 -07:00
];
2016-03-25 01:18:05 -07:00
2024-03-13 13:10:51 -07:00
protected $rules = [
2024-05-23 13:51:26 -07:00
'model_id' => [ 'required' , 'integer' , 'exists:models,id,deleted_at,NULL' , 'not_array' ],
'status_id' => [ 'required' , 'integer' , 'exists:status_labels,id' ],
'asset_tag' => [ 'required' , 'min:1' , 'max:255' , 'unique_undeleted:assets,asset_tag' , 'not_array' ],
'name' => [ 'nullable' , 'max:255' ],
'company_id' => [ 'nullable' , 'integer' , 'exists:companies,id' ],
'warranty_months' => [ 'nullable' , 'numeric' , 'digits_between:0,240' ],
'last_checkout' => [ 'nullable' , 'date_format:Y-m-d H:i:s' ],
'last_checkin' => [ 'nullable' , 'date_format:Y-m-d H:i:s' ],
'expected_checkin' => [ 'nullable' , 'date' ],
'last_audit_date' => [ 'nullable' , 'date_format:Y-m-d H:i:s' ],
'next_audit_date' => [ 'nullable' , 'date' ],
2024-05-23 11:53:00 -07:00
//'after:last_audit_date'],
2024-05-23 13:51:26 -07:00
'location_id' => [ 'nullable' , 'exists:locations,id' ],
'rtd_location_id' => [ 'nullable' , 'exists:locations,id' ],
'purchase_date' => [ 'nullable' , 'date' , 'date_format:Y-m-d' ],
'serial' => [ 'nullable' , 'unique_undeleted:assets,serial' ],
'purchase_cost' => [ 'nullable' , 'numeric' , 'gte:0' ],
'supplier_id' => [ 'nullable' , 'exists:suppliers,id' ],
'asset_eol_date' => [ 'nullable' , 'date' ],
'eol_explicit' => [ 'nullable' , 'boolean' ],
'byod' => [ 'nullable' , 'boolean' ],
'order_number' => [ 'nullable' , 'string' , 'max:191' ],
'notes' => [ 'nullable' , 'string' , 'max:65535' ],
'assigned_to' => [ 'nullable' , 'integer' ],
'requestable' => [ 'nullable' , 'boolean' ],
'assigned_user' => [ 'nullable' , 'exists:users,id,deleted_at,NULL' ],
'assigned_location' => [ 'nullable' , 'exists:locations,id,deleted_at,NULL' ],
'assigned_asset' => [ 'nullable' , 'exists:assets,id,deleted_at,NULL' ]
2024-03-13 13:10:51 -07:00
];
2016-03-25 01:18:05 -07:00
2024-03-27 11:53:57 -07:00
/**
2016-03-25 01:18:05 -07:00
* The attributes that are mass assignable .
*
* @ var array
*/
2017-01-10 16:19:18 -08:00
protected $fillable = [
'asset_tag' ,
'assigned_to' ,
2017-09-18 16:40:13 -07:00
'assigned_type' ,
2017-01-10 16:19:18 -08:00
'company_id' ,
'image' ,
2018-03-29 05:11:07 -07:00
'location_id' ,
2017-01-10 16:19:18 -08:00
'model_id' ,
'name' ,
'notes' ,
2017-10-26 16:13:35 -07:00
'order_number' ,
2017-01-10 16:19:18 -08:00
'purchase_cost' ,
'purchase_date' ,
'rtd_location_id' ,
'serial' ,
'status_id' ,
'supplier_id' ,
'warranty_months' ,
2020-02-03 19:37:03 -08:00
'requestable' ,
2020-11-11 13:30:11 -08:00
'last_checkout' ,
2020-11-13 03:22:26 -08:00
'expected_checkin' ,
2023-01-18 13:04:36 -08:00
'byod' ,
2023-01-22 00:56:19 -08:00
'asset_eol_date' ,
2024-06-19 03:37:15 -07:00
'eol_explicit' ,
2023-01-24 17:36:58 -08:00
'last_audit_date' ,
'next_audit_date' ,
2023-09-12 16:03:13 -07:00
'asset_eol_date' ,
2024-05-30 15:02:23 -07:00
'last_checkin' ,
'last_checkout' ,
2017-01-10 16:19:18 -08:00
];
2016-03-25 01:18:05 -07:00
2018-07-16 14:13:07 -07:00
use Searchable ;
2017-10-31 05:21:55 -07:00
2018-07-16 14:13:07 -07:00
/**
* The attributes that should be included when searching the model .
2024-06-19 03:37:15 -07:00
*
2018-07-16 14:13:07 -07:00
* @ var array
*/
protected $searchableAttributes = [
2024-06-19 03:37:15 -07:00
'name' ,
'asset_tag' ,
'serial' ,
'order_number' ,
'purchase_cost' ,
'notes' ,
2018-07-16 14:13:07 -07:00
'created_at' ,
2024-06-19 03:37:15 -07:00
'updated_at' ,
'purchase_date' ,
'expected_checkin' ,
'next_audit_date' ,
2021-06-10 13:15:52 -07:00
'last_audit_date' ,
2024-03-27 13:37:40 -07:00
'last_checkin' ,
'last_checkout' ,
2023-01-22 00:56:19 -08:00
'asset_eol_date' ,
2018-07-16 14:13:07 -07:00
];
/**
* The relations and their attributes that should be included when searching the model .
2024-06-19 03:37:15 -07:00
*
2018-07-16 14:13:07 -07:00
* @ var array
*/
protected $searchableRelations = [
'assetstatus' => [ 'name' ],
'supplier' => [ 'name' ],
'company' => [ 'name' ],
'defaultLoc' => [ 'name' ],
2020-11-24 19:49:46 -08:00
'location' => [ 'name' ],
2023-01-22 00:56:19 -08:00
'model' => [ 'name' , 'model_number' , 'eol' ],
2018-07-16 14:13:07 -07:00
'model.category' => [ 'name' ],
'model.manufacturer' => [ 'name' ],
2018-09-29 21:33:52 -07:00
];
2023-02-19 10:31:10 -08:00
// To properly set the expected checkin as Y-m-d
public function setExpectedCheckinAttribute ( $value )
{
if ( $value == '' ) {
$value = null ;
}
$this -> attributes [ 'expected_checkin' ] = $value ;
}
2018-09-29 21:33:52 -07:00
/**
* This handles the custom field validation for assets
*
* @ var array
*/
2018-10-02 04:40:20 -07:00
public function save ( array $params = [])
2018-09-29 21:33:52 -07:00
{
2021-06-10 13:15:52 -07:00
if ( $this -> model_id != '' ) {
2018-09-29 21:33:52 -07:00
$model = AssetModel :: find ( $this -> model_id );
if (( $model ) && ( $model -> fieldset )) {
2022-03-29 08:28:43 -07:00
foreach ( $model -> fieldset -> fields as $field ){
if ( $field -> format == 'BOOLEAN' ){
$this -> { $field -> db_column } = filter_var ( $this -> { $field -> db_column }, FILTER_VALIDATE_BOOLEAN );
}
}
2024-03-20 13:23:45 -07:00
$this -> rules += $model -> fieldset -> validation_rules ();
2018-09-29 21:33:52 -07:00
2023-10-31 09:00:36 -07:00
if ( $this -> model -> fieldset ){
foreach ( $this -> model -> fieldset -> fields as $field ){
if ( $field -> format == 'BOOLEAN' ){
$this -> { $field -> db_column } = filter_var ( $this -> { $field -> db_column }, FILTER_VALIDATE_BOOLEAN );
}
2022-03-22 08:38:57 -07:00
}
}
2022-03-09 16:49:39 -08:00
}
}
2018-09-29 21:33:52 -07:00
return parent :: save ( $params );
}
2017-10-31 05:21:55 -07:00
2016-12-23 17:52:00 -08:00
public function getDisplayNameAttribute ()
{
return $this -> present () -> name ();
}
2016-03-25 01:18:05 -07:00
2017-03-14 08:37:39 -07:00
/**
* Returns the warranty expiration date as Carbon object
* @ return \Carbon | null
*/
public function getWarrantyExpiresAttribute ()
{
if ( isset ( $this -> attributes [ 'warranty_months' ]) && isset ( $this -> attributes [ 'purchase_date' ])) {
if ( is_string ( $this -> attributes [ 'purchase_date' ]) || is_string ( $this -> attributes [ 'purchase_date' ])) {
$purchase_date = \Carbon\Carbon :: parse ( $this -> attributes [ 'purchase_date' ]);
} else {
$purchase_date = \Carbon\Carbon :: instance ( $this -> attributes [ 'purchase_date' ]);
}
$purchase_date -> setTime ( 0 , 0 , 0 );
2021-06-10 13:15:52 -07:00
2017-03-14 08:37:39 -07:00
return $purchase_date -> addMonths (( int ) $this -> attributes [ 'warranty_months' ]);
}
return null ;
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the asset -> company relationship
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 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
/**
2020-11-10 05:06:47 -08:00
* Determines if an asset is available for checkout .
2023-11-28 05:32:47 -08:00
* This checks to see if it ' s checked out to an invalid ( deleted ) user
2020-11-10 05:06:47 -08:00
* OR if the assigned_to and deleted_at fields on the asset are empty AND
* that the status is deployable
2018-08-01 00:06:41 -07:00
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
2021-06-10 13:15:52 -07:00
* @ return bool
2018-08-01 00:06:41 -07:00
*/
2016-08-16 13:02:42 -07:00
public function availableForCheckout ()
{
2021-01-26 22:12:24 -08:00
// This asset is not currently assigned to anyone and is not deleted...
2021-06-10 13:15:52 -07:00
if (( ! $this -> assigned_to ) && ( ! $this -> deleted_at )) {
2021-01-26 22:12:24 -08:00
// The asset status is not archived and is deployable
if (( $this -> assetstatus ) && ( $this -> assetstatus -> archived == '0' )
2024-06-19 03:37:15 -07:00
&& ( $this -> assetstatus -> deployable == '1' ))
2021-01-26 22:12:24 -08:00
{
return true ;
}
2017-10-28 02:31:54 -07:00
}
return false ;
2016-08-16 13:02:42 -07:00
}
2016-07-26 01:39:30 -07:00
2018-08-01 00:06:41 -07:00
2016-12-23 17:52:00 -08:00
/**
2018-08-01 00:06:41 -07:00
* Checks the asset out to the target
*
* @ todo The admin parameter is never used . Can probably be removed .
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
2016-12-23 17:52:00 -08:00
* @ param User $user
* @ param User $admin
* @ param Carbon $checkout_at
2017-11-08 18:03:27 -08:00
* @ param Carbon $expected_checkin
2016-12-23 17:52:00 -08:00
* @ param string $note
* @ param null $name
* @ return bool
2018-08-01 00:06:41 -07:00
* @ since [ v3 . 0 ]
2021-06-10 13:15:52 -07:00
* @ return bool
2016-12-23 17:52:00 -08:00
*/
2021-02-18 14:21:19 -08:00
public function checkOut ( $target , $admin = null , $checkout_at = null , $expected_checkin = null , $note = null , $name = null , $location = null )
2016-03-25 01:18:05 -07:00
{
2021-06-10 13:15:52 -07:00
if ( ! $target ) {
2016-08-16 13:02:42 -07:00
return false ;
}
2020-04-29 07:59:00 -07:00
if ( $this -> is ( $target )) {
throw new CheckoutNotAllowed ( 'You cannot check an asset out to itself.' );
}
2016-03-25 01:18:05 -07:00
if ( $expected_checkin ) {
2016-08-16 13:02:42 -07:00
$this -> expected_checkin = $expected_checkin ;
2016-03-25 01:18:05 -07:00
}
$this -> last_checkout = $checkout_at ;
2023-01-19 12:35:44 -08:00
$this -> name = $name ;
2016-03-25 01:18:05 -07:00
2016-12-27 16:24:41 -08:00
$this -> assignedTo () -> associate ( $target );
2017-11-03 19:39:48 -07:00
if ( $location != null ) {
$this -> location_id = $location ;
2017-12-28 20:08:45 -08:00
} else {
2020-04-09 18:32:34 -07:00
if ( isset ( $target -> location )) {
2017-12-28 20:08:45 -08:00
$this -> location_id = $target -> location -> id ;
}
2020-04-09 18:32:34 -07:00
if ( $target instanceof Location ) {
2018-07-23 06:47:21 -07:00
$this -> location_id = $target -> id ;
}
2017-11-03 19:39:48 -07:00
}
2016-03-25 01:18:05 -07:00
2023-08-31 20:12:07 -07:00
$originalValues = $this -> getRawOriginal ();
// attempt to detect change in value if different from today's date
if ( $checkout_at && strpos ( $checkout_at , date ( 'Y-m-d' )) === false ) {
$originalValues [ 'action_date' ] = date ( 'Y-m-d H:i:s' );
}
2016-03-25 01:18:05 -07:00
if ( $this -> save ()) {
2021-06-10 13:15:52 -07:00
if ( is_int ( $admin )) {
2021-04-05 19:28:31 -07:00
$checkedOutBy = User :: findOrFail ( $admin );
2021-06-10 13:16:56 -07:00
} elseif ( get_class ( $admin ) === \App\Models\User :: class ) {
2021-04-05 19:28:31 -07:00
$checkedOutBy = $admin ;
} else {
2024-07-04 12:49:22 -07:00
$checkedOutBy = auth () -> user ();
2021-04-05 19:28:31 -07:00
}
2023-08-31 20:12:07 -07:00
event ( new CheckoutableCheckedOut ( $this , $target , $checkedOutBy , $note , $originalValues ));
2021-02-18 14:21:19 -08:00
2018-05-16 19:20:43 -07:00
$this -> increment ( 'checkout_counter' , 1 );
2021-06-10 13:15:52 -07:00
2016-03-25 01:18:05 -07:00
return true ;
}
2021-06-10 13:15:52 -07:00
2016-03-25 01:18:05 -07:00
return false ;
}
2018-08-01 00:06:41 -07:00
/**
* Sets the detailedNameAttribute
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return string
*/
2016-06-22 12:27:41 -07:00
public function getDetailedNameAttribute ()
{
2017-09-29 17:14:38 -07:00
if ( $this -> assignedto ) {
$user_name = $this -> assignedto -> present () -> name ();
2016-06-22 12:27:41 -07:00
} else {
2021-06-10 13:15:52 -07:00
$user_name = 'Unassigned' ;
2016-06-22 12:27:41 -07:00
}
2021-06-10 13:15:52 -07:00
return $this -> asset_tag . ' - ' . $this -> name . ' (' . $user_name . ') ' . ( $this -> model ) ? $this -> model -> name : '' ;
2016-05-24 18:05:48 -07:00
}
2017-09-29 17:14:38 -07:00
2018-08-01 00:06:41 -07:00
/**
* Pulls in the validation rules
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return array
*/
public function validationRules ()
2016-03-25 01:18:05 -07:00
{
return $this -> rules ;
}
2016-04-23 02:07:40 -07:00
2016-05-18 19:26:50 -07:00
/**
2018-08-01 00:06:41 -07:00
* Establishes the asset -> depreciation relationship
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-03-25 01:18:05 -07:00
public function depreciation ()
{
2023-07-20 09:45:45 -07:00
return $this -> hasOneThrough ( \App\Models\Depreciation :: class , \App\Models\AssetModel :: class , 'id' , 'id' , 'model_id' , 'depreciation_id' );
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
2016-05-18 19:26:50 -07:00
/**
* Get components assigned to this asset
2018-08-01 00:06:41 -07:00
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
2016-05-18 19:26:50 -07:00
*/
public function components ()
{
2023-05-30 07:41:11 -07:00
return $this -> belongsToMany ( '\App\Models\Component' , 'components_assets' , 'asset_id' , 'component_id' ) -> withPivot ( 'id' , 'assigned_qty' , 'created_at' );
2016-05-18 19:26:50 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Get depreciation attribute from associated asset model
*
* @ todo Is this still needed ?
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-03-25 01:18:05 -07:00
public function get_depreciation ()
{
2018-01-25 11:06:37 -08:00
if (( $this -> model ) && ( $this -> model -> depreciation )) {
2018-01-25 03:34:52 -08:00
return $this -> model -> depreciation ;
}
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Get uploads for this asset
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-03-25 01:18:05 -07:00
public function uploads ()
{
2016-09-06 19:39:42 -07:00
return $this -> hasMany ( '\App\Models\Actionlog' , 'item_id' )
-> where ( 'item_type' , '=' , Asset :: class )
2016-03-25 01:18:05 -07:00
-> where ( 'action_type' , '=' , 'uploaded' )
-> whereNotNull ( 'filename' )
-> orderBy ( 'created_at' , 'desc' );
}
2016-12-29 06:31:16 -08:00
/**
2018-08-01 00:06:41 -07:00
* Determines whether the asset is checked out to a user
*
2016-12-29 06:31:16 -08:00
* Even though we allow allow for checkout to things beyond users
* this method is an easy way of seeing if we are checked out to a user .
2018-08-01 00:06:41 -07:00
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
2016-12-29 06:31:16 -08:00
*/
2023-11-30 10:06:58 -08:00
public function checkedOutToUser () : bool
2016-03-25 01:18:05 -07:00
{
2017-09-05 17:54:58 -07:00
return $this -> assignedType () === self :: USER ;
2016-03-25 01:18:05 -07:00
}
2023-11-30 10:06:58 -08:00
public function checkedOutToLocation () : bool
2023-11-30 09:53:26 -08:00
{
return $this -> assignedType () === self :: LOCATION ;
}
2023-11-30 10:06:58 -08:00
public function checkedOutToAsset () : bool
2023-11-30 09:53:26 -08:00
{
return $this -> assignedType () === self :: ASSET ;
}
2018-08-01 00:06:41 -07:00
/**
* Get the target this asset is checked out to
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-12-27 16:24:41 -08:00
public function assignedTo ()
{
2020-11-10 05:06:47 -08:00
return $this -> morphTo ( 'assigned' , 'assigned_type' , 'assigned_to' ) -> withTrashed ();
2016-12-27 16:24:41 -08:00
}
2018-08-01 00:06:41 -07:00
/**
* Gets assets assigned to this asset
*
* Sigh .
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-12-27 16:24:41 -08:00
public function assignedAssets ()
{
2021-06-10 13:19:27 -07:00
return $this -> morphMany ( self :: class , 'assigned' , 'assigned_type' , 'assigned_to' ) -> withTrashed ();
2016-12-27 16:24:41 -08:00
}
2018-08-01 00:06:41 -07:00
/**
* Get the asset ' s location based on the assigned user
*
* @ todo Refactor this if possible . It ' s awful .
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
* @ return \ArrayObject
*/
2021-06-10 13:15:52 -07:00
public function assetLoc ( $iterations = 1 , $first_asset = null )
2016-03-25 01:18:05 -07:00
{
2021-06-10 13:15:52 -07:00
if ( ! empty ( $this -> assignedType ())) {
2016-12-27 16:24:41 -08:00
if ( $this -> assignedType () == self :: ASSET ) {
2021-06-10 13:15:52 -07:00
if ( ! $first_asset ) {
$first_asset = $this ;
2017-10-28 01:48:27 -07:00
}
2021-06-10 13:15:52 -07:00
if ( $iterations > 10 ) {
throw new \Exception ( 'Asset assignment Loop for Asset ID: ' . $first_asset -> id );
2017-10-28 01:48:27 -07:00
}
2021-06-10 13:15:52 -07:00
$assigned_to = self :: find ( $this -> assigned_to ); //have to do this this way because otherwise it errors
2017-10-31 08:47:40 -07:00
if ( $assigned_to ) {
2017-12-04 23:00:55 -08:00
return $assigned_to -> assetLoc ( $iterations + 1 , $first_asset );
2017-10-31 08:47:40 -07:00
} // Recurse until we have a final location
2017-05-22 17:49:03 -07:00
}
if ( $this -> assignedType () == self :: LOCATION ) {
2017-10-31 08:47:40 -07:00
if ( $this -> assignedTo ) {
return $this -> assignedTo ;
}
2016-12-27 16:24:41 -08:00
}
2017-05-22 17:49:03 -07:00
if ( $this -> assignedType () == self :: USER ) {
2017-10-31 08:47:40 -07:00
if (( $this -> assignedTo ) && $this -> assignedTo -> userLoc ) {
return $this -> assignedTo -> userLoc ;
2017-09-25 11:25:15 -07:00
}
2017-10-31 08:47:40 -07:00
//this makes no sense
return $this -> defaultLoc ;
2017-05-22 17:49:03 -07:00
}
2017-09-25 11:25:15 -07:00
2016-03-25 01:18:05 -07:00
}
2017-10-28 01:48:27 -07:00
return $this -> defaultLoc ;
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Gets the lowercased name of the type of target the asset is assigned to
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
* @ return string
*/
2016-12-27 16:24:41 -08:00
public function assignedType ()
{
2024-06-21 13:06:43 -07:00
return $this -> assigned_type ? strtolower ( class_basename ( $this -> assigned_type )) : null ;
2016-12-27 16:24:41 -08:00
}
2018-08-01 00:06:41 -07:00
2023-03-07 13:42:51 -08:00
/**
* This is annoying , but because we don ' t say " assets " in our route names , we have to make an exception here
* @ todo - normalize the route names - API endpoint URLS can stay the same
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v6 . 1.0 ]
* @ return string
*/
public function targetShowRoute ()
{
$route = str_plural ( $this -> assignedType ());
if ( $route == 'assets' ) {
return 'hardware' ;
}
return $route ;
}
2018-08-01 00:06:41 -07:00
/**
* Get the asset ' s location based on default RTD location
*
* @ 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 defaultLoc ()
{
2021-06-10 13:16:56 -07:00
return $this -> belongsTo ( \App\Models\Location :: class , 'rtd_location_id' );
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Get the image URL of the asset .
*
* Check first to see if there is a specific image uploaded to the asset ,
* and if not , check for an image uploaded to the asset model .
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v2 . 0 ]
* @ return string | false
*/
2017-03-14 08:37:39 -07:00
public function getImageUrl ()
{
2021-06-10 13:15:52 -07:00
if ( $this -> image && ! empty ( $this -> image )) {
2018-09-29 21:33:52 -07:00
return Storage :: disk ( 'public' ) -> url ( app ( 'assets_upload_path' ) . e ( $this -> image ));
2021-06-10 13:15:52 -07:00
} elseif ( $this -> model && ! empty ( $this -> model -> image )) {
2018-09-29 21:33:52 -07:00
return Storage :: disk ( 'public' ) -> url ( app ( 'models_upload_path' ) . e ( $this -> model -> image ));
2017-01-24 22:46:07 -08:00
}
2021-06-10 13:15:52 -07:00
2017-01-24 22:46:07 -08:00
return false ;
}
2018-08-01 00:06:41 -07:00
/**
* Get the asset ' s logs
*
* @ 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' )
-> withTrashed ();
}
2018-04-06 16:23:39 -07:00
/**
2018-08-01 00:06:41 -07:00
* Get the list of checkouts for this asset
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v2 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
2018-04-06 16:23:39 -07:00
*/
public function checkouts ()
{
return $this -> assetlog () -> where ( 'action_type' , '=' , 'checkout' )
-> orderBy ( 'created_at' , 'desc' )
-> withTrashed ();
}
/**
2018-08-01 00:06:41 -07:00
* Get the list of checkins for this asset
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v2 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
2018-04-06 16:23:39 -07:00
*/
public function checkins ()
{
return $this -> assetlog ()
-> where ( 'action_type' , '=' , 'checkin from' )
-> orderBy ( 'created_at' , 'desc' )
-> withTrashed ();
}
/**
2018-08-01 00:06:41 -07:00
* Get the asset ' s user requests
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v2 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
2018-04-06 16:23:39 -07:00
*/
public function userRequests ()
{
return $this -> assetlog ()
-> where ( 'action_type' , '=' , 'requested' )
-> orderBy ( 'created_at' , 'desc' )
-> withTrashed ();
}
2016-03-25 01:18:05 -07:00
2018-08-01 00:06:41 -07:00
/**
* Get maintenances for this asset
*
* @ author Vincent Sposato < vincent . sposato @ gmail . com >
* @ since 1.0
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-03-25 01:18:05 -07:00
public function assetmaintenances ()
{
2021-06-10 13:16:56 -07:00
return $this -> hasMany ( \App\Models\AssetMaintenance :: class , 'asset_id' )
2016-12-01 00:55:00 -08:00
-> orderBy ( 'created_at' , 'desc' );
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Get action logs history for this asset
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v1 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2024-08-10 09:00:20 -07:00
public function admin ()
2016-03-25 01:18:05 -07:00
{
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
/**
* Establishes the asset -> status 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 assetstatus ()
{
2021-06-10 13:16:56 -07:00
return $this -> belongsTo ( \App\Models\Statuslabel :: class , 'status_id' );
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the asset -> model 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 model ()
{
2021-06-10 13:16:56 -07:00
return $this -> belongsTo ( \App\Models\AssetModel :: class , 'model_id' ) -> withTrashed ();
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Return the assets with a warranty expiring within x days
*
* @ param $days
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v2 . 0 ]
* @ return mixed
*/
2016-03-25 01:18:05 -07:00
public static function getExpiringWarrantee ( $days = 30 )
{
2022-01-18 12:21:49 -08:00
$days = ( is_null ( $days )) ? 30 : $days ;
2022-07-11 12:25:38 -07:00
2023-11-30 13:59:03 -08:00
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?
2016-03-25 01:18:05 -07:00
-> whereNotNull ( 'warranty_months' )
-> whereNotNull ( 'purchase_date' )
-> whereNull ( 'deleted_at' )
2022-08-29 12:33:51 -07:00
-> whereRaw ( 'DATE_ADD(`purchase_date`,INTERVAL `warranty_months` MONTH) <= DATE(NOW() + INTERVAL '
2016-03-25 01:18:05 -07:00
. $days
2022-08-29 12:33:51 -07:00
. ' DAY) AND DATE_ADD(`purchase_date`, INTERVAL `warranty_months` MONTH) > NOW()' )
-> orderByRaw ( 'DATE_ADD(`purchase_date`,INTERVAL `warranty_months` MONTH)' )
2016-03-25 01:18:05 -07:00
-> get ();
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the asset -> assigned licenses relationship
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-03-25 01:18:05 -07:00
public function licenses ()
{
2021-06-10 13:16:56 -07:00
return $this -> belongsToMany ( \App\Models\License :: class , 'license_seats' , 'asset_id' , 'license_id' );
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
2023-11-28 05:32:47 -08:00
* Establishes the asset -> license seats relationship
2018-08-01 00:06:41 -07:00
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 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 , 'asset_id' );
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the asset -> aupplier 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 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
/**
* Establishes the asset -> location relationship
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v2 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2017-10-28 01:48:27 -07:00
public function location ()
{
2021-06-10 13:16:56 -07:00
return $this -> belongsTo ( \App\Models\Location :: class , 'location_id' );
2017-10-28 01:48:27 -07:00
}
2016-03-25 01:18:05 -07:00
2018-08-01 00:06:41 -07:00
/**
* Get the next autoincremented asset tag
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
* @ return string | false
*/
2023-07-12 08:39:45 -07:00
public static function autoincrement_asset ( int $additional_increment = 0 )
2016-03-25 01:18:05 -07:00
{
$settings = \App\Models\Setting :: getSettings ();
2017-06-15 19:42:43 -07:00
2016-03-25 01:18:05 -07:00
if ( $settings -> auto_increment_assets == '1' ) {
2016-07-27 21:28:00 -07:00
if ( $settings -> zerofill_count > 0 ) {
2023-07-12 08:39:45 -07:00
return $settings -> auto_increment_prefix . self :: zerofill ( $settings -> next_auto_tag_base + $additional_increment , $settings -> zerofill_count );
2016-07-27 21:28:00 -07:00
}
2021-06-10 13:15:52 -07:00
2023-07-12 08:39:45 -07:00
return $settings -> auto_increment_prefix . ( $settings -> next_auto_tag_base + $additional_increment );
2016-03-25 01:18:05 -07:00
} else {
return false ;
}
}
2018-08-01 00:06:41 -07:00
/**
* Get the next base number for the auto - incrementer .
2017-06-15 19:42:43 -07:00
*
2018-08-01 00:06:41 -07:00
* We ' ll add the zerofill and prefixes on the fly as we generate the number .
2017-06-15 19:42:43 -07:00
*
2018-08-01 00:06:41 -07:00
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
* @ return int
2017-06-15 19:42:43 -07:00
*/
public static function nextAutoIncrement ( $assets )
{
$max = 1 ;
foreach ( $assets as $asset ) {
2021-06-10 13:15:52 -07:00
$results = preg_match ( " / \ d+ $ / " , $asset [ 'asset_tag' ], $matches );
2017-06-15 19:42:43 -07:00
2024-06-19 03:37:15 -07:00
if ( $results )
2017-06-15 19:42:43 -07:00
{
$number = $matches [ 0 ];
2024-06-19 03:37:15 -07:00
if ( $number > $max )
2017-06-15 19:42:43 -07:00
{
$max = $number ;
}
}
}
}
2018-08-01 00:06:41 -07:00
/**
* Add zerofilling based on Settings
*
* We ' ll add the zerofill and prefixes on the fly as we generate the number .
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
* @ return string
*/
2016-12-29 14:02:18 -08:00
public static function zerofill ( $num , $zerofill = 3 )
2016-07-27 21:28:00 -07:00
{
return str_pad ( $num , $zerofill , '0' , STR_PAD_LEFT );
}
2018-08-01 00:06:41 -07:00
/**
* Determine whether to send a checkin / checkout email based on
* asset model category
*
* @ 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
*/
2016-12-23 17:52:00 -08:00
public function checkin_email ()
2016-03-25 01:18:05 -07:00
{
2022-02-10 11:53:49 -08:00
if (( $this -> model ) && ( $this -> model -> category )) {
return $this -> model -> category -> checkin_email ;
}
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Determine whether this asset requires acceptance by the assigned user
*
* @ 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
*/
2016-03-25 01:18:05 -07:00
public function requireAcceptance ()
{
2019-12-06 18:17:03 -08:00
if (( $this -> model ) && ( $this -> model -> category )) {
return $this -> model -> category -> require_acceptance ;
}
2016-03-25 01:18:05 -07:00
}
2024-05-15 06:56:52 -07:00
/**
* Determine whether this asset ' s next audit date is before the last audit date
*
* @ return bool
* @ since [ v6 . 4.1 ]
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* */
public function checkInvalidNextAuditDate ()
{
if (( $this -> last_audit_date ) && ( $this -> next_audit_date ) && ( $this -> last_audit_date > $this -> next_audit_date )) {
return true ;
}
return false ;
}
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
*/
2016-03-25 01:18:05 -07:00
public function getEula ()
{
2022-08-29 11:26:47 -07:00
2019-12-06 18:17:03 -08:00
if (( $this -> model ) && ( $this -> model -> category )) {
if ( $this -> model -> category -> eula_text ) {
2022-08-29 11:26:47 -07:00
return Helper :: parseEscapedMarkedown ( $this -> model -> category -> eula_text );
2019-12-06 18:17:03 -08:00
} elseif ( $this -> model -> category -> use_default_eula == '1' ) {
2022-08-29 11:26:47 -07:00
return Helper :: parseEscapedMarkedown ( Setting :: getSettings () -> default_eula_text );
2019-12-06 18:17:03 -08:00
} else {
return false ;
}
2016-03-25 01:18:05 -07:00
}
2021-06-10 13:15:52 -07:00
2019-12-06 18:17:03 -08:00
return false ;
2016-03-25 01:18:05 -07:00
}
2023-04-19 16:35:06 -07:00
public function getComponentCost (){
$cost = 0 ;
foreach ( $this -> components as $component ) {
$cost += $component -> pivot -> assigned_qty * $component -> purchase_cost ;
}
return $cost ;
}
2018-08-01 00:06:41 -07:00
2023-11-29 02:07:47 -08:00
/**
* -----------------------------------------------
* BEGIN MUTATORS
* -----------------------------------------------
**/
2024-05-15 06:21:16 -07:00
/**
* Make sure the next_audit_date is formatted as Y - m - d .
*
* This is kind of dumb and confusing , since we already cast it that way AND it ' s a date field
* in the database , but here we are .
*
* @ param $value
* @ return void
*/
2024-05-30 18:14:59 -07:00
2024-06-05 02:56:54 -07:00
protected function nextAuditDate () : Attribute
2024-05-15 06:21:16 -07:00
{
2024-06-05 02:56:54 -07:00
return Attribute :: make (
get : fn ( $value ) => $value ? Carbon :: parse ( $value ) -> format ( 'Y-m-d' ) : null ,
set : fn ( $value ) => $value ? Carbon :: parse ( $value ) -> format ( 'Y-m-d' ) : null ,
);
2024-05-15 06:21:16 -07:00
}
2024-06-19 03:11:50 -07:00
protected function lastAuditDate () : Attribute
2024-05-15 06:21:16 -07:00
{
2024-06-19 03:11:50 -07:00
return Attribute :: make (
get : fn ( $value ) => $value ? Carbon :: parse ( $value ) -> format ( 'Y-m-d H:i:s' ) : null ,
set : fn ( $value ) => $value ? Carbon :: parse ( $value ) -> format ( 'Y-m-d H:i:s' ) : null ,
);
}
2024-06-05 02:56:54 -07:00
protected function lastCheckout () : Attribute
2024-05-30 18:14:59 -07:00
{
2024-06-05 02:56:54 -07:00
return Attribute :: make (
get : fn ( $value ) => $value ? Carbon :: parse ( $value ) -> format ( 'Y-m-d H:i:s' ) : null ,
set : fn ( $value ) => $value ? Carbon :: parse ( $value ) -> format ( 'Y-m-d H:i:s' ) : null ,
);
2024-05-30 18:14:59 -07:00
}
2024-06-05 02:56:54 -07:00
protected function lastCheckin () : Attribute
2024-05-30 18:14:59 -07:00
{
2024-06-05 02:56:54 -07:00
return Attribute :: make (
get : fn ( $value ) => $value ? Carbon :: parse ( $value ) -> format ( 'Y-m-d H:i:s' ) : null ,
set : fn ( $value ) => $value ? Carbon :: parse ( $value ) -> format ( 'Y-m-d H:i:s' ) : null ,
);
2024-05-30 18:14:59 -07:00
}
2024-06-05 02:56:54 -07:00
protected function assetEolDate () : Attribute
2024-05-30 18:14:59 -07:00
{
2024-06-05 02:56:54 -07:00
return Attribute :: make (
get : fn ( $value ) => $value ? Carbon :: parse ( $value ) -> format ( 'Y-m-d' ) : null ,
set : fn ( $value ) => $value ? Carbon :: parse ( $value ) -> format ( 'Y-m-d' ) : null ,
);
2024-05-15 06:21:16 -07:00
}
2023-11-29 02:07:47 -08:00
/**
* This sets the requestable to a boolean 0 or 1. This accounts for forms or API calls that
* explicitly pass the requestable field but it has a null or empty value .
*
* This will also correctly parse a 1 / 0 if " true " / " false " is passed .
*
* @ param $value
* @ return void
*/
2024-06-05 02:56:54 -07:00
protected function requestable () : Attribute
2023-11-29 02:07:47 -08:00
{
2024-06-05 02:56:54 -07:00
return Attribute :: make (
get : fn ( $value ) => ( int ) filter_var ( $value , FILTER_VALIDATE_BOOLEAN ),
set : fn ( $value ) => ( int ) filter_var ( $value , FILTER_VALIDATE_BOOLEAN ),
);
2023-11-29 02:07:47 -08:00
}
2018-08-01 00:06:41 -07:00
/**
* -----------------------------------------------
* BEGIN QUERY SCOPES
* -----------------------------------------------
**/
2018-07-16 14:13:07 -07:00
/**
* Run additional , advanced searches .
2018-08-01 00:06:41 -07:00
*
* @ param \Illuminate\Database\Eloquent\Builder $query
2018-07-16 17:44:31 -07:00
* @ param array $terms The search terms
2018-08-01 00:06:41 -07:00
* @ return \Illuminate\Database\Eloquent\Builder
2018-07-16 14:13:07 -07:00
*/
2021-06-10 13:15:52 -07:00
public function advancedTextSearch ( Builder $query , array $terms )
{
2018-07-16 17:44:31 -07:00
2018-08-01 00:06:41 -07:00
/**
* Assigned user
*/
2021-06-10 13:15:52 -07:00
$query = $query -> leftJoin ( 'users as assets_users' , function ( $leftJoin ) {
$leftJoin -> on ( 'assets_users.id' , '=' , 'assets.assigned_to' )
-> where ( 'assets.assigned_type' , '=' , User :: class );
2018-08-01 00:06:41 -07:00
});
2018-07-16 17:44:31 -07:00
2021-06-10 13:15:52 -07:00
foreach ( $terms as $term ) {
2018-07-16 17:44:31 -07:00
2018-08-01 00:06:41 -07:00
$query = $query
-> orWhere ( 'assets_users.first_name' , 'LIKE' , '%' . $term . '%' )
-> orWhere ( 'assets_users.last_name' , 'LIKE' , '%' . $term . '%' )
-> orWhere ( 'assets_users.username' , 'LIKE' , '%' . $term . '%' )
2023-10-25 12:59:58 -07:00
-> orWhere ( 'assets_users.employee_num' , 'LIKE' , '%' . $term . '%' )
2023-05-23 13:38:50 -07:00
-> orWhereMultipleColumns ([
2023-05-23 15:58:58 -07:00
'assets_users.first_name' ,
'assets_users.last_name' ,
2023-05-23 13:38:50 -07:00
], $term );
2018-08-01 00:06:41 -07:00
}
2018-07-16 17:44:31 -07:00
2018-08-01 00:06:41 -07:00
/**
* Assigned location
*/
2021-06-10 13:15:52 -07:00
$query = $query -> leftJoin ( 'locations as assets_locations' , function ( $leftJoin ) {
$leftJoin -> on ( 'assets_locations.id' , '=' , 'assets.assigned_to' )
-> where ( 'assets.assigned_type' , '=' , Location :: class );
2018-08-01 00:06:41 -07:00
});
2018-07-16 14:13:07 -07:00
2021-06-10 13:15:52 -07:00
foreach ( $terms as $term ) {
2018-07-16 14:13:07 -07:00
2018-08-01 00:06:41 -07:00
$query = $query -> orWhere ( 'assets_locations.name' , 'LIKE' , '%' . $term . '%' );
}
2018-07-16 17:44:31 -07:00
2018-08-01 00:06:41 -07:00
/**
* Assigned assets
*/
2021-06-10 13:15:52 -07:00
$query = $query -> leftJoin ( 'assets as assigned_assets' , function ( $leftJoin ) {
2018-08-01 00:06:41 -07:00
$leftJoin -> on ( 'assigned_assets.id' , '=' , 'assets.assigned_to' )
2021-06-10 13:15:52 -07:00
-> where ( 'assets.assigned_type' , '=' , self :: class );
2018-08-01 00:06:41 -07:00
});
2018-07-16 14:13:07 -07:00
2021-06-10 13:15:52 -07:00
foreach ( $terms as $term ) {
2018-08-01 00:06:41 -07:00
$query = $query -> orWhere ( 'assigned_assets.name' , 'LIKE' , '%' . $term . '%' );
2018-07-16 17:44:31 -07:00
2018-08-01 00:06:41 -07:00
}
2018-07-16 14:13:07 -07:00
2018-08-01 00:06:41 -07:00
return $query ;
2018-07-16 14:13:07 -07:00
}
2016-03-25 01:18:05 -07:00
2018-08-01 00:06:41 -07:00
/**
* Query builder scope for hardware
*
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
2016-03-25 01:18:05 -07:00
public function scopeHardware ( $query )
{
return $query -> where ( 'physical' , '=' , '1' );
}
2018-08-01 00:06:41 -07:00
/**
* Query builder scope for pending assets
*
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
2016-03-25 01:18:05 -07:00
public function scopePending ( $query )
{
return $query -> whereHas ( 'assetstatus' , function ( $query ) {
$query -> where ( 'deployable' , '=' , 0 )
-> where ( 'pending' , '=' , 1 )
-> where ( 'archived' , '=' , 0 );
});
}
2016-04-19 20:23:04 -07:00
/**
2017-09-05 17:54:58 -07:00
* Query builder scope for searching location
2016-04-19 20:23:04 -07:00
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-04-19 20:23:04 -07:00
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-04-19 20:23:04 -07:00
*/
public function scopeAssetsByLocation ( $query , $location )
{
2016-06-22 12:27:41 -07:00
return $query -> where ( function ( $query ) use ( $location ) {
2017-09-05 17:54:58 -07:00
$query -> whereHas ( 'assignedTo' , function ( $query ) use ( $location ) {
$query -> where ([
[ 'users.location_id' , '=' , $location -> id ],
2021-06-10 13:15:52 -07:00
[ 'assets.assigned_type' , '=' , User :: class ],
2017-09-05 17:54:58 -07:00
]) -> orWhere ([
[ 'locations.id' , '=' , $location -> id ],
2021-06-10 13:15:52 -07:00
[ 'assets.assigned_type' , '=' , Location :: class ],
2017-09-05 17:54:58 -07:00
]) -> orWhere ([
[ 'assets.rtd_location_id' , '=' , $location -> id ],
2021-06-10 13:15:52 -07:00
[ 'assets.assigned_type' , '=' , self :: class ],
2017-09-05 17:54:58 -07:00
]);
2016-06-22 12:27:41 -07:00
}) -> orWhere ( function ( $query ) use ( $location ) {
2016-04-19 20:23:04 -07:00
$query -> where ( 'assets.rtd_location_id' , '=' , $location -> id );
$query -> whereNull ( 'assets.assigned_to' );
});
});
}
/**
* Query builder scope for RTD assets
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-04-19 20:23:04 -07:00
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-04-19 20:23:04 -07:00
*/
2016-03-25 01:18:05 -07:00
public function scopeRTD ( $query )
{
2018-07-25 06:46:06 -07:00
return $query -> whereNull ( 'assets.assigned_to' )
2016-03-25 01:18:05 -07:00
-> whereHas ( 'assetstatus' , function ( $query ) {
$query -> where ( 'deployable' , '=' , 1 )
-> where ( 'pending' , '=' , 0 )
-> where ( 'archived' , '=' , 0 );
});
}
/**
* Query builder scope for Undeployable assets
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-03-25 01:18:05 -07:00
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-03-25 01:18:05 -07:00
*/
public function scopeUndeployable ( $query )
{
return $query -> whereHas ( 'assetstatus' , function ( $query ) {
$query -> where ( 'deployable' , '=' , 0 )
-> where ( 'pending' , '=' , 0 )
-> where ( 'archived' , '=' , 0 );
});
}
2016-09-01 13:28:15 -07:00
/**
* Query builder scope for non - Archived assets
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-09-01 13:28:15 -07:00
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-09-01 13:28:15 -07:00
*/
public function scopeNotArchived ( $query )
{
return $query -> whereHas ( 'assetstatus' , function ( $query ) {
$query -> where ( 'archived' , '=' , 0 );
});
}
2019-05-05 19:32:52 -07:00
/**
* Query builder scope for Assets that are due for auditing , based on the assets . next_audit_date
* and settings . audit_warning_days .
*
* This is / will be used in the artisan command snipeit : upcoming - audits and also
* for an upcoming API call for retrieving a report on assets that will need to be audited .
*
* Due for audit soon :
* next_audit_date greater than or equal to now ( must be in the future )
* and ( next_audit_date - threshold days ) <= now ()
*
* Example :
* next_audit_date = May 4 , 2025
* threshold for alerts = 30 days
* now = May 4 , 2019
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since v4 . 6.16
* @ param Setting $settings
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeDueForAudit ( $query , $settings )
{
2019-11-21 21:34:41 -08:00
$interval = $settings -> audit_warning_days ? ? 0 ;
2024-04-26 06:02:23 -07:00
$today = Carbon :: now ();
$interval_date = $today -> copy () -> addDays ( $interval ) -> format ( 'Y-m-d' );
2019-11-21 21:34:41 -08:00
2019-05-05 19:32:52 -07:00
return $query -> whereNotNull ( 'assets.next_audit_date' )
2024-04-26 06:02:23 -07:00
-> whereBetween ( 'assets.next_audit_date' , [ $today -> format ( 'Y-m-d' ), $interval_date ])
2019-05-05 19:32:52 -07:00
-> where ( 'assets.archived' , '=' , 0 )
-> NotArchived ();
}
/**
* Query builder scope for Assets that are OVERDUE for auditing , based on the assets . next_audit_date
* and settings . audit_warning_days . It checks to see if assets . next audit_date is before now
*
* This is / will be used in the artisan command snipeit : upcoming - audits and also
* for an upcoming API call for retrieving a report on overdue assets .
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since v4 . 6.16
* @ param Setting $settings
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOverdueForAudit ( $query )
{
return $query -> whereNotNull ( 'assets.next_audit_date' )
2024-04-26 06:02:23 -07:00
-> where ( 'assets.next_audit_date' , '<' , Carbon :: now () -> format ( 'Y-m-d' ))
2019-05-05 19:32:52 -07:00
-> where ( 'assets.archived' , '=' , 0 )
-> NotArchived ();
}
/**
* Query builder scope for Assets that are due for auditing OR overdue , based on the assets . next_audit_date
* and settings . audit_warning_days .
*
* This is / will be used in the artisan command snipeit : upcoming - audits and also
* for an upcoming API call for retrieving a report on assets that will need to be audited .
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since v4 . 6.16
* @ param Setting $settings
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeDueOrOverdueForAudit ( $query , $settings )
{
2024-04-26 06:02:23 -07:00
2024-04-26 12:59:27 -07:00
return $query -> where ( function ( $query ) {
$query -> OverdueForAudit ();
}) -> orWhere ( function ( $query ) use ( $settings ) {
$query -> DueForAudit ( $settings );
});
2024-04-26 06:02:23 -07:00
}
/**
2024-04-26 11:23:27 -07:00
* Query builder scope for Assets that are DUE for checkin , based on the assets . expected_checkin
* and settings . audit_warning_days . It checks to see if assets . expected_checkin is now
2024-04-26 06:02:23 -07:00
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since v6 . 4.0
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
2024-04-26 11:01:05 -07:00
public function scopeDueForCheckin ( $query , $settings )
2019-05-05 19:32:52 -07:00
{
2019-07-18 14:37:48 -07:00
$interval = $settings -> audit_warning_days ? ? 0 ;
2024-04-26 11:01:05 -07:00
$today = Carbon :: now ();
$interval_date = $today -> copy () -> addDays ( $interval ) -> format ( 'Y-m-d' );
2019-07-18 14:37:48 -07:00
2024-04-26 11:01:05 -07:00
return $query -> whereNotNull ( 'assets.expected_checkin' )
-> whereBetween ( 'assets.expected_checkin' , [ $today -> format ( 'Y-m-d' ), $interval_date ])
-> where ( 'assets.archived' , '=' , 0 )
2024-04-26 11:06:46 -07:00
-> whereNotNull ( 'assets.assigned_to' )
2024-04-26 11:01:05 -07:00
-> NotArchived ();
}
2024-04-26 13:01:27 -07:00
/**
* Query builder scope for Assets that are overdue for checkin OR overdue
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since v6 . 4.0
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
2024-04-26 06:02:23 -07:00
public function scopeOverdueForCheckin ( $query )
{
return $query -> whereNotNull ( 'assets.expected_checkin' )
-> where ( 'assets.expected_checkin' , '<' , Carbon :: now () -> format ( 'Y-m-d' ))
2019-05-05 19:32:52 -07:00
-> where ( 'assets.archived' , '=' , 0 )
2024-04-26 11:06:46 -07:00
-> whereNotNull ( 'assets.assigned_to' )
2019-05-05 19:32:52 -07:00
-> NotArchived ();
}
2024-04-26 06:02:23 -07:00
/**
2024-04-26 12:59:27 -07:00
* Query builder scope for Assets that are due for checkin OR overdue
2024-04-26 06:02:23 -07:00
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since v6 . 4.0
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeDueOrOverdueForCheckin ( $query , $settings )
{
2024-04-26 12:59:27 -07:00
return $query -> where ( function ( $query ) {
$query -> OverdueForCheckin ();
}) -> orWhere ( function ( $query ) use ( $settings ) {
$query -> DueForCheckin ( $settings );
});
2019-05-05 19:32:52 -07:00
}
2022-06-23 13:43:23 -07:00
/**
2022-06-23 16:02:54 -07:00
* Query builder scope for Archived assets counting
*
* This is primarily used for the tab counters so that IF the admin
* has chosen to not display archived assets in their regular lists
* and views , it will return the correct number .
2022-06-23 13:43:23 -07:00
*
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeAssetsForShow ( $query )
{
if ( Setting :: getSettings () -> show_archived_in_list != 1 ) {
return $query -> whereHas ( 'assetstatus' , function ( $query ) {
$query -> where ( 'archived' , '=' , 0 );
});
} else {
return $query ;
}
}
2016-03-25 01:18:05 -07:00
/**
* Query builder scope for Archived assets
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-03-25 01:18:05 -07:00
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-03-25 01:18:05 -07:00
*/
public function scopeArchived ( $query )
{
return $query -> whereHas ( 'assetstatus' , function ( $query ) {
$query -> where ( 'deployable' , '=' , 0 )
-> where ( 'pending' , '=' , 0 )
-> where ( 'archived' , '=' , 1 );
});
}
/**
* Query builder scope for Deployed assets
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-03-25 01:18:05 -07:00
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-03-25 01:18:05 -07:00
*/
public function scopeDeployed ( $query )
{
return $query -> where ( 'assigned_to' , '>' , '0' );
}
/**
* Query builder scope for Requestable assets
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-03-25 01:18:05 -07:00
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-03-25 01:18:05 -07:00
*/
public function scopeRequestableAssets ( $query )
{
2022-05-24 12:00:23 -07:00
$table = $query -> getModel () -> getTable ();
return Company :: scopeCompanyables ( $query -> where ( $table . '.requestable' , '=' , 1 ))
2016-04-19 20:23:04 -07:00
-> whereHas ( 'assetstatus' , function ( $query ) {
2022-01-14 12:48:33 -08:00
$query -> where ( function ( $query ) {
$query -> where ( 'deployable' , '=' , 1 )
-> where ( 'archived' , '=' , 0 ); // you definitely can't request something that's archived
}) -> orWhere ( 'pending' , '=' , 1 ); // we've decided that even though an asset may be 'pending', you can still request it
2016-04-19 20:23:04 -07:00
});
2016-03-25 01:18:05 -07:00
}
/**
* scopeInModelList
* Get all assets in the provided listing of model ids
*
* @ param $query
* @ param array $modelIdListing
*
* @ return mixed
* @ author Vincent Sposato < vincent . sposato @ gmail . com >
* @ version v1 . 0
*/
public function scopeInModelList ( $query , array $modelIdListing )
{
2017-11-08 20:03:26 -08:00
return $query -> whereIn ( 'assets.model_id' , $modelIdListing );
2016-03-25 01:18:05 -07:00
}
/**
* Query builder scope to get not - yet - accepted assets
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-03-25 01:18:05 -07:00
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-03-25 01:18:05 -07:00
*/
public function scopeNotYetAccepted ( $query )
{
2021-06-10 13:15:52 -07:00
return $query -> where ( 'accepted' , '=' , 'pending' );
2016-03-25 01:18:05 -07:00
}
/**
* Query builder scope to get rejected assets
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-03-25 01:18:05 -07:00
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-03-25 01:18:05 -07:00
*/
public function scopeRejected ( $query )
{
2021-06-10 13:15:52 -07:00
return $query -> where ( 'accepted' , '=' , 'rejected' );
2016-03-25 01:18:05 -07:00
}
/**
* Query builder scope to get accepted assets
*
2017-06-15 19:42:43 -07:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-03-25 01:18:05 -07:00
*
2017-06-15 19:42:43 -07:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-03-25 01:18:05 -07:00
*/
public function scopeAccepted ( $query )
{
2021-06-10 13:15:52 -07:00
return $query -> where ( 'accepted' , '=' , 'accepted' );
2016-03-25 01:18:05 -07:00
}
2017-11-16 16:49:16 -08:00
/**
* Query builder scope to search on text for complex Bootstrap Tables API .
*
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
* @ param text $search Search term
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeAssignedSearch ( $query , $search )
{
$search = explode ( ' OR ' , $search );
2021-06-10 13:15:52 -07:00
return $query -> leftJoin ( 'users as assets_users' , function ( $leftJoin ) {
$leftJoin -> on ( 'assets_users.id' , '=' , 'assets.assigned_to' )
-> where ( 'assets.assigned_type' , '=' , User :: class );
}) -> leftJoin ( 'locations as assets_locations' , function ( $leftJoin ) {
$leftJoin -> on ( 'assets_locations.id' , '=' , 'assets.assigned_to' )
-> where ( 'assets.assigned_type' , '=' , Location :: class );
}) -> leftJoin ( 'assets as assigned_assets' , function ( $leftJoin ) {
2017-11-16 16:49:16 -08:00
$leftJoin -> on ( 'assigned_assets.id' , '=' , 'assets.assigned_to' )
2021-06-10 13:15:52 -07:00
-> where ( 'assets.assigned_type' , '=' , self :: class );
2017-11-16 16:49:16 -08:00
}) -> where ( function ( $query ) use ( $search ) {
foreach ( $search as $search ) {
$query -> whereHas ( 'model' , function ( $query ) use ( $search ) {
$query -> whereHas ( 'category' , function ( $query ) use ( $search ) {
$query -> where ( function ( $query ) use ( $search ) {
$query -> where ( 'categories.name' , 'LIKE' , '%' . $search . '%' )
-> orWhere ( 'models.name' , 'LIKE' , '%' . $search . '%' )
-> orWhere ( 'models.model_number' , 'LIKE' , '%' . $search . '%' );
});
});
}) -> orWhereHas ( 'model' , function ( $query ) use ( $search ) {
$query -> whereHas ( 'manufacturer' , function ( $query ) use ( $search ) {
$query -> where ( function ( $query ) use ( $search ) {
$query -> where ( 'manufacturers.name' , 'LIKE' , '%' . $search . '%' );
});
});
}) -> orWhere ( function ( $query ) use ( $search ) {
$query -> where ( 'assets_users.first_name' , 'LIKE' , '%' . $search . '%' )
-> orWhere ( 'assets_users.last_name' , 'LIKE' , '%' . $search . '%' )
2023-05-23 13:38:50 -07:00
-> orWhereMultipleColumns ([
2023-05-23 15:58:58 -07:00
'assets_users.first_name' ,
'assets_users.last_name' ,
2023-05-23 13:38:50 -07:00
], $search )
2017-11-16 16:49:16 -08:00
-> orWhere ( 'assets_users.username' , 'LIKE' , '%' . $search . '%' )
-> orWhere ( 'assets_locations.name' , 'LIKE' , '%' . $search . '%' )
-> orWhere ( 'assigned_assets.name' , 'LIKE' , '%' . $search . '%' );
2016-03-25 01:18:05 -07:00
}) -> orWhere ( 'assets.name' , 'LIKE' , '%' . $search . '%' )
-> orWhere ( 'assets.asset_tag' , 'LIKE' , '%' . $search . '%' )
-> orWhere ( 'assets.serial' , 'LIKE' , '%' . $search . '%' )
-> orWhere ( 'assets.order_number' , 'LIKE' , '%' . $search . '%' )
-> orWhere ( 'assets.notes' , 'LIKE' , '%' . $search . '%' );
}
2019-05-24 13:50:11 -07:00
2021-06-10 13:15:52 -07:00
}) -> withTrashed () -> whereNull ( 'assets.deleted_at' ); //workaround for laravel bug
2016-03-25 01:18:05 -07:00
}
2018-10-31 15:19:13 -07:00
/**
* Query builder scope to search the department ID of users assigned to assets
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v5 . 0 ]
* @ return string | false
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeCheckedOutToTargetInDepartment ( $query , $search )
{
2021-06-10 13:15:52 -07:00
return $query -> leftJoin ( 'users as assets_dept_users' , function ( $leftJoin ) {
$leftJoin -> on ( 'assets_dept_users.id' , '=' , 'assets.assigned_to' )
-> where ( 'assets.assigned_type' , '=' , User :: class );
2018-10-31 15:19:13 -07:00
}) -> where ( function ( $query ) use ( $search ) {
$query -> where ( 'assets_dept_users.department_id' , '=' , $search );
2021-06-10 13:15:52 -07:00
}) -> withTrashed () -> whereNull ( 'assets.deleted_at' ); //workaround for laravel bug
2018-10-31 15:19:13 -07:00
}
2017-03-11 04:26:01 -08:00
/**
* Query builder scope to search on text filters for complex Bootstrap Tables API
*
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
* @ param text $filter JSON array of search keys and terms
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeByFilter ( $query , $filter )
{
return $query -> where ( function ( $query ) use ( $filter ) {
foreach ( $filter as $key => $search_val ) {
2017-10-18 10:07:35 -07:00
2021-06-10 13:15:52 -07:00
$fieldname = str_replace ( 'custom_fields.' , '' , $key );
2017-10-18 10:07:35 -07:00
2021-06-10 13:15:52 -07:00
if ( $fieldname == 'asset_tag' ) {
2017-03-11 04:26:01 -08:00
$query -> where ( 'assets.asset_tag' , 'LIKE' , '%' . $search_val . '%' );
}
2021-06-10 13:15:52 -07:00
if ( $fieldname == 'name' ) {
2017-03-11 04:26:01 -08:00
$query -> where ( 'assets.name' , 'LIKE' , '%' . $search_val . '%' );
}
2021-10-28 16:42:10 -07:00
2021-08-05 06:07:28 -07:00
if ( $fieldname == 'serial' ) {
2017-03-11 04:26:01 -08:00
$query -> where ( 'assets.serial' , 'LIKE' , '%' . $search_val . '%' );
}
2021-06-10 13:15:52 -07:00
if ( $fieldname == 'purchase_date' ) {
2017-03-11 04:26:01 -08:00
$query -> where ( 'assets.purchase_date' , 'LIKE' , '%' . $search_val . '%' );
}
2021-06-10 13:15:52 -07:00
if ( $fieldname == 'purchase_cost' ) {
2017-03-11 04:26:01 -08:00
$query -> where ( 'assets.purchase_cost' , 'LIKE' , '%' . $search_val . '%' );
}
2021-06-10 13:15:52 -07:00
if ( $fieldname == 'notes' ) {
2017-03-11 04:26:01 -08:00
$query -> where ( 'assets.notes' , 'LIKE' , '%' . $search_val . '%' );
}
2021-06-10 13:15:52 -07:00
if ( $fieldname == 'order_number' ) {
2017-03-11 04:26:01 -08:00
$query -> where ( 'assets.order_number' , 'LIKE' , '%' . $search_val . '%' );
}
2021-06-10 13:15:52 -07:00
if ( $fieldname == 'status_label' ) {
2017-03-11 04:26:01 -08:00
$query -> whereHas ( 'assetstatus' , function ( $query ) use ( $search_val ) {
2021-06-10 13:15:52 -07:00
$query -> where ( 'status_labels.name' , 'LIKE' , '%' . $search_val . '%' );
2017-03-11 04:26:01 -08:00
});
}
2021-06-10 13:15:52 -07:00
if ( $fieldname == 'location' ) {
2017-11-02 08:06:10 -07:00
$query -> whereHas ( 'location' , function ( $query ) use ( $search_val ) {
2021-06-10 13:15:52 -07:00
$query -> where ( 'locations.name' , 'LIKE' , '%' . $search_val . '%' );
2017-03-11 04:26:01 -08:00
});
}
2023-08-16 14:04:17 -07:00
if ( $fieldname == 'rtd_location' ) {
$query -> whereHas ( 'defaultLoc' , function ( $query ) use ( $search_val ) {
$query -> where ( 'locations.name' , 'LIKE' , '%' . $search_val . '%' );
});
}
2021-11-01 14:14:19 -07:00
if ( $fieldname == 'assigned_to' ) {
$query -> whereHasMorph ( 'assignedTo' , [ User :: class ], function ( $query ) use ( $search_val ) {
2017-10-05 00:35:37 -07:00
$query -> where ( function ( $query ) use ( $search_val ) {
2021-06-10 13:15:52 -07:00
$query -> where ( 'users.first_name' , 'LIKE' , '%' . $search_val . '%' )
-> orWhere ( 'users.last_name' , 'LIKE' , '%' . $search_val . '%' );
2017-03-11 04:26:01 -08:00
});
});
}
2021-06-10 13:15:52 -07:00
if ( $fieldname == 'manufacturer' ) {
2017-03-11 04:26:01 -08:00
$query -> whereHas ( 'model' , function ( $query ) use ( $search_val ) {
$query -> whereHas ( 'manufacturer' , function ( $query ) use ( $search_val ) {
$query -> where ( function ( $query ) use ( $search_val ) {
$query -> where ( 'manufacturers.name' , 'LIKE' , '%' . $search_val . '%' );
});
});
});
}
2021-06-10 13:15:52 -07:00
if ( $fieldname == 'category' ) {
2017-10-05 00:35:37 -07:00
$query -> whereHas ( 'model' , function ( $query ) use ( $search_val ) {
$query -> whereHas ( 'category' , function ( $query ) use ( $search_val ) {
2017-03-11 04:26:01 -08:00
$query -> where ( function ( $query ) use ( $search_val ) {
2021-06-10 13:15:52 -07:00
$query -> where ( 'categories.name' , 'LIKE' , '%' . $search_val . '%' )
-> orWhere ( 'models.name' , 'LIKE' , '%' . $search_val . '%' )
-> orWhere ( 'models.model_number' , 'LIKE' , '%' . $search_val . '%' );
2017-03-11 04:26:01 -08:00
});
});
});
}
2021-06-10 13:15:52 -07:00
if ( $fieldname == 'model' ) {
2017-03-11 04:26:01 -08:00
$query -> where ( function ( $query ) use ( $search_val ) {
$query -> whereHas ( 'model' , function ( $query ) use ( $search_val ) {
2021-06-10 13:15:52 -07:00
$query -> where ( 'models.name' , 'LIKE' , '%' . $search_val . '%' );
2017-03-11 04:26:01 -08:00
});
});
}
2021-06-10 13:15:52 -07:00
if ( $fieldname == 'model_number' ) {
2017-03-11 04:26:01 -08:00
$query -> where ( function ( $query ) use ( $search_val ) {
$query -> whereHas ( 'model' , function ( $query ) use ( $search_val ) {
2021-06-10 13:15:52 -07:00
$query -> where ( 'models.model_number' , 'LIKE' , '%' . $search_val . '%' );
2017-03-11 04:26:01 -08:00
});
});
}
2021-06-10 13:15:52 -07:00
if ( $fieldname == 'company' ) {
2017-03-11 04:26:01 -08:00
$query -> where ( function ( $query ) use ( $search_val ) {
$query -> whereHas ( 'company' , function ( $query ) use ( $search_val ) {
2021-06-10 13:15:52 -07:00
$query -> where ( 'companies.name' , 'LIKE' , '%' . $search_val . '%' );
2017-03-11 04:26:01 -08:00
});
});
}
2018-04-25 20:25:03 -07:00
2021-06-10 13:15:52 -07:00
if ( $fieldname == 'supplier' ) {
2018-04-25 20:25:03 -07:00
$query -> where ( function ( $query ) use ( $search_val ) {
$query -> whereHas ( 'supplier' , function ( $query ) use ( $search_val ) {
2021-06-10 13:15:52 -07:00
$query -> where ( 'suppliers.name' , 'LIKE' , '%' . $search_val . '%' );
2018-04-25 20:25:03 -07:00
});
});
}
2021-11-01 14:14:19 -07:00
2017-03-11 04:26:01 -08:00
2019-07-31 14:24:01 -07:00
/**
* THIS CLUNKY BIT IS VERY IMPORTANT
*
* Although inelegant , this section matters a lot when querying against fields that do not
* exist on the asset table . There ' s probably a better way to do this moving forward , for
* example using the Schema :: methods to determine whether or not a column actually exists ,
* or even just using the $searchableRelations variable earlier in this file .
*
* In short , this set of statements tells the query builder to ONLY query against an
* actual field that 's being passed if it doesn' t meet known relational fields . This
2024-02-14 01:46:43 -08:00
* allows us to query custom fields directly in the assets table
2019-07-31 14:24:01 -07:00
* ( regardless of their name ) and * skip * any fields that we already know can only be
* searched through relational searches that we do earlier in this method .
*
* For example , we do not store " location " as a field on the assets table , we store
* that relationship through location_id on the assets table , therefore querying
* assets . location would fail , as that field doesn 't exist -- plus we' re already searching
* against those relationships earlier in this method .
*
* - snipe
*
*/
2021-10-28 16:42:10 -07:00
2019-07-31 13:55:21 -07:00
if (( $fieldname != 'category' ) && ( $fieldname != 'model_number' ) && ( $fieldname != 'rtd_location' ) && ( $fieldname != 'location' ) && ( $fieldname != 'supplier' )
2021-11-01 14:14:19 -07:00
&& ( $fieldname != 'status_label' ) && ( $fieldname != 'assigned_to' ) && ( $fieldname != 'model' ) && ( $fieldname != 'company' ) && ( $fieldname != 'manufacturer' )) {
2021-08-05 06:07:28 -07:00
$query -> where ( 'assets.' . $fieldname , 'LIKE' , '%' . $search_val . '%' );
2017-11-02 08:06:10 -07:00
}
2017-10-18 10:07:35 -07:00
2021-11-01 14:14:19 -07:00
}
2017-10-18 10:07:35 -07:00
2017-10-05 23:09:02 -07:00
2017-03-11 04:26:01 -08:00
});
2017-10-05 23:09:02 -07:00
2017-03-11 04:26:01 -08:00
}
2016-03-25 01:18:05 -07:00
/**
* Query builder scope to order on model
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-03-25 01:18:05 -07:00
* @ param text $order Order
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-03-25 01:18:05 -07:00
*/
public function scopeOrderModels ( $query , $order )
{
2017-11-16 14:14:30 -08:00
return $query -> join ( 'models as asset_models' , 'assets.model_id' , '=' , 'asset_models.id' ) -> orderBy ( 'asset_models.name' , $order );
2016-03-25 01:18:05 -07:00
}
2016-06-27 22:32:40 -07:00
/**
* Query builder scope to order on model number
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-06-27 22:32:40 -07:00
* @ param text $order Order
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-06-27 22:32:40 -07:00
*/
public function scopeOrderModelNumber ( $query , $order )
{
2023-06-29 08:52:09 -07:00
return $query -> leftJoin ( 'models as model_number_sort' , 'assets.model_id' , '=' , 'model_number_sort.id' ) -> orderBy ( 'model_number_sort.model_number' , $order );
2016-06-27 22:32:40 -07:00
}
2016-03-25 01:18:05 -07:00
2016-11-11 19:46:25 -08:00
/**
* Query builder scope to order on assigned user
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-11-11 19:46:25 -08:00
* @ param text $order Order
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-11-11 19:46:25 -08:00
*/
2016-03-25 01:18:05 -07:00
public function scopeOrderAssigned ( $query , $order )
{
2017-11-02 13:47:37 -07:00
return $query -> leftJoin ( 'users as users_sort' , 'assets.assigned_to' , '=' , 'users_sort.id' ) -> select ( 'assets.*' ) -> orderBy ( 'users_sort.first_name' , $order ) -> orderBy ( 'users_sort.last_name' , $order );
2016-03-25 01:18:05 -07:00
}
/**
* Query builder scope to order on status
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-03-25 01:18:05 -07:00
* @ param text $order Order
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-03-25 01:18:05 -07:00
*/
public function scopeOrderStatus ( $query , $order )
{
2017-11-02 13:47:37 -07:00
return $query -> join ( 'status_labels as status_sort' , 'assets.status_id' , '=' , 'status_sort.id' ) -> orderBy ( 'status_sort.name' , $order );
2016-03-25 01:18:05 -07:00
}
2017-05-15 20:55:39 -07:00
/**
2016-03-25 01:18:05 -07:00
* Query builder scope to order on company
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-03-25 01:18:05 -07:00
* @ param text $order Order
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-03-25 01:18:05 -07:00
*/
public function scopeOrderCompany ( $query , $order )
{
2017-11-02 13:47:37 -07:00
return $query -> leftJoin ( 'companies as company_sort' , 'assets.company_id' , '=' , 'company_sort.id' ) -> orderBy ( 'company_sort.name' , $order );
2016-03-25 01:18:05 -07:00
}
2017-02-03 19:34:24 -08:00
/**
* Query builder scope to return results of a category
*
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
* @ param text $order Order
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeInCategory ( $query , $category_id )
{
2018-09-07 03:19:54 -07:00
return $query -> join ( 'models as category_models' , 'assets.model_id' , '=' , 'category_models.id' )
-> join ( 'categories' , 'category_models.category_id' , '=' , 'categories.id' ) -> where ( 'category_models.category_id' , '=' , $category_id );
2017-02-03 19:34:24 -08:00
}
2017-02-03 19:52:00 -08:00
/**
* Query builder scope to return results of a manufacturer
*
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
* @ param text $order Order
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeByManufacturer ( $query , $manufacturer_id )
{
return $query -> join ( 'models' , 'assets.model_id' , '=' , 'models.id' )
2017-03-14 08:37:39 -07:00
-> join ( 'manufacturers' , 'models.manufacturer_id' , '=' , 'manufacturers.id' ) -> where ( 'models.manufacturer_id' , '=' , $manufacturer_id );
2017-02-03 19:52:00 -08:00
}
2017-02-03 19:34:24 -08:00
/**
* Query builder scope to order on category
*
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
* @ param text $order Order
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
2016-03-25 01:18:05 -07:00
public function scopeOrderCategory ( $query , $order )
{
2017-11-02 13:47:37 -07:00
return $query -> join ( 'models as order_model_category' , 'assets.model_id' , '=' , 'order_model_category.id' )
-> join ( 'categories as category_order' , 'order_model_category.category_id' , '=' , 'category_order.id' )
-> orderBy ( 'category_order.name' , $order );
2016-03-25 01:18:05 -07:00
}
2016-05-12 10:38:57 -07:00
/**
* Query builder scope to order on manufacturer
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-05-12 10:38:57 -07:00
* @ param text $order Order
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-05-12 10:38:57 -07:00
*/
public function scopeOrderManufacturer ( $query , $order )
{
2023-02-27 13:24:09 -08:00
return $query -> join ( 'models as order_asset_model' , 'assets.model_id' , '=' , 'order_asset_model.id' )
2023-06-01 11:08:51 -07:00
-> leftjoin ( 'manufacturers as manufacturer_order' , 'order_asset_model.manufacturer_id' , '=' , 'manufacturer_order.id' )
2023-02-27 13:24:09 -08:00
-> orderBy ( 'manufacturer_order.name' , $order );
2016-05-12 10:38:57 -07:00
}
2017-02-08 03:31:42 -08:00
/**
2016-06-28 12:19:14 -07:00
* Query builder scope to order on location
2016-03-25 01:18:05 -07:00
*
2017-02-03 19:34:24 -08:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
2016-03-25 01:18:05 -07:00
* @ param text $order Order
*
2017-02-03 19:34:24 -08:00
* @ return \Illuminate\Database\Query\Builder Modified query builder
2016-03-25 01:18:05 -07:00
*/
public function scopeOrderLocation ( $query , $order )
{
2017-11-16 16:49:48 -08:00
return $query -> leftJoin ( 'locations as asset_locations' , 'asset_locations.id' , '=' , 'assets.location_id' ) -> orderBy ( 'asset_locations.name' , $order );
2016-03-25 01:18:05 -07:00
}
2017-02-08 03:31:42 -08:00
2018-01-24 14:27:12 -08:00
/**
* Query builder scope to order on default
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
* @ param text $order Order
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderRtdLocation ( $query , $order )
{
return $query -> leftJoin ( 'locations as rtd_asset_locations' , 'rtd_asset_locations.id' , '=' , 'assets.rtd_location_id' ) -> orderBy ( 'rtd_asset_locations.name' , $order );
}
2017-05-15 20:55:39 -07:00
/**
* Query builder scope to order on supplier name
*
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
* @ param text $order Order
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderSupplier ( $query , $order )
{
2017-11-03 13:28:57 -07:00
return $query -> leftJoin ( 'suppliers as suppliers_assets' , 'assets.supplier_id' , '=' , 'suppliers_assets.id' ) -> orderBy ( 'suppliers_assets.name' , $order );
2017-05-15 20:55:39 -07:00
}
2017-02-08 03:31:42 -08:00
/**
* Query builder scope to search on location ID
*
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
* @ param text $search Search term
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeByLocationId ( $query , $search )
{
return $query -> where ( function ( $query ) use ( $search ) {
2017-11-16 16:49:48 -08:00
$query -> whereHas ( 'location' , function ( $query ) use ( $search ) {
2017-02-08 03:31:42 -08:00
$query -> where ( 'locations.id' , '=' , $search );
2017-08-25 06:30:10 -07:00
});
2017-02-08 03:31:42 -08:00
});
2017-11-03 20:10:05 -07:00
2017-02-08 03:31:42 -08:00
}
2017-05-15 20:55:39 -07:00
2017-10-17 11:20:05 -07:00
/**
2019-11-22 16:13:42 -08:00
* Query builder scope to search on depreciation name
2017-10-17 11:20:05 -07:00
* @ param \Illuminate\Database\Query\Builder $query Query builder instance
* @ param text $search Search term
*
* @ return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeByDepreciationId ( $query , $search )
{
return $query -> join ( 'models' , 'assets.model_id' , '=' , 'models.id' )
-> join ( 'depreciations' , 'models.depreciation_id' , '=' , 'depreciations.id' ) -> where ( 'models.depreciation_id' , '=' , $search );
}
2016-03-25 01:18:05 -07:00
}