From d262aec4c3d80688ca95043b4fb3cb5fca7a6ec4 Mon Sep 17 00:00:00 2001 From: Daniel Meltzer Date: Tue, 27 Dec 2016 19:24:41 -0500 Subject: [PATCH 1/9] Save Progress. --- app/Console/Commands/SendExpirationAlerts.php | 2 +- app/Http/Controllers/AssetsController.php | 18 ++++++-- app/Http/Controllers/ReportsController.php | 13 ++---- app/Http/Requests/AssetCheckoutRequest.php | 4 +- app/Models/Asset.php | 46 ++++++++++++++----- app/Models/Location.php | 10 +++- app/Models/Loggable.php | 12 ++++- app/Models/User.php | 5 +- app/Presenters/AssetPresenter.php | 6 +-- app/Presenters/LocationPresenter.php | 9 ++++ app/Presenters/UserPresenter.php | 9 ++++ resources/views/hardware/checkout.blade.php | 34 ++++++++++++-- resources/views/hardware/view.blade.php | 10 ++-- 13 files changed, 136 insertions(+), 42 deletions(-) diff --git a/app/Console/Commands/SendExpirationAlerts.php b/app/Console/Commands/SendExpirationAlerts.php index e47b99eaea..f8dfc8f0a4 100644 --- a/app/Console/Commands/SendExpirationAlerts.php +++ b/app/Console/Commands/SendExpirationAlerts.php @@ -68,7 +68,7 @@ class SendExpirationAlerts extends Command $asset_data['email_content'] .= ''.e($asset->present()->warrantee_expires()).''; $asset_data['email_content'] .= ''.$difference.' '.trans('mail.days').''; $asset_data['email_content'] .= ''.($asset->supplier ? e($asset->supplier->name) : '').''; - $asset_data['email_content'] .= ''.($asset->assigneduser ? e($asset->assigneduser->present()->fullName()) : '').''; + $asset_data['email_content'] .= ''.($asset->assignedTo ? e($asset->assignedTo->present()->name()) : '').''; $asset_data['email_content'] .= ''; } diff --git a/app/Http/Controllers/AssetsController.php b/app/Http/Controllers/AssetsController.php index a64de53d18..7b26ed8d57 100755 --- a/app/Http/Controllers/AssetsController.php +++ b/app/Http/Controllers/AssetsController.php @@ -416,7 +416,10 @@ class AssetsController extends Controller $this->authorize('checkout', $asset); // Get the dropdown of users and then pass it to the checkout view - return View::make('hardware/checkout', compact('asset'))->with('users_list', Helper::usersList()); + return View::make('hardware/checkout', compact('asset')) + ->with('users_list', Helper::usersList()) + ->with('assets_list', Helper::assetsList()) + ->with('locations_list', Helper::locationsList()); } @@ -431,7 +434,6 @@ class AssetsController extends Controller */ public function postCheckout(AssetCheckoutRequest $request, $assetId) { - // Check if the asset exists if (!$asset = Asset::find($assetId)) { return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); @@ -440,7 +442,14 @@ class AssetsController extends Controller } $this->authorize('checkout', $asset); - $user = User::find(Input::get('assigned_to')); + if(request('assigned_user')) { + $target = User::find(request('assigned_user')); + } elseif(request('assigned_asset')) { + $target = Asset::find(request('assigned_asset')); + } elseif(request('assigned_location')) { + $target = Location::find(request('assigned_location')); + } + // $user = User::find(Input::get('assigned_to')); $admin = Auth::user(); if ((Input::has('checkout_at')) && (Input::get('checkout_at')!= date("Y-m-d"))) { @@ -454,7 +463,7 @@ class AssetsController extends Controller } else { $expected_checkin = ''; } - if ($asset->checkOutToUser($user, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), e(Input::get('name')))) { + if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), e(Input::get('name')))) { // Redirect to the new asset page return redirect()->to("hardware")->with('success', trans('admin/hardware/message.checkout.success')); } @@ -518,6 +527,7 @@ class AssetsController extends Controller $asset->expected_checkin = null; $asset->last_checkout = null; $asset->assigned_to = null; + $asset->assignedTo()->disassociate($asset); $asset->accepted = null; $asset->name = e(Input::get('name')); diff --git a/app/Http/Controllers/ReportsController.php b/app/Http/Controllers/ReportsController.php index 55d1a77021..00815b8f6e 100644 --- a/app/Http/Controllers/ReportsController.php +++ b/app/Http/Controllers/ReportsController.php @@ -121,7 +121,7 @@ class ReportsController extends Controller // Open output stream $handle = fopen('php://output', 'w'); - Asset::with('assigneduser', 'assetloc','defaultLoc','assigneduser.userloc','model','supplier','assetstatus','model.manufacturer')->orderBy('created_at', 'DESC')->chunk(500, function($assets) use($handle, $customfields) { + Asset::with('assignedTo', 'assetLoc','defaultLoc','assigneduser.userloc','model','supplier','assetstatus','model.manufacturer')->orderBy('created_at', 'DESC')->chunk(500, function($assets) use($handle, $customfields) { $headers=[ trans('general.company'), trans('admin/hardware/table.asset_tag'), @@ -162,8 +162,7 @@ class ReportsController extends Controller ($asset->supplier) ? e($asset->supplier->name) : '', ($asset->assigneduser) ? e($asset->assigneduser->present()->fullName()) : '', ($asset->last_checkout!='') ? e($asset->last_checkout) : '', - ($asset->assigneduser && $asset->assigneduser->userloc!='') ? - e($asset->assigneduser->userloc->name) : ( ($asset->defaultLoc!='') ? e($asset->defaultLoc->name) : ''), + e($asset->assetLoc->present()->name()), ($asset->notes) ? e($asset->notes) : '', ]; foreach($customfields as $field) { @@ -244,15 +243,13 @@ class ReportsController extends Controller $row[] = e($asset->name); $row[] = e($asset->serial); - if ($asset->assigned_to > 0) { - $user = User::find($asset->assigned_to); - $row[] = e($user->present()->fullName()); + if ($target = $asset->assignedTo) { + $row[] = e($target->present()->name()); } else { $row[] = ''; // Empty string if unassigned } - if (( $asset->assigned_to > 0 ) && ( $asset->assigneduser->location_id > 0 )) { - $location = Location::find($asset->assigneduser->location_id); + if (( $asset->assigned_to > 0 ) && ( $location = $asset->assetLoc )) { if ($location->city) { $row[] = e($location->city) . ', ' . e($location->state); } elseif ($location->name) { diff --git a/app/Http/Requests/AssetCheckoutRequest.php b/app/Http/Requests/AssetCheckoutRequest.php index 9b3e98c2d6..7c341b3028 100644 --- a/app/Http/Requests/AssetCheckoutRequest.php +++ b/app/Http/Requests/AssetCheckoutRequest.php @@ -24,7 +24,9 @@ class AssetCheckoutRequest extends Request public function rules() { return [ - "assigned_to" => 'required', + "assigned_user" => 'required_without_all:assigned_asset,assigned_location', + "assigned_asset" => 'required_without_all:assigned_user,assigned_location', + "assigned_location" => 'required_without_all:assigned_user,assigned_asset', ]; } } diff --git a/app/Models/Asset.php b/app/Models/Asset.php index 995f4085fb..32a6cae796 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -22,6 +22,9 @@ class Asset extends Depreciable use Loggable, Requestable, Presentable; use SoftDeletes; + const LOCATION = 'location'; + const ASSET = 'asset'; + const USER = 'user'; /** * The database table used by the model. * @@ -91,9 +94,9 @@ class Asset extends Depreciable * @param null $name * @return bool */ - public function checkOutToUser($user, $admin, $checkout_at = null, $expected_checkin = null, $note = null, $name = null) + public function checkOut($target, $admin, $checkout_at = null, $expected_checkin = null, $note = null, $name = null) { - if (!$user) { + if (!$target) { return false; } @@ -103,7 +106,8 @@ class Asset extends Depreciable $this->last_checkout = $checkout_at; - $this->assigneduser()->associate($user); + $this->assignedTo()->associate($target); + if($name != null) { $this->name = $name; @@ -113,8 +117,6 @@ class Asset extends Depreciable $this->accepted="pending"; } - - if ($this->save()) { $log = $this->logCheckout($note); if ((($this->requireAcceptance()=='1') || ($this->getEula())) && ($user->email!='')) { @@ -150,7 +152,6 @@ class Asset extends Depreciable } - public function getDetailedNameAttribute() { if ($this->assignedUser) { @@ -209,18 +210,41 @@ class Asset extends Depreciable ->withTrashed(); } + public function assignedTo() + { + return $this->morphTo('assigned', 'assigned_type', 'assigned_to'); + } + + public function assignedAssets() + { + return $this->morphMany('App\Models\Asset', 'assigned', 'assigned_type', 'assigned_to')->withTrashed(); + } + /** * Get the asset's location based on the assigned user **/ - public function assetloc() + public function assetLoc() { - if ($this->assigneduser) { - return $this->assigneduser->userloc(); - } else { - return $this->belongsTo('\App\Models\Location', 'rtd_location_id'); + if(!empty($this->assignedType())) { + if ($this->assignedType() == self::ASSET) { + return $this->assignedTo->assetloc(); // Recurse until we have a final location + } elseif ($this->assignedType() == self::LOCATION) { + return $this->assignedTo(); + } + // Default to User +// var_dump($this); + if(!$this->assignedTo) { + dd($this); + } + return $this->assignedTo->userLoc(); } + return $this->defaultLoc(); } + public function assignedType() + { + return strtolower(class_basename($this->assigned_type)); + } /** * Get the asset's location based on default RTD location **/ diff --git a/app/Models/Location.php b/app/Models/Location.php index 174d4c577f..971dc3cc80 100755 --- a/app/Models/Location.php +++ b/app/Models/Location.php @@ -55,9 +55,9 @@ class Location extends SnipeModel return $this->hasManyThrough('\App\Models\Asset', '\App\Models\User', 'location_id', 'assigned_to', 'id'); } - public function assignedassets() + public function locationAssets() { - return $this->hasMany('\App\Models\Asset', 'rtd_location_id'); + return $this->hasMany('\App\Models\Asset', 'rtd_location_id')->orHas('assignedAssets'); } public function parent() @@ -70,6 +70,12 @@ class Location extends SnipeModel return $this->hasMany('\App\Models\Location', 'parent_id'); } + public function assignedAssets() + { + return $this->morphMany('App\Models\Asset', 'assigned', 'assigned_type', 'assigned_to')->withTrashed(); + // return $this->hasMany('\App\Models\Asset', 'assigned_to')->withTrashed(); + } + public static function getLocationHierarchy($locations, $parent_id = null) { diff --git a/app/Models/Loggable.php b/app/Models/Loggable.php index baf2086cb4..4845b37b65 100644 --- a/app/Models/Loggable.php +++ b/app/Models/Loggable.php @@ -45,7 +45,7 @@ trait Loggable $log->user_id = Auth::user()->id; if (!is_null($this->asset_id) || isset($target)) { - $log->target_type = Asset::class; + $log->target_type = $this->assigned_type; $log->target_id = $this->asset_id; } else if (!is_null($this->assigned_to)) { $log->target_type = User::class; @@ -53,7 +53,15 @@ trait Loggable } $item = call_user_func(array($log->target_type, 'find'), $log->target_id); - $log->location_id = $item->location_id; + $class = get_class($item); + if($class == Location::class) { + // We can checkout to a location + $log->location_id = $item->id; + } else if ($class== Asset::class) { + $log->location_id = $item->rtd_location_id; + } else { + $log->location_id = $item->location_id; + } $log->note = $note; $log->logaction('checkout'); diff --git a/app/Models/User.php b/app/Models/User.php index c7fca06647..38cde9931b 100755 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -127,9 +127,10 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo /** * Get assets assigned to this user */ - public function assets() + public function assignedAssets() { - return $this->hasMany('\App\Models\Asset', 'assigned_to')->withTrashed(); + return $this->morphMany('App\Models\Asset', 'assigned', 'assigned_type', 'assigned_to')->withTrashed(); + // return $this->hasMany('\App\Models\Asset', 'assigned_to')->withTrashed(); } /** diff --git a/app/Presenters/AssetPresenter.php b/app/Presenters/AssetPresenter.php index 8fb9e76a9e..935fc8ebe5 100644 --- a/app/Presenters/AssetPresenter.php +++ b/app/Presenters/AssetPresenter.php @@ -80,14 +80,14 @@ class AssetPresenter extends Presenter $results['status_label'] = ''; $results['assigned_to'] = ''; - if($assigned = $this->model->assigneduser) { + if($assigned = $this->model->assignedTo) { $results['status_label'] = 'Deployed'; - $results['assigned_to'] = (string) link_to_route('users.show', $assigned->present()->fullName(), $this->assigned_to ); + $results['assigned_to'] = $assigned->present()->nameUrl(); } else if($this->model->assetstatus) { $results['status_label'] = $this->model->assetstatus->name; } $results['location'] = ''; - if (isset($assigned) and !empty($assignedLoc = $assigned->userloc)) { + if (isset($assigned) and !empty($assignedLoc = $this->model->assetLoc)) { $results['location'] = $assignedLoc->present()->nameUrl(); } else if (!empty($this->model->defaultLoc)) { $results['location'] = $this->model->defaultLoc->present()->nameUrl(); diff --git a/app/Presenters/LocationPresenter.php b/app/Presenters/LocationPresenter.php index 5b751f6b48..c1c8da1e64 100644 --- a/app/Presenters/LocationPresenter.php +++ b/app/Presenters/LocationPresenter.php @@ -56,6 +56,15 @@ class LocationPresenter extends Presenter return (string)link_to_route('locations.show', $this->name, $this->id); } + /** + * Getter for Polymorphism. + * @return mixed + */ + public function name() + { + return $this->model->name; + } + /** * Url to view this item. * @return string diff --git a/app/Presenters/UserPresenter.php b/app/Presenters/UserPresenter.php index 0bcc9ef1de..b4f047cadb 100644 --- a/app/Presenters/UserPresenter.php +++ b/app/Presenters/UserPresenter.php @@ -109,6 +109,15 @@ class UserPresenter extends Presenter return "{$this->first_name} {$this->last_name}"; } + /** + * Standard accessor. + * @TODO Remove presenter::fullName() entirely? + * @return string + */ + public function name() + { + return $this->fullName(); + } /** * Returns the user Gravatar image url. * diff --git a/resources/views/hardware/checkout.blade.php b/resources/views/hardware/checkout.blade.php index e666b353bc..31a1c982eb 100755 --- a/resources/views/hardware/checkout.blade.php +++ b/resources/views/hardware/checkout.blade.php @@ -47,14 +47,40 @@
- {{ Form::label('assigned_to', trans('admin/hardware/form.checkout_to'), array('class' => 'col-md-3 control-label')) }} + {{ Form::label('assigned_user', trans('admin/hardware/form.checkout_to'), array('class' => 'col-md-3 control-label')) }}
- {{ Form::select('assigned_to', $users_list , Input::old('assigned_to', $asset->assigned_to), array('class'=>'select2', 'id'=>'assigned_to', 'style'=>'width:100%')) }} + {{ Form::select('assigned_user', $users_list , Input::old('assigned_user', $asset->assigned_type == 'App\Models\User' ? $asset->assigned_to : 0), array('class'=>'select2', 'id'=>'assigned_user', 'style'=>'width:100%')) }} - {!! $errors->first('assigned_to', ' :message') !!} + {!! $errors->first('assigned_user', ' :message') !!}
- New + New +
+
+ + +
+ {{ Form::label('assigned_asset', trans('admin/hardware/form.checkout_to'), array('class' => 'col-md-3 control-label')) }} +
+ {{ Form::select('assigned_asset', $assets_list , Input::old('assigned_asset', $asset->assigned_type == 'App\Models\Asset' ? $asset->assigned_to : 0), array('class'=>'select2', 'id'=>'assigned_asset', 'style'=>'width:100%')) }} + + {!! $errors->first('assigned_asset', ' :message') !!} +
+
+ New +
+
+ + +
+ {{ Form::label('assigned_location', trans('admin/hardware/form.checkout_to'), array('class' => 'col-md-3 control-label')) }} +
+ {{ Form::select('assigned_location', $locations_list , Input::old('assigned_location', $asset->assigned_type == 'App\Models\Asset' ? $asset->assigned_to : 0), array('class'=>'select2', 'id'=>'assigned_location', 'style'=>'width:100%')) }} + + {!! $errors->first('assigned_location', ' :message') !!} +
+
+ New
diff --git a/resources/views/hardware/view.blade.php b/resources/views/hardware/view.blade.php index eccf174232..35e7dc1b72 100755 --- a/resources/views/hardware/view.blade.php +++ b/resources/views/hardware/view.blade.php @@ -229,7 +229,7 @@ @if ($asset->depreciation) - {{ trans('admin/hardware/form.depreciation') }} + {{ trans('general.depreciation') }} {{ $asset->depreciation->name }} ({{ $asset->depreciation->months }} @@ -347,11 +347,13 @@ @endif - @if (($asset->assigneduser) && ($asset->assigned_to > 0) && ($asset->deleted_at=='')) + @if (($asset->assignedTo) && ($asset->assigned_to > 0) && ($asset->deleted_at==''))

{{ trans('admin/hardware/form.checkedout_to') }}

- {{ $asset->assigneduser->present()->fullName() }} - {{ $asset->assigneduser->present()->fullName() }} + @if($asset->assigned_type == User::class) + {{ $asset->assigneduser->present()->fullName() }} + @endif + {!! $asset->assignedTo->present()->nameUrl() !!}