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 @@
+
+
+
+
+
+
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() }}
+ @if($asset->assigned_type == User::class)
+
+ @endif
+ {!! $asset->assignedTo->present()->nameUrl() !!}
|