Merge pull request #17833 from grokability/tighter-controls-on-licenses
Tighter controls on license deletion, also fixes #16227 adding more tables to location print
This commit is contained in:
@@ -37,10 +37,14 @@ class LocationsController extends Controller
|
||||
'address',
|
||||
'address2',
|
||||
'assets_count',
|
||||
'assets_count',
|
||||
'assigned_assets_count',
|
||||
'rtd_assets_count',
|
||||
'accessories_count',
|
||||
'assigned_accessories_count',
|
||||
'assigned_assets_count',
|
||||
'assigned_assets_count',
|
||||
'components_count',
|
||||
'consumables_count',
|
||||
'users_count',
|
||||
'children_count',
|
||||
'city',
|
||||
'country',
|
||||
'created_at',
|
||||
@@ -54,7 +58,6 @@ class LocationsController extends Controller
|
||||
'rtd_assets_count',
|
||||
'state',
|
||||
'updated_at',
|
||||
'users_count',
|
||||
'zip',
|
||||
'notes',
|
||||
];
|
||||
@@ -79,8 +82,9 @@ class LocationsController extends Controller
|
||||
'locations.currency',
|
||||
'locations.company_id',
|
||||
'locations.notes',
|
||||
'locations.created_by',
|
||||
'locations.deleted_at',
|
||||
])
|
||||
->withCount('assignedAssets as assigned_assets_count')
|
||||
->withCount('assignedAssets as assigned_assets_count')
|
||||
->withCount('assets as assets_count')
|
||||
->withCount('assignedAccessories as assigned_accessories_count')
|
||||
@@ -88,6 +92,8 @@ class LocationsController extends Controller
|
||||
->withCount('rtd_assets as rtd_assets_count')
|
||||
->withCount('children as children_count')
|
||||
->withCount('users as users_count')
|
||||
->withCount('consumables as consumables_count')
|
||||
->withCount('components as components_count')
|
||||
->with('adminuser');
|
||||
|
||||
// Only scope locations if the setting is enabled
|
||||
@@ -131,6 +137,14 @@ class LocationsController extends Controller
|
||||
$locations->where('locations.company_id', '=', $request->input('company_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('parent_id')) {
|
||||
$locations->where('locations.parent_id', '=', $request->input('parent_id'));
|
||||
}
|
||||
|
||||
if ($request->input('status') == 'deleted') {
|
||||
$locations->onlyTrashed();
|
||||
}
|
||||
|
||||
// Make sure the offset and limit are actually integers and do not exceed system limits
|
||||
$offset = ($request->input('offset') > $locations->count()) ? $locations->count() : app('api_offset_value');
|
||||
$limit = app('api_limit_value');
|
||||
@@ -224,8 +238,13 @@ class LocationsController extends Controller
|
||||
])
|
||||
->withCount('assignedAssets as assigned_assets_count')
|
||||
->withCount('assets as assets_count')
|
||||
->withCount('assignedAccessories as assigned_accessories_count')
|
||||
->withCount('accessories as accessories_count')
|
||||
->withCount('rtd_assets as rtd_assets_count')
|
||||
->withCount('children as children_count')
|
||||
->withCount('users as users_count')
|
||||
->withCount('consumables as consumables_count')
|
||||
->withCount('components as components_count')
|
||||
->findOrFail($id);
|
||||
|
||||
return (new LocationsTransformer)->transformLocation($location);
|
||||
@@ -320,11 +339,15 @@ class LocationsController extends Controller
|
||||
{
|
||||
$this->authorize('delete', Location::class);
|
||||
$location = Location::withCount('assignedAssets as assigned_assets_count')
|
||||
->withCount('assignedAssets as assigned_assets_count')
|
||||
->withCount('assets as assets_count')
|
||||
->withCount('assignedAccessories as assigned_accessories_count')
|
||||
->withCount('accessories as accessories_count')
|
||||
->withCount('rtd_assets as rtd_assets_count')
|
||||
->withCount('children as children_count')
|
||||
->withCount('users as users_count')
|
||||
->withCount('accessories as accessories_count')
|
||||
->withCount('consumables as consumables_count')
|
||||
->withCount('components as components_count')
|
||||
->findOrFail($id);
|
||||
|
||||
if (! $location->isDeletable()) {
|
||||
|
||||
@@ -189,30 +189,36 @@ class LocationsController extends Controller
|
||||
{
|
||||
$this->authorize('delete', Location::class);
|
||||
|
||||
if (is_null($location = Location::find($locationId))) {
|
||||
$location = Location::withCount('assignedAssets as assigned_assets_count')
|
||||
->withCount('assets as assets_count')
|
||||
->withCount('assignedAccessories as assigned_accessories_count')
|
||||
->withCount('accessories as accessories_count')
|
||||
->withCount('rtd_assets as rtd_assets_count')
|
||||
->withCount('children as children_count')
|
||||
->withCount('users as users_count')
|
||||
->withCount('consumables as consumables_count')
|
||||
->withCount('components as components_count')
|
||||
->find($locationId);
|
||||
|
||||
if (!$location) {
|
||||
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.does_not_exist'));
|
||||
}
|
||||
|
||||
if ($location->users()->count() > 0) {
|
||||
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_users'));
|
||||
} elseif ($location->children()->count() > 0) {
|
||||
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_child_loc'));
|
||||
} elseif ($location->assets()->count() > 0) {
|
||||
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_assets'));
|
||||
} elseif ($location->assignedassets()->count() > 0) {
|
||||
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_assets'));
|
||||
}
|
||||
if ($location->isDeletable()) {
|
||||
|
||||
if ($location->image) {
|
||||
try {
|
||||
Storage::disk('public')->delete('locations/'.$location->image);
|
||||
} catch (\Exception $e) {
|
||||
Log::error($e);
|
||||
if ($location->image) {
|
||||
try {
|
||||
Storage::disk('public')->delete('locations/'.$location->image);
|
||||
} catch (\Exception $e) {
|
||||
Log::error($e);
|
||||
}
|
||||
}
|
||||
$location->delete();
|
||||
return redirect()->to(route('locations.index'))->with('success', trans('admin/locations/message.delete.success'));
|
||||
} else {
|
||||
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_users'));
|
||||
}
|
||||
$location->delete();
|
||||
|
||||
return redirect()->to(route('locations.index'))->with('success', trans('admin/locations/message.delete.success'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,23 +253,41 @@ class LocationsController extends Controller
|
||||
$this->authorize('view', Location::class);
|
||||
|
||||
if ($location = Location::where('id', $id)->first()) {
|
||||
$parent = Location::where('id', $location->parent_id)->first();
|
||||
$manager = User::where('id', $location->manager_id)->first();
|
||||
$company = Company::where('id', $location->company_id)->first();
|
||||
$users = User::where('location_id', $id)->with('company', 'department', 'location')->get();
|
||||
$assets = Asset::where('assigned_to', $id)->where('assigned_type', Location::class)->with('model', 'model.category')->get();
|
||||
return view('locations/print')
|
||||
->with('assets', $assets)
|
||||
->with('users',$users)
|
||||
->with('assigned', false)
|
||||
->with('assets', $location->assets)
|
||||
->with('assignedAssets', $location->assignedAssets)
|
||||
->with('accessories', $location->accessories)
|
||||
->with('assignedAccessories', $location->assignedAccessories)
|
||||
->with('users',$location->users)
|
||||
->with('location', $location)
|
||||
->with('parent', $parent)
|
||||
->with('manager', $manager)
|
||||
->with('company', $company);
|
||||
->with('consumables', $location->consumables)
|
||||
->with('components', $location->components)
|
||||
->with('children', $location->children);
|
||||
}
|
||||
|
||||
return redirect()->route('locations.index')->with('error', trans('admin/locations/message.does_not_exist'));
|
||||
}
|
||||
|
||||
public function print_all_assigned($id) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('view', Location::class);
|
||||
if ($location = Location::where('id', $id)->first()) {
|
||||
return view('locations/print')
|
||||
->with('assigned', true)
|
||||
->with('assets', $location->assets)
|
||||
->with('assignedAssets', $location->assignedAssets)
|
||||
->with('accessories', $location->accessories)
|
||||
->with('assignedAccessories', $location->assignedAccessories)
|
||||
->with('users',$location->users)
|
||||
->with('location', $location)
|
||||
->with('consumables', $location->consumables)
|
||||
->with('components', $location->components)
|
||||
->with('children', $location->children);
|
||||
}
|
||||
return redirect()->route('locations.index')->with('error', trans('admin/locations/message.does_not_exist'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a view that presents a form to clone a location.
|
||||
@@ -321,33 +345,12 @@ class LocationsController extends Controller
|
||||
return redirect()->route('locations.index')->with('success', trans('admin/locations/message.restore.success'));
|
||||
}
|
||||
|
||||
// Check validation
|
||||
return redirect()->back()->with('error', trans('general.could_not_restore', ['item_type' => trans('general.location'), 'error' => $location->getErrors()->first()]));
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', trans('admin/models/message.does_not_exist'));
|
||||
|
||||
}
|
||||
public function print_all_assigned($id) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('view', Location::class);
|
||||
if ($location = Location::where('id', $id)->first()) {
|
||||
$parent = Location::where('id', $location->parent_id)->first();
|
||||
$manager = User::where('id', $location->manager_id)->first();
|
||||
$company = Company::where('id', $location->company_id)->first();
|
||||
$users = User::where('location_id', $id)->with('company', 'department', 'location')->get();
|
||||
$assets = Asset::where('location_id', $id)->with('model', 'model.category')->get();
|
||||
return view('locations/print')
|
||||
->with('assets', $assets)
|
||||
->with('users',$users)
|
||||
->with('location', $location)
|
||||
->with('parent', $parent)
|
||||
->with('manager', $manager)
|
||||
->with('company', $company);
|
||||
}
|
||||
return redirect()->route('locations.index')->with('error', trans('admin/locations/message.does_not_exist'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a view that allows the user to bulk delete locations
|
||||
@@ -366,8 +369,12 @@ class LocationsController extends Controller
|
||||
$locations = Location::whereIn('id', $locations_raw_array)
|
||||
->withCount('assignedAssets as assigned_assets_count')
|
||||
->withCount('assets as assets_count')
|
||||
->withCount('assignedAccessories as assigned_accessories_count')
|
||||
->withCount('accessories as accessories_count')
|
||||
->withCount('rtd_assets as rtd_assets_count')
|
||||
->withCount('children as children_count')
|
||||
->withCount('consumables as consumables_count')
|
||||
->withCount('components as components_count')
|
||||
->withCount('users as users_count')->get();
|
||||
|
||||
$valid_count = 0;
|
||||
@@ -400,9 +407,13 @@ class LocationsController extends Controller
|
||||
$locations = Location::whereIn('id', $locations_raw_array)
|
||||
->withCount('assignedAssets as assigned_assets_count')
|
||||
->withCount('assets as assets_count')
|
||||
->withCount('assignedAccessories as assigned_accessories_count')
|
||||
->withCount('accessories as accessories_count')
|
||||
->withCount('rtd_assets as rtd_assets_count')
|
||||
->withCount('children as children_count')
|
||||
->withCount('users as users_count')->get();
|
||||
->withCount('users as users_count')
|
||||
->withCount('consumables as consumables_count')
|
||||
->withCount('components as components_count')->get();
|
||||
|
||||
$success_count = 0;
|
||||
$error_count = 0;
|
||||
|
||||
@@ -53,6 +53,9 @@ class LocationsTransformer
|
||||
'assets_count' => (int) $location->assets_count,
|
||||
'rtd_assets_count' => (int) $location->rtd_assets_count,
|
||||
'users_count' => (int) $location->users_count,
|
||||
'consumables_count' => (int) $location->consumables_count,
|
||||
'components_count' => (int) $location->components_count,
|
||||
'children_count' => (int) $location->children_count,
|
||||
'currency' => ($location->currency) ? e($location->currency) : null,
|
||||
'ldap_ou' => ($location->ldap_ou) ? e($location->ldap_ou) : null,
|
||||
'notes' => Helper::parseEscapedMarkedownInline($location->notes),
|
||||
@@ -76,12 +79,13 @@ class LocationsTransformer
|
||||
];
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'update' => Gate::allows('update', Location::class) ? true : false,
|
||||
'update' => (Gate::allows('update', Location::class) && ($location->deleted_at == '')),
|
||||
'delete' => $location->isDeletable(),
|
||||
'bulk_selectable' => [
|
||||
'delete' => $location->isDeletable()
|
||||
],
|
||||
'clone' => (Gate::allows('create', Location::class) && ($location->deleted_at == '')),
|
||||
'restore' => (Gate::allows('create', Location::class) && ($location->deleted_at != '')),
|
||||
];
|
||||
|
||||
$array += $permissions_array;
|
||||
|
||||
+12
-5
@@ -43,6 +43,7 @@ class Location extends SnipeModel
|
||||
'company_id' => 'integer',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Whether the model should inject its identifier to the unique
|
||||
* validation rules before attempting validation. If this property
|
||||
@@ -113,13 +114,19 @@ class Location extends SnipeModel
|
||||
{
|
||||
|
||||
return Gate::allows('delete', $this)
|
||||
&& ($this->assets_count == 0)
|
||||
&& ($this->assigned_assets_count == 0)
|
||||
&& ($this->children_count == 0)
|
||||
&& ($this->accessories_count == 0)
|
||||
&& ($this->users_count == 0);
|
||||
&& ($this->deleted_at == '')
|
||||
&& (($this->assets_count ?? $this->assets()->count()) === 0)
|
||||
&& (($this->assigned_assets_count ?? $this->assignedAssets()->count()) === 0)
|
||||
&& (($this->accessories_count ?? $this->accessories()->count()) === 0)
|
||||
&& (($this->assigned_accessories_count ?? $this->assignedAccessories()->count()) === 0)
|
||||
&& (($this->children_count ?? $this->children()->count()) === 0)
|
||||
&& (($this->components_count ?? $this->components()->count()) === 0)
|
||||
&& (($this->consumables_count ?? $this->consumables()->count()) === 0)
|
||||
&& (($this->rtd_assets_count ?? $this->rtd_assets()->count()) === 0)
|
||||
&& (($this->users_count ?? $this->users()->count()) === 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Establishes the user -> location relationship
|
||||
*
|
||||
|
||||
@@ -61,6 +61,15 @@ class LocationPresenter extends Presenter
|
||||
'title' => trans('admin/locations/table.parent'),
|
||||
'visible' => true,
|
||||
'formatter' => 'locationsLinkObjFormatter',
|
||||
], [
|
||||
'field' => 'users_count',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.people'),
|
||||
'titleTooltip' => trans('general.people'),
|
||||
'visible' => true,
|
||||
'class' => 'css-house-user',
|
||||
], [
|
||||
'field' => 'assets_count',
|
||||
'searchable' => false,
|
||||
@@ -98,7 +107,7 @@ class LocationPresenter extends Presenter
|
||||
'titleTooltip' => trans('general.accessories'),
|
||||
'visible' => true,
|
||||
'class' => 'css-accessory',
|
||||
], [
|
||||
],[
|
||||
'field' => 'assigned_accessories_count',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
@@ -108,14 +117,34 @@ class LocationPresenter extends Presenter
|
||||
'visible' => true,
|
||||
'class' => 'css-accessory-alt',
|
||||
], [
|
||||
'field' => 'users_count',
|
||||
'field' => 'components_count',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.people'),
|
||||
'titleTooltip' => trans('general.people'),
|
||||
'title' => trans('general.components'),
|
||||
'titleTooltip' => trans('general.components'),
|
||||
'visible' => true,
|
||||
'class' => 'css-house-user',
|
||||
'class' => 'css-component',
|
||||
],
|
||||
[
|
||||
'field' => 'consumables_count',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.consumables'),
|
||||
'titleTooltip' => trans('general.consumables'),
|
||||
'visible' => true,
|
||||
'class' => 'css-consumable',
|
||||
],
|
||||
[
|
||||
'field' => 'children_count',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.child_locations'),
|
||||
'titleTooltip' => trans('general.child_locations'),
|
||||
'visible' => true,
|
||||
'class' => 'css-child-locations',
|
||||
], [
|
||||
'field' => 'currency',
|
||||
'searchable' => true,
|
||||
|
||||
@@ -60,18 +60,14 @@ class UserPresenter extends Presenter
|
||||
'title' => trans('admin/users/table.name'),
|
||||
'visible' => true,
|
||||
'formatter' => 'usersLinkFormatter',
|
||||
],
|
||||
|
||||
[
|
||||
], [
|
||||
'field' => 'first_name',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'title' => trans('general.first_name'),
|
||||
'visible' => false,
|
||||
'formatter' => 'usersLinkFormatter',
|
||||
],
|
||||
|
||||
[
|
||||
], [
|
||||
'field' => 'last_name',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
@@ -85,7 +81,23 @@ class UserPresenter extends Presenter
|
||||
'sortable' => true,
|
||||
'switchable' => false,
|
||||
'title' => trans('admin/users/table.display_name'),
|
||||
'visible' => false,
|
||||
], [
|
||||
'field' => 'username',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => false,
|
||||
'title' => trans('admin/users/table.username'),
|
||||
'visible' => true,
|
||||
'formatter' => 'usernameRoleLinkFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'employee_num',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.employee_number'),
|
||||
'visible' => false,
|
||||
],
|
||||
[
|
||||
'field' => 'jobtitle',
|
||||
@@ -129,7 +141,7 @@ class UserPresenter extends Presenter
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('admin/users/table.phone'),
|
||||
'visible' => true,
|
||||
'visible' => false,
|
||||
'formatter' => 'phoneFormatter',
|
||||
],
|
||||
[
|
||||
@@ -190,24 +202,7 @@ class UserPresenter extends Presenter
|
||||
'title' => trans('general.zip'),
|
||||
'visible' => false,
|
||||
],
|
||||
[
|
||||
'field' => 'username',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => false,
|
||||
'title' => trans('admin/users/table.username'),
|
||||
'visible' => true,
|
||||
'formatter' => 'usernameRoleLinkFormatter',
|
||||
],
|
||||
|
||||
[
|
||||
'field' => 'employee_num',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.employee_number'),
|
||||
'visible' => false,
|
||||
],
|
||||
[
|
||||
'field' => 'locale',
|
||||
'searchable' => true,
|
||||
@@ -231,7 +226,7 @@ class UserPresenter extends Presenter
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('admin/users/general.department_manager'),
|
||||
'visible' => true,
|
||||
'visible' => false,
|
||||
'formatter' => 'usersLinkObjFormatter',
|
||||
],
|
||||
[
|
||||
@@ -248,7 +243,7 @@ class UserPresenter extends Presenter
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'title' => trans('admin/users/table.manager'),
|
||||
'visible' => true,
|
||||
'visible' => false,
|
||||
'formatter' => 'usersLinkObjFormatter',
|
||||
],
|
||||
[
|
||||
|
||||
@@ -1049,6 +1049,7 @@ th.css-license > .th-inner,
|
||||
th.css-location > .th-inner,
|
||||
th.css-users > .th-inner,
|
||||
th.css-currency > .th-inner,
|
||||
th.css-child-locations > .th-inner,
|
||||
th.css-history > .th-inner {
|
||||
font-size: 0px;
|
||||
line-height: 0.75 !important;
|
||||
@@ -1071,6 +1072,7 @@ th.css-license > .th-inner::before,
|
||||
th.css-location > .th-inner::before,
|
||||
th.css-users > .th-inner::before,
|
||||
th.css-currency > .th-inner::before,
|
||||
th.css-child-locations > .th-inner::before,
|
||||
th.css-history > .th-inner::before {
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
@@ -1152,6 +1154,12 @@ th.css-accessory-alt > .th-inner::before {
|
||||
font-size: 19px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
th.css-child-locations > .th-inner::before {
|
||||
content: "\f64f";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-size: 19px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
th.css-currency > .th-inner::before {
|
||||
content: "\24";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -673,6 +673,7 @@ th.css-license > .th-inner,
|
||||
th.css-location > .th-inner,
|
||||
th.css-users > .th-inner,
|
||||
th.css-currency > .th-inner,
|
||||
th.css-child-locations > .th-inner,
|
||||
th.css-history > .th-inner {
|
||||
font-size: 0px;
|
||||
line-height: 0.75 !important;
|
||||
@@ -695,6 +696,7 @@ th.css-license > .th-inner::before,
|
||||
th.css-location > .th-inner::before,
|
||||
th.css-users > .th-inner::before,
|
||||
th.css-currency > .th-inner::before,
|
||||
th.css-child-locations > .th-inner::before,
|
||||
th.css-history > .th-inner::before {
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
@@ -776,6 +778,12 @@ th.css-accessory-alt > .th-inner::before {
|
||||
font-size: 19px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
th.css-child-locations > .th-inner::before {
|
||||
content: "\f64f";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-size: 19px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
th.css-currency > .th-inner::before {
|
||||
content: "\24";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
|
||||
File diff suppressed because one or more lines are too long
Vendored
+16
@@ -22385,6 +22385,7 @@ th.css-license > .th-inner,
|
||||
th.css-location > .th-inner,
|
||||
th.css-users > .th-inner,
|
||||
th.css-currency > .th-inner,
|
||||
th.css-child-locations > .th-inner,
|
||||
th.css-history > .th-inner {
|
||||
font-size: 0px;
|
||||
line-height: 0.75 !important;
|
||||
@@ -22407,6 +22408,7 @@ th.css-license > .th-inner::before,
|
||||
th.css-location > .th-inner::before,
|
||||
th.css-users > .th-inner::before,
|
||||
th.css-currency > .th-inner::before,
|
||||
th.css-child-locations > .th-inner::before,
|
||||
th.css-history > .th-inner::before {
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
@@ -22488,6 +22490,12 @@ th.css-accessory-alt > .th-inner::before {
|
||||
font-size: 19px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
th.css-child-locations > .th-inner::before {
|
||||
content: "\f64f";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-size: 19px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
th.css-currency > .th-inner::before {
|
||||
content: "\24";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
@@ -23989,6 +23997,7 @@ th.css-license > .th-inner,
|
||||
th.css-location > .th-inner,
|
||||
th.css-users > .th-inner,
|
||||
th.css-currency > .th-inner,
|
||||
th.css-child-locations > .th-inner,
|
||||
th.css-history > .th-inner {
|
||||
font-size: 0px;
|
||||
line-height: 0.75 !important;
|
||||
@@ -24011,6 +24020,7 @@ th.css-license > .th-inner::before,
|
||||
th.css-location > .th-inner::before,
|
||||
th.css-users > .th-inner::before,
|
||||
th.css-currency > .th-inner::before,
|
||||
th.css-child-locations > .th-inner::before,
|
||||
th.css-history > .th-inner::before {
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
@@ -24092,6 +24102,12 @@ th.css-accessory-alt > .th-inner::before {
|
||||
font-size: 19px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
th.css-child-locations > .th-inner::before {
|
||||
content: "\f64f";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-size: 19px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
th.css-currency > .th-inner::before {
|
||||
content: "\24";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=76d88f0f91b852f7eecbce357ab5858b",
|
||||
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=42f97cd5b9ee7521b04a448e7fc16ac9",
|
||||
"/css/dist/skins/_all-skins.css": "/css/dist/skins/_all-skins.css?id=d81a7ed323f68a7c5e3e9115f7fb5404",
|
||||
"/css/build/overrides.css": "/css/build/overrides.css?id=257e65d85ce9cf5a413065df1b131c03",
|
||||
"/css/build/app.css": "/css/build/app.css?id=3dcb1500ec5991cc4058fd5e4d9b8b49",
|
||||
"/css/build/overrides.css": "/css/build/overrides.css?id=d8bef2b8ef03ee8dbb120749211eafc0",
|
||||
"/css/build/app.css": "/css/build/app.css?id=1bf6a5e78cbccff6e6d32640c28c54b8",
|
||||
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=ee0ed88465dd878588ed044eefb67723",
|
||||
"/css/dist/skins/skin-yellow.css": "/css/dist/skins/skin-yellow.css?id=3d8a3d2035ea28aaad4a703c2646f515",
|
||||
"/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=3979929a3423ff35b96b1fc84299fdf3",
|
||||
@@ -19,7 +19,7 @@
|
||||
"/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=b2cd9f59d7e8587939ce27b2d3363d82",
|
||||
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=7277edd636cf46aa7786a4449ce0ead7",
|
||||
"/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=cbd06cc1d58197ccc81d4376bbaf0d28",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=a6b8969f0f70c07cf740f30bb7139b45",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=dd5f7ab27ec80569b90d63a883718ff9",
|
||||
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||
"/js/select2/i18n/af.js": "/js/select2/i18n/af.js?id=4f6fcd73488ce79fae1b7a90aceaecde",
|
||||
|
||||
@@ -746,6 +746,7 @@ th.css-license > .th-inner,
|
||||
th.css-location > .th-inner,
|
||||
th.css-users > .th-inner,
|
||||
th.css-currency > .th-inner,
|
||||
th.css-child-locations > .th-inner,
|
||||
th.css-history > .th-inner
|
||||
{
|
||||
font-size: 0px;
|
||||
@@ -771,6 +772,7 @@ th.css-license > .th-inner::before,
|
||||
th.css-location > .th-inner::before,
|
||||
th.css-users > .th-inner::before,
|
||||
th.css-currency > .th-inner::before,
|
||||
th.css-child-locations > .th-inner::before,
|
||||
th.css-history > .th-inner::before
|
||||
{
|
||||
display: inline-block;
|
||||
@@ -853,6 +855,13 @@ th.css-accessory-alt > .th-inner::before {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
th.css-child-locations > .th-inner::before {
|
||||
content: "\f64f"; // change this to f51e for coins
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-size: 19px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
th.css-currency > .th-inner::before {
|
||||
content: "\24"; // change this to f51e for coins
|
||||
font-family: "Font Awesome 5 Free";
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
return array(
|
||||
|
||||
'does_not_exist' => 'Location does not exist.',
|
||||
'assoc_users' => 'This location is not currently deletable because it is the location of record for at least one asset or user, has assets assigned to it, or is the parent location of another location. Please update your records to no longer reference this location and try again ',
|
||||
'assoc_users' => 'This location is not currently deletable because it is the location of record for at least one item or user, has assets assigned to it, or is the parent location of another location. Please update your records to no longer reference this location and try again ',
|
||||
'assoc_assets' => 'This location is currently associated with at least one asset and cannot be deleted. Please update your assets to no longer reference this location and try again. ',
|
||||
'assoc_child_loc' => 'This location is currently the parent of at least one child location and cannot be deleted. Please update your locations to no longer reference this location and try again. ',
|
||||
'assigned_assets' => 'Assigned Assets',
|
||||
'current_location' => 'Current Location',
|
||||
'open_map' => 'Open in :map_provider_icon Maps',
|
||||
'deleted_warning' => 'This location has been deleted. Please restore it before attempting to make any changes.',
|
||||
|
||||
|
||||
'create' => array(
|
||||
|
||||
@@ -12,7 +12,8 @@ return [
|
||||
'create' => 'Create Location',
|
||||
'update' => 'Update Location',
|
||||
'print_assigned' => 'Print Assigned',
|
||||
'print_all_assigned' => 'Print All Assigned',
|
||||
'print_inventory' => 'Print Inventory',
|
||||
'print_all_assigned' => 'Print Inventory and Assigned',
|
||||
'name' => 'Location Name',
|
||||
'address' => 'Address',
|
||||
'address2' => 'Address Line 2',
|
||||
|
||||
@@ -11,7 +11,6 @@ return array(
|
||||
'title' => 'Asset Models',
|
||||
'update' => 'Update Asset Model',
|
||||
'view' => 'View Asset Model',
|
||||
'update' => 'Update Asset Model',
|
||||
'clone' => 'Clone Model',
|
||||
'edit' => 'Edit Model',
|
||||
'clone' => 'Clone Model',
|
||||
'edit' => 'Edit Model',
|
||||
);
|
||||
|
||||
@@ -614,6 +614,7 @@ return [
|
||||
'footer_credit' => '<a target="_blank" href="https://snipeitapp.com" rel="noopener">Snipe-IT</a> is open source software, made with <i class="fa fa-heart" aria-hidden="true" style="color: #a94442; font-size: 10px" /></i><span class="sr-only">love</span> by <a href="https://bsky.app/profile/snipeitapp.com" rel="noopener">@snipeitapp.com</a>.',
|
||||
'set_password' => 'Set a Password',
|
||||
'upload_deleted' => 'Upload Deleted',
|
||||
'child_locations' => 'Child Locations',
|
||||
|
||||
// Add form placeholders here
|
||||
'placeholders' => [
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
data-buttons="locationButtons"
|
||||
id="locationTable"
|
||||
class="table table-striped snipe-table"
|
||||
data-url="{{ route('api.locations.index', array('company_id'=>e(Request::get('company_id')))) }}"
|
||||
data-url="{{ route('api.locations.index', ['company_id'=>e(request('company_id')), 'status' => e(request('status'))]) }}"
|
||||
data-export-options='{
|
||||
"fileName": "export-locations-{{ date('Y-m-d') }}",
|
||||
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
|
||||
|
||||
@@ -49,107 +49,359 @@
|
||||
@endif
|
||||
@endif
|
||||
|
||||
<h2>{{ trans('general.assigned_to', array('name' => $location->display_name)) }}</h2>
|
||||
@if ($parent)
|
||||
{{ $parent->display_name }}
|
||||
<h2>
|
||||
@if ($assigned)
|
||||
{{ trans('general.assigned_to', array('name' => $location->display_name)) }}
|
||||
@else
|
||||
{{ trans('admin/locations/table.print_inventory') }} : {{ $location->display_name }}
|
||||
@endif
|
||||
</h2>
|
||||
@if ($location->parent)
|
||||
<strong>{{ trans('admin/locations/table.parent') }}:</strong> {{ $location->parent->display_name }}
|
||||
@endif
|
||||
<br>
|
||||
@if ($company)
|
||||
<b>{{ trans('admin/companies/table.name') }}:</b> {{ $company->display_name }}
|
||||
@if ($location->company)
|
||||
<b>{{ trans('admin/companies/table.name') }}:</b> {{ $location->company->display_name }}
|
||||
<br>
|
||||
@endif
|
||||
@if ($manager)
|
||||
<b>{{ trans('general.manager') }}</b> {{ $manager->display_name }}<br>
|
||||
@if ($location->manager)
|
||||
<b>{{ trans('admin/users/table.manager') }}:</b> {{ $location->manager->display_name }}<br>
|
||||
@endif
|
||||
<b>{{ trans('general.date') }}</b> {{ \App\Helpers\Helper::getFormattedDateObject(now(), 'datetime', false) }}<br><br>
|
||||
<b>{{ trans('general.date') }}:</b> {{ \App\Helpers\Helper::getFormattedDateObject(now(), 'datetime', false) }}<br><br>
|
||||
|
||||
@if ($users->count() > 0)
|
||||
@php
|
||||
$counter = 1;
|
||||
@endphp
|
||||
<table class="inventory">
|
||||
<thead>
|
||||
@php
|
||||
$counter = 1;
|
||||
@endphp
|
||||
<table class="inventory">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="6">{{ trans('general.users') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="6">{{ trans('general.users') }}</th>
|
||||
<th style="width: 5px;"></th>
|
||||
<th style="width: 25%;">{{ trans('general.company') }}</th>
|
||||
<th style="width: 25%;">{{ trans('admin/locations/table.user_name') }}</th>
|
||||
<th style="width: 10%;">{{ trans('general.employee_number') }}</th>
|
||||
<th style="width: 20%;">{{ trans('admin/locations/table.department') }}</th>
|
||||
<th style="width: 20%;">{{ trans('admin/locations/table.location') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5px;"></th>
|
||||
<th style="width: 25%;">{{ trans('general.company') }}</th>
|
||||
<th style="width: 25%;">{{ trans('admin/locations/table.user_name') }}</th>
|
||||
<th style="width: 10%;">{{ trans('general.employee_number') }}</th>
|
||||
<th style="width: 20%;">{{ trans('admin/locations/table.department') }}</th>
|
||||
<th style="width: 20%;">{{ trans('admin/locations/table.location') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@foreach ($users as $user)
|
||||
</thead>
|
||||
@foreach ($users as $user)
|
||||
|
||||
<tr>
|
||||
<td>{{ $counter }}</td>
|
||||
<td>{{ (($user) && ($user->company)) ? $user->company->name : '' }}</td>
|
||||
<td>{{ ($user) ? $user->first_name .' '. $user->last_name : '' }}</td>
|
||||
<td>{{ ($user) ? $user->employee_num : '' }}</td>
|
||||
<td>{{ (($user) && ($user->department)) ? $user->department->name : '' }}</td>
|
||||
<td>{{ (($user) && ($user->location)) ? $user->location->name : '' }}</td>
|
||||
</tr>
|
||||
@php
|
||||
$counter++
|
||||
@endphp
|
||||
@endforeach
|
||||
</table>
|
||||
<tr>
|
||||
<td>{{ $counter }}</td>
|
||||
<td>{{ (($user) && ($user->company)) ? $user->company->name : '' }}</td>
|
||||
<td>{{ ($user) ? $user->first_name .' '. $user->last_name : '' }}</td>
|
||||
<td>{{ ($user) ? $user->employee_num : '' }}</td>
|
||||
<td>{{ (($user) && ($user->department)) ? $user->department->name : '' }}</td>
|
||||
<td>{{ (($user) && ($user->location)) ? $user->location->name : '' }}</td>
|
||||
</tr>
|
||||
@php
|
||||
$counter++
|
||||
@endphp
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
|
||||
|
||||
|
||||
@if ($assets->count() > 0)
|
||||
@if ($children->count() > 0)
|
||||
<br><br>
|
||||
<table class="inventory">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="10">{{ trans('general.assets') }}</th>
|
||||
<th colspan="10">{{ trans('general.child_locations') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20px;"></th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_tag') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_name') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_category') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_manufacturer') }}</th>
|
||||
<th style="width: 15%;">{{ trans('admin/locations/table.asset_model') }}</th>
|
||||
<th style="width: 15%;">{{ trans('admin/locations/table.asset_serial') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_location') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_checked_out') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_expected_checkin') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@php
|
||||
$counter = 1;
|
||||
@endphp
|
||||
|
||||
@foreach ($assets as $asset)
|
||||
@php
|
||||
if($snipeSettings->show_archived_in_list != 1 && $asset->assetstatus?->archived == 1){
|
||||
continue;
|
||||
}
|
||||
@endphp
|
||||
<tr>
|
||||
<td>{{ $counter }}</td>
|
||||
<td>{{ $asset->asset_tag }}</td>
|
||||
<td>{{ $asset->name }}</td>
|
||||
<td>{{ (($asset->model) && ($asset->model->category)) ? $asset->model->category->name : '' }}</td>
|
||||
<td>{{ (($asset->model) && ($asset->model->manufacturer)) ? $asset->model->manufacturer->name : '' }}</td>
|
||||
<td>{{ ($asset->model) ? $asset->model->name : '' }}</td>
|
||||
<td>{{ $asset->serial }}</td>
|
||||
<td>{{ ($asset->location) ? $asset->location->name : '' }}</td>
|
||||
<td>{{ \App\Helpers\Helper::getFormattedDateObject( $asset->last_checkout, 'datetime', false) }}</td>
|
||||
<td>{{ \App\Helpers\Helper::getFormattedDateObject( $asset->expected_checkin, 'datetime', false) }}</td>
|
||||
<th style="width: 20px;"></th>
|
||||
<th>{{ trans('general.name') }}</th>
|
||||
<th>{{ trans('general.address') }}</th>
|
||||
<th>{{ trans('general.city') }}</th>
|
||||
<th>{{ trans('general.state') }}</th>
|
||||
<th>{{ trans('general.country') }}</th>
|
||||
<th>{{ trans('general.zip') }}</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
@php
|
||||
$counter = 1;
|
||||
@endphp
|
||||
|
||||
@foreach ($children as $child)
|
||||
<tr>
|
||||
<td>{{ $counter }}</td>
|
||||
<td>{{ $child->name }}</td>
|
||||
<td>{{ $child->address }}</td>
|
||||
<td>{{ $child->city }}</td>
|
||||
<td>{{ $child->state }}</td>
|
||||
<td>{{ $child->country }}</td>
|
||||
<td>{{ $child->zip }}</td>
|
||||
</tr>
|
||||
@php
|
||||
$counter++
|
||||
@endphp
|
||||
@endforeach
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
|
||||
@if ($assets->count() > 0)
|
||||
<br><br>
|
||||
<table class="inventory">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="10">{{ trans('general.assets') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20px;"></th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_tag') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_name') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_category') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_manufacturer') }}</th>
|
||||
<th style="width: 15%;">{{ trans('admin/locations/table.asset_model') }}</th>
|
||||
<th style="width: 15%;">{{ trans('admin/locations/table.asset_serial') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_location') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_checked_out') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_expected_checkin') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@php
|
||||
$counter = 1;
|
||||
@endphp
|
||||
|
||||
@foreach ($assets as $asset)
|
||||
@php
|
||||
if($snipeSettings->show_archived_in_list != 1 && $asset->assetstatus?->archived == 1){
|
||||
continue;
|
||||
}
|
||||
@endphp
|
||||
<tr>
|
||||
<td>{{ $counter }}</td>
|
||||
<td>{{ $asset->asset_tag }}</td>
|
||||
<td>{{ $asset->name }}</td>
|
||||
<td>{{ (($asset->model) && ($asset->model->category)) ? $asset->model->category->name : '' }}</td>
|
||||
<td>{{ (($asset->model) && ($asset->model->manufacturer)) ? $asset->model->manufacturer->name : '' }}</td>
|
||||
<td>{{ ($asset->model) ? $asset->model->name : '' }}</td>
|
||||
<td>{{ $asset->serial }}</td>
|
||||
<td>{{ ($asset->location) ? $asset->location->name : '' }}</td>
|
||||
<td>{{ \App\Helpers\Helper::getFormattedDateObject( $asset->last_checkout, 'datetime', false) }}</td>
|
||||
<td>{{ \App\Helpers\Helper::getFormattedDateObject( $asset->expected_checkin, 'datetime', false) }}</td>
|
||||
</tr>
|
||||
@php
|
||||
$counter++
|
||||
@endphp
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
|
||||
@if ($assigned)
|
||||
@if ($assignedAssets->count() > 0)
|
||||
<br><br>
|
||||
<table class="inventory">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="10">{{ trans('admin/locations/message.assigned_assets') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20px;"></th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_tag') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_name') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_category') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_manufacturer') }}</th>
|
||||
<th style="width: 15%;">{{ trans('admin/locations/table.asset_model') }}</th>
|
||||
<th style="width: 15%;">{{ trans('admin/locations/table.asset_serial') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_location') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_checked_out') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_expected_checkin') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@php
|
||||
$counter = 1;
|
||||
@endphp
|
||||
|
||||
@foreach ($assignedAssets as $asset)
|
||||
@php
|
||||
if($snipeSettings->show_archived_in_list != 1 && $asset->assetstatus?->archived == 1){
|
||||
continue;
|
||||
}
|
||||
@endphp
|
||||
<tr>
|
||||
<td>{{ $counter }}</td>
|
||||
<td>{{ $asset->asset_tag }}</td>
|
||||
<td>{{ $asset->name }}</td>
|
||||
<td>{{ (($asset->model) && ($asset->model->category)) ? $asset->model->category->name : '' }}</td>
|
||||
<td>{{ (($asset->model) && ($asset->model->manufacturer)) ? $asset->model->manufacturer->name : '' }}</td>
|
||||
<td>{{ ($asset->model) ? $asset->model->name : '' }}</td>
|
||||
<td>{{ $asset->serial }}</td>
|
||||
<td>{{ ($asset->location) ? $asset->location->name : '' }}</td>
|
||||
<td>{{ \App\Helpers\Helper::getFormattedDateObject( $asset->last_checkout, 'datetime', false) }}</td>
|
||||
<td>{{ \App\Helpers\Helper::getFormattedDateObject( $asset->expected_checkin, 'datetime', false) }}</td>
|
||||
</tr>
|
||||
@php
|
||||
$counter++
|
||||
@endphp
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@if ($accessories->count() > 0)
|
||||
<br><br>
|
||||
<table class="inventory">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="10">{{ trans('general.accessories') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20px;"></th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_name') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_category') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_manufacturer') }}</th>
|
||||
<th>{{ trans('admin/models/table.modelnumber') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_location') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@php
|
||||
$counter = 1;
|
||||
@endphp
|
||||
|
||||
@foreach ($accessories as $accessory)
|
||||
<tr>
|
||||
<td>{{ $counter }}</td>
|
||||
<td>{{ $accessory->name }}</td>
|
||||
<td>{{ ($accessory->category) ? $accessory->category->name : '' }}</td>
|
||||
<td>{{ ($accessory->manufacturer) ? $accessory->manufacturer->name : '' }}</td>
|
||||
<td>{{ $asset->model_number }}</td>
|
||||
<td>{{ ($asset->location) ? $asset->location->name : '' }}</td>
|
||||
</tr>
|
||||
@php
|
||||
$counter++
|
||||
@endphp
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
|
||||
@if ($assigned)
|
||||
@if ($assignedAccessories->count() > 0)
|
||||
<br><br>
|
||||
<table class="inventory">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="10">{{ trans('general.accessories_assigned') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20px;"></th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_name') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_category') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_manufacturer') }}</th>
|
||||
<th>{{ trans('admin/models/table.modelnumber') }}</th>
|
||||
<th style="width: 10%;">{{ trans('admin/locations/table.asset_location') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@php
|
||||
$counter = 1;
|
||||
@endphp
|
||||
|
||||
@foreach ($assignedAccessories as $accessory)
|
||||
<tr>
|
||||
<td>{{ $counter }}</td>
|
||||
<td>{{ $accessory->name }}</td>
|
||||
<td>{{ ($accessory->category) ? $accessory->category->name : '' }}</td>
|
||||
<td>{{ ($accessory->manufacturer) ? $accessory->manufacturer->name : '' }}</td>
|
||||
<td>{{ $asset->model_number }}</td>
|
||||
<td>{{ ($asset->location) ? $asset->location->name : '' }}</td>
|
||||
</tr>
|
||||
@php
|
||||
$counter++
|
||||
@endphp
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
@if ($consumables->count() > 0)
|
||||
<br><br>
|
||||
<table class="inventory">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="10">{{ trans('general.accessories') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20px;"></th>
|
||||
<th>{{ trans('admin/locations/table.asset_name') }}</th>
|
||||
<th>{{ trans('general.qty') }}</th>
|
||||
<th>{{ trans('admin/locations/table.asset_category') }}</th>
|
||||
<th>{{ trans('admin/locations/table.asset_manufacturer') }}</th>
|
||||
<th>{{ trans('admin/models/table.modelnumber') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@php
|
||||
$counter = 1;
|
||||
@endphp
|
||||
|
||||
@foreach ($consumables as $consumable)
|
||||
<tr>
|
||||
<td>{{ $counter }}</td>
|
||||
<td>{{ $consumable->name }}</td>
|
||||
<td>{{ $consumable->qty }}</td>
|
||||
<td>{{ ($consumable->category) ? $consumable->category->name : '' }}</td>
|
||||
<td>{{ ($consumable->manufacturer) ? $consumable->manufacturer->name : '' }}</td>
|
||||
<td>{{ $consumable->model_number }}</td>
|
||||
</tr>
|
||||
@php
|
||||
$counter++
|
||||
@endphp
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
|
||||
@if ($components->count() > 0)
|
||||
<br><br>
|
||||
<table class="inventory">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="10">{{ trans('general.components') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20px;"></th>
|
||||
<th>{{ trans('admin/locations/table.asset_name') }}</th>
|
||||
<th>{{ trans('general.qty') }}</th>
|
||||
<th>{{ trans('admin/locations/table.asset_category') }}</th>
|
||||
<th>{{ trans('admin/locations/table.asset_manufacturer') }}</th>
|
||||
<th>{{ trans('admin/models/table.modelnumber') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@php
|
||||
$counter = 1;
|
||||
@endphp
|
||||
|
||||
@foreach ($components as $component)
|
||||
<tr>
|
||||
<td>{{ $counter }}</td>
|
||||
<td>{{ $component->name }}</td>
|
||||
<td>{{ $component->qty }}</td>
|
||||
<td>{{ ($component->category) ? $component->category->name : '' }}</td>
|
||||
<td>{{ ($component->manufacturer) ? $component->manufacturer->name : '' }}</td>
|
||||
<td>{{ $component->model_number }}</td>
|
||||
</tr>
|
||||
@php
|
||||
$counter++
|
||||
@endphp
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
|
||||
@@ -157,26 +409,26 @@
|
||||
<br>
|
||||
<br>
|
||||
<table>
|
||||
<tr>
|
||||
<td>{{ trans('admin/locations/table.signed_by_asset_auditor') }}</td>
|
||||
<td><br>------------------------------------------------------ <br></td>
|
||||
<td>{{ trans('admin/locations/table.date') }}</td>
|
||||
<td><br>------------------------------ <br></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ trans('admin/locations/table.signed_by_asset_auditor') }}</td>
|
||||
<td><br>------------------------------------------------------ <br></td>
|
||||
<td>{{ trans('admin/locations/table.date') }}</td>
|
||||
<td><br>------------------------------ <br></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>{{ trans('admin/locations/table.signed_by_finance_auditor') }}</td>
|
||||
<td><br>------------------------------------------------------ <br></td>
|
||||
<td>{{ trans('admin/locations/table.date') }}</td>
|
||||
<td><br>------------------------------ <br></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ trans('admin/locations/table.signed_by_finance_auditor') }}</td>
|
||||
<td><br>------------------------------------------------------ <br></td>
|
||||
<td>{{ trans('admin/locations/table.date') }}</td>
|
||||
<td><br>------------------------------ <br></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>{{ trans('admin/locations/table.signed_by_location_manager') }}</td>
|
||||
<td><br>------------------------------------------------------ <br></td>
|
||||
<td>{{ trans('admin/locations/table.date') }}</td>
|
||||
<td><br>------------------------------ <br></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ trans('admin/locations/table.signed_by_location_manager') }}</td>
|
||||
<td><br>------------------------------------------------------ <br></td>
|
||||
<td>{{ trans('admin/locations/table.date') }}</td>
|
||||
<td><br>------------------------------ <br></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
@@ -17,8 +17,21 @@
|
||||
@section('content')
|
||||
|
||||
<div class="row">
|
||||
|
||||
@if ($location->deleted_at!='')
|
||||
<div class="col-md-12">
|
||||
<div class="callout callout-warning">
|
||||
<x-icon type="warning" />
|
||||
{{ trans('admin/locations/message.deleted_warning') }}
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
<div class="col-md-9">
|
||||
|
||||
|
||||
|
||||
<div class="nav-tabs-custom">
|
||||
<ul class="nav nav-tabs hidden-print">
|
||||
|
||||
@@ -29,7 +42,7 @@
|
||||
<span class="sr-only">
|
||||
{{ trans('general.users') }}
|
||||
</span>
|
||||
{!! ($location->users->count() > 0) ? '<span class="badge">'.number_format($location->users->count()).'</span>' : '' !!}
|
||||
{!! ($location->users()->count() > 0) ? '<span class="badge">'.number_format($location->users()->count()).'</span>' : '' !!}
|
||||
</a>
|
||||
</li>
|
||||
@endcan
|
||||
@@ -70,7 +83,7 @@
|
||||
<li>
|
||||
<a href="#accessories" data-toggle="tab" data-tooltip="true" title="{{ trans('general.accessories') }}">
|
||||
<i class="far fa-keyboard fa-fw" style="font-size: 17px" aria-hidden="true"></i>
|
||||
{!! ($location->accessories->count() > 0) ? '<span class="badge">'.number_format($location->accessories->count()).'</span>' : '' !!}
|
||||
{!! ($location->accessories()->count() > 0) ? '<span class="badge">'.number_format($location->accessories()->count()).'</span>' : '' !!}
|
||||
<span class="sr-only">
|
||||
{{ trans('general.accessories') }}
|
||||
</span>
|
||||
@@ -80,7 +93,7 @@
|
||||
<li>
|
||||
<a href="#accessories_assigned" data-toggle="tab" data-tooltip="true" title="{{ trans('general.accessories_assigned') }}">
|
||||
<i class="fas fa-keyboard fa-fw" style="font-size: 17px" aria-hidden="true"></i>
|
||||
{!! ($location->assignedAccessories->count() > 0) ? '<span class="badge">'.number_format($location->assignedAccessories->count()).'</span>' : '' !!}
|
||||
{!! ($location->assignedAccessories()->count() > 0) ? '<span class="badge">'.number_format($location->assignedAccessories()->count()).'</span>' : '' !!}
|
||||
<span class="sr-only">
|
||||
{{ trans('general.accessories_assigned') }}
|
||||
</span>
|
||||
@@ -93,7 +106,7 @@
|
||||
<li>
|
||||
<a href="#consumables" data-toggle="tab" data-tooltip="true" title="{{ trans('general.consumables') }}">
|
||||
<i class="fas fa-tint fa-fw" style="font-size: 17px" aria-hidden="true"></i>
|
||||
{!! ($location->consumables->count() > 0) ? '<span class="badge">'.number_format($location->consumables->count()).'</span>' : '' !!}
|
||||
{!! ($location->consumables()->count() > 0) ? '<span class="badge">'.number_format($location->consumables->count()).'</span>' : '' !!}
|
||||
<span class="sr-only">
|
||||
{{ trans('general.consumables') }}
|
||||
</span>
|
||||
@@ -105,7 +118,7 @@
|
||||
<li>
|
||||
<a href="#components" data-toggle="tab" data-tooltip="true" title="{{ trans('general.components') }}">
|
||||
<i class="fas fa-hdd fa-fw" style="font-size: 17px" aria-hidden="true"></i>
|
||||
{!! ($location->components->count() > 0) ? '<span class="badge">'.number_format($location->components->count()).'</span>' : '' !!}
|
||||
{!! ($location->components->count() > 0) ? '<span class="badge">'.number_format($location->components()->count()).'</span>' : '' !!}
|
||||
<span class="sr-only">
|
||||
{{ trans('general.components') }}
|
||||
</span>
|
||||
@@ -113,6 +126,18 @@
|
||||
</li>
|
||||
@endcan
|
||||
|
||||
<li>
|
||||
<a href="#child_locations" data-toggle="tab" data-tooltip="true" title="{{ trans('general.child_locations') }}">
|
||||
<span class="hidden-xs hidden-sm">
|
||||
<i class="fa-solid fa-city fa-fw" style="font-size: 17px" aria-hidden="true"></i>
|
||||
<span class="sr-only">
|
||||
{{ trans('general.child_locations') }}
|
||||
</span>
|
||||
{!! ($location->children()->count() > 0 ) ? '<span class="badge">'.number_format($location->children()->count()).'</span>' : '' !!}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#files" data-toggle="tab" data-tooltip="true" title="{{ trans('general.files') }}">
|
||||
|
||||
@@ -124,11 +149,15 @@
|
||||
<span class="sr-only">
|
||||
{{ trans('general.files') }}
|
||||
</span>
|
||||
{!! ($location->uploads->count() > 0 ) ? '<span class="badge">'.number_format($location->uploads->count()).'</span>' : '' !!}
|
||||
{!! ($location->uploads()->count() > 0 ) ? '<span class="badge">'.number_format($location->uploads()->count()).'</span>' : '' !!}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#history" data-toggle="tab" data-tooltip="true" title="{{ trans('general.history') }}">
|
||||
<i class="fa-solid fa-clock-rotate-left fa-fw" style="font-size: 17px" aria-hidden="true"></i>
|
||||
@@ -337,16 +366,65 @@
|
||||
</table>
|
||||
</div><!-- /.tab-pane -->
|
||||
|
||||
|
||||
<div class="tab-pane" id="child_locations">
|
||||
<h2 class="box-title">
|
||||
{{ trans('general.child_locations') }}
|
||||
</h2>
|
||||
<table
|
||||
role="table"
|
||||
data-columns="{{ \App\Presenters\LocationPresenter::dataTableLayout() }}"
|
||||
data-cookie-id-table="childrenListingTable"
|
||||
data-id-table="childrenListingTable"
|
||||
data-side-pagination="server"
|
||||
data-sort-order="asc"
|
||||
id="childrenListingTable"
|
||||
data-buttons="childrenListingTable"
|
||||
class="table table-striped snipe-table"
|
||||
data-url="{{route('api.locations.index', ['parent_id' => $location->id]) }}"
|
||||
data-export-options='{
|
||||
"fileName": "export-children-locations-{{ str_slug($location->name) }}-{{ date('Y-m-d') }}",
|
||||
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
|
||||
}'>
|
||||
</table>
|
||||
</div><!-- /.tab-pane -->
|
||||
|
||||
<div class="tab-pane fade" id="files">
|
||||
<h2 class="box-title">
|
||||
{{ trans('general.child_locations') }}
|
||||
</h2>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<x-filestable object_type="locations" :object="$location" />
|
||||
</div> <!-- /.col-md-12 -->
|
||||
</div> <!-- /.row -->
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="tab-pane" id="accessories_assigned">
|
||||
<h2 class="box-title" style="float:left">
|
||||
{{ trans('general.accessories_assigned') }}
|
||||
</h2>
|
||||
|
||||
<table
|
||||
role="table"
|
||||
data-columns="{{ \App\Presenters\LocationPresenter::assignedAccessoriesDataTableLayout() }}"
|
||||
data-cookie-id-table="accessoriesAssignedListingTable"
|
||||
data-id-table="accessoriesAssignedListingTable"
|
||||
data-side-pagination="server"
|
||||
data-sort-order="asc"
|
||||
id="accessoriesAssignedListingTable"
|
||||
data-buttons="accessoryButtons"
|
||||
class="table table-striped snipe-table"
|
||||
data-url="{{ route('api.locations.assigned_accessories', ['location' => $location]) }}"
|
||||
data-export-options='{
|
||||
"fileName": "export-locations-{{ str_slug($location->name) }}-accessories-{{ date('Y-m-d') }}",
|
||||
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
|
||||
}'>
|
||||
</table>
|
||||
</div><!-- /.tab-pane -->
|
||||
|
||||
<div class="tab-pane" id="history">
|
||||
<h2 class="box-title">{{ trans('general.history') }}</h2>
|
||||
<!-- checked out assets table -->
|
||||
@@ -411,16 +489,16 @@
|
||||
<li>{{ $location->city }} {{ $location->state }} {{ $location->zip }}</li>
|
||||
@endif
|
||||
@if ($location->manager)
|
||||
<li>{{ trans('admin/users/table.manager') }}: {!! $location->manager->present()->nameUrl() !!}</li>
|
||||
<li><strong>{{ trans('admin/users/table.manager') }}</strong>: {!! $location->manager->present()->nameUrl() !!}</li>
|
||||
@endif
|
||||
@if ($location->company)
|
||||
<li>{{ trans('admin/companies/table.name') }}: {!! $location->company->present()->nameUrl() !!}</li>
|
||||
<li><strong>{{ trans('admin/companies/table.name') }}</strong>: {!! $location->company->present()->nameUrl() !!}</li>
|
||||
@endif
|
||||
@if ($location->parent)
|
||||
<li>{{ trans('admin/locations/table.parent') }}: {!! $location->parent->present()->nameUrl() !!}</li>
|
||||
<li><strong>{{ trans('admin/locations/table.parent') }}</strong>: {!! $location->parent->present()->nameUrl() !!}</li>
|
||||
@endif
|
||||
@if ($location->ldap_ou)
|
||||
<li>{{ trans('admin/locations/table.ldap_ou') }}: {{ $location->ldap_ou }}</li>
|
||||
<li><strong>{{ trans('admin/locations/table.ldap_ou') }}</strong>: {{ $location->ldap_ou }}</li>
|
||||
@endif
|
||||
|
||||
|
||||
@@ -442,18 +520,28 @@
|
||||
</div>
|
||||
|
||||
@can('update', $location)
|
||||
<div class="col-md-12">
|
||||
<a href="{{ route('locations.edit', ['location' => $location->id]) }}" style="width: 100%;" class="btn btn-sm btn-warning btn-social">
|
||||
<x-icon type="edit" />
|
||||
{{ trans('admin/locations/table.update') }}
|
||||
</a>
|
||||
</div>
|
||||
@if ($location->deleted_at=='')
|
||||
<div class="col-md-12">
|
||||
<a href="{{ route('locations.edit', ['location' => $location->id]) }}" style="width: 100%;" class="btn btn-sm btn-warning btn-social">
|
||||
<x-icon type="edit" />
|
||||
{{ trans('admin/locations/table.update') }}
|
||||
</a>
|
||||
</div>
|
||||
@else
|
||||
<div class="col-md-12">
|
||||
<a style="width: 100%;" class="btn btn-sm btn-warning btn-social disabled">
|
||||
<x-icon type="edit" />
|
||||
{{ trans('admin/locations/table.update') }}
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
@endcan
|
||||
|
||||
@if ($location->deleted_at=='')
|
||||
<div class="col-md-12" style="padding-top: 5px;">
|
||||
<a href="{{ route('locations.print_assigned', ['locationId' => $location->id]) }}" style="width: 100%;" class="btn btn-sm btn-primary btn-social hidden-print">
|
||||
<x-icon type="print" />
|
||||
{{ trans('admin/locations/table.print_assigned') }}
|
||||
{{ trans('admin/locations/table.print_inventory') }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-12" style="padding-top: 5px;">
|
||||
@@ -462,6 +550,7 @@
|
||||
{{ trans('admin/locations/table.print_all_assigned') }}
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@can('delete', $location)
|
||||
<div class="col-md-12 hidden-print" style="padding-top: 10px;">
|
||||
@@ -474,16 +563,18 @@
|
||||
{{ trans('general.delete') }}
|
||||
</button>
|
||||
@else
|
||||
<a href="#" class="btn btn-block btn-sm btn-danger btn-social hidden-print disabled" data-tooltip="true" data-placement="top" data-title="{{ trans('general.cannot_be_deleted') }}">
|
||||
<span data-placement="top" data-tooltip="true" data-title="{{ trans('admin/locations/message.assoc_users') }}">
|
||||
<a href="#" class="btn btn-block btn-sm btn-danger btn-social hidden-print disabled" data-tooltip="true">
|
||||
<x-icon type="delete" />
|
||||
{{ trans('general.delete') }}
|
||||
</a>
|
||||
</span>
|
||||
@endif
|
||||
|
||||
@else
|
||||
<form method="POST" action="{{ route('locations.restore', ['location' => $location->id]) }}">
|
||||
@csrf
|
||||
<button class="btn btn-sm btn-block btn-warning btn-social delete-asset">
|
||||
<button class="btn btn-sm btn-block btn-warning btn-social">
|
||||
<x-icon type="restore" />
|
||||
{{ trans('general.restore') }}
|
||||
</button>
|
||||
|
||||
@@ -1289,7 +1289,7 @@
|
||||
|
||||
btnShowDeleted: {
|
||||
text: '{{ (request()->input('status') == "deleted") ?trans('admin/users/table.show_current') : trans('admin/users/table.show_deleted') }}',
|
||||
icon: 'fa-solid fa-user-slash {{ (request()->input('status') == "deleted") ? ' text-danger' : ' fa-user-slash' }}',
|
||||
icon: 'fa-solid fa-trash {{ (request()->input('status') == "deleted") ? ' text-danger' : ' fa-user-trash' }}',
|
||||
event () {
|
||||
window.location.href = '{{ (request()->input('status') == "deleted") ? route('users.index') : route('users.index', ['status' => 'deleted']) }}';
|
||||
},
|
||||
@@ -1398,6 +1398,18 @@
|
||||
@endif
|
||||
}
|
||||
},
|
||||
|
||||
btnShowDeleted: {
|
||||
text: '{{ (request()->input('status') == "deleted") ? trans('admin/users/table.show_current') : trans('admin/users/table.show_deleted') }}',
|
||||
icon: 'fa-solid fa-trash {{ (request()->input('status') == "deleted") ? ' text-danger' : ' fa-user-trash' }}',
|
||||
event () {
|
||||
window.location.href = '{{ (request()->input('status') == "deleted") ? route('locations.index') : route('locations.index', ['status' => 'deleted']) }}';
|
||||
},
|
||||
attributes: {
|
||||
title: '{{ (request()->input('status') == "deleted") ? trans('admin/users/table.show_current') : trans('admin/users/table.show_deleted') }}',
|
||||
|
||||
}
|
||||
},
|
||||
});
|
||||
@endcan
|
||||
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
namespace Tests\Feature\Locations\Api;
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Component;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\Location;
|
||||
use App\Models\User;
|
||||
use Tests\Concerns\TestsPermissionsRequirement;
|
||||
@@ -24,11 +27,12 @@ class DeleteLocationsTest extends TestCase implements TestsPermissionsRequiremen
|
||||
public function testErrorReturnedViaApiIfLocationDoesNotExist()
|
||||
{
|
||||
$this->actingAsForApi(User::factory()->superuser()->create())
|
||||
->deleteJson(route('api.users.destroy', 'invalid-id'))
|
||||
->deleteJson(route('api.locations.destroy', 'invalid-id'))
|
||||
->assertOk()
|
||||
->assertStatus(200)
|
||||
->assertStatusMessageIs('error')
|
||||
->json();
|
||||
|
||||
}
|
||||
|
||||
public function testErrorReturnedViaApiIfLocationIsAlreadyDeleted()
|
||||
@@ -55,9 +59,10 @@ class DeleteLocationsTest extends TestCase implements TestsPermissionsRequiremen
|
||||
->assertStatus(200)
|
||||
->assertStatusMessageIs('error')
|
||||
->json();
|
||||
$this->assertNotSoftDeleted($location);
|
||||
}
|
||||
|
||||
public function testDisallowUserDeletionViaApiIfStillHasChildLocations()
|
||||
public function testDisallowLocationDeletionViaApiIfStillHasChildLocations()
|
||||
{
|
||||
$parent = Location::factory()->create();
|
||||
Location::factory()->count(5)->create(['parent_id' => $parent->id]);
|
||||
@@ -69,9 +74,10 @@ class DeleteLocationsTest extends TestCase implements TestsPermissionsRequiremen
|
||||
->assertStatus(200)
|
||||
->assertStatusMessageIs('error')
|
||||
->json();
|
||||
$this->assertNotSoftDeleted($parent);
|
||||
}
|
||||
|
||||
public function testDisallowUserDeletionViaApiIfStillHasAssetsAssigned()
|
||||
public function testDisallowLocationDeletionViaApiIfStillHasAssetsAssigned()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
Asset::factory()->count(5)->assignedToLocation($location)->create();
|
||||
@@ -84,9 +90,10 @@ class DeleteLocationsTest extends TestCase implements TestsPermissionsRequiremen
|
||||
->assertStatus(200)
|
||||
->assertStatusMessageIs('error')
|
||||
->json();
|
||||
$this->assertNotSoftDeleted($location);
|
||||
}
|
||||
|
||||
public function testDisallowUserDeletionViaApiIfStillHasAssetsAsLocation()
|
||||
public function testDisallowLocationDeletionViaApiIfStillHasAssetsAsLocation()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
Asset::factory()->count(5)->create(['location_id' => $location->id]);
|
||||
@@ -99,6 +106,73 @@ class DeleteLocationsTest extends TestCase implements TestsPermissionsRequiremen
|
||||
->assertStatus(200)
|
||||
->assertStatusMessageIs('error')
|
||||
->json();
|
||||
$this->assertNotSoftDeleted($location);
|
||||
}
|
||||
|
||||
public function testDisallowLocationDeletionViaApiIfStillHasConsumablesAsLocation()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
Consumable::factory()->count(5)->create(['location_id' => $location->id]);
|
||||
|
||||
$this->assertFalse($location->isDeletable());
|
||||
|
||||
$this->actingAsForApi(User::factory()->superuser()->create())
|
||||
->deleteJson(route('api.locations.destroy', $location->id))
|
||||
->assertOk()
|
||||
->assertStatus(200)
|
||||
->assertStatusMessageIs('error')
|
||||
->json();
|
||||
$this->assertNotSoftDeleted($location);
|
||||
}
|
||||
|
||||
public function testDisallowLocationDeletionViaApiIfStillHasComponentsAsLocation()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
Component::factory()->count(5)->create(['location_id' => $location->id]);
|
||||
|
||||
$this->assertFalse($location->isDeletable());
|
||||
|
||||
$this->actingAsForApi(User::factory()->superuser()->create())
|
||||
->deleteJson(route('api.locations.destroy', $location->id))
|
||||
->assertOk()
|
||||
->assertStatus(200)
|
||||
->assertStatusMessageIs('error')
|
||||
->json();
|
||||
|
||||
$this->assertNotSoftDeleted($location);
|
||||
}
|
||||
|
||||
public function testDisallowLocationDeletionViaApiIfStillHasAccessoriesAssigned()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
Accessory::factory()->count(5)->checkedOutToLocation($location)->create();
|
||||
|
||||
$this->assertFalse($location->isDeletable());
|
||||
|
||||
$this->actingAsForApi(User::factory()->superuser()->create())
|
||||
->deleteJson(route('api.locations.destroy', $location->id))
|
||||
->assertOk()
|
||||
->assertStatus(200)
|
||||
->assertStatusMessageIs('error')
|
||||
->json();
|
||||
$this->assertNotSoftDeleted($location);
|
||||
}
|
||||
|
||||
public function testDisallowLocationDeletionViaApiIfStillHasAccessoriesAsLocation()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
Accessory::factory()->count(5)->create(['location_id' => $location->id]);
|
||||
|
||||
$this->assertFalse($location->isDeletable());
|
||||
|
||||
$this->actingAsForApi(User::factory()->superuser()->create())
|
||||
->deleteJson(route('api.locations.destroy', $location->id))
|
||||
->assertOk()
|
||||
->assertStatus(200)
|
||||
->assertStatusMessageIs('error')
|
||||
->json();
|
||||
|
||||
$this->assertNotSoftDeleted($location);
|
||||
}
|
||||
|
||||
public function testCanDeleteLocation()
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Users\Ui;
|
||||
|
||||
use App\Models\Consumable;
|
||||
use Tests\TestCase;
|
||||
use App\Models\Location;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\User;
|
||||
use App\Models\Asset;
|
||||
|
||||
class DeleteLocationsTest extends TestCase
|
||||
{
|
||||
|
||||
public function testRequiresPermission()
|
||||
{
|
||||
$this->actingAs(User::factory()->create())
|
||||
->delete(route('locations.destroy', Location::factory()->create()))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
public function testCanDeleteLocation()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
|
||||
$this->actingAs(User::factory()->deleteLocations()->create())
|
||||
->delete(route('locations.destroy', $location))
|
||||
->assertRedirectToRoute('locations.index')
|
||||
->assertSessionHas('success')
|
||||
->assertStatus(302)
|
||||
->assertRedirect(route('locations.index'));
|
||||
|
||||
$this->assertSoftDeleted($location);
|
||||
}
|
||||
|
||||
|
||||
public function testCannotDeleteLocationWithAssetsAsLocation()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
Asset::factory()->count(5)->create(['location_id' => $location->id]);
|
||||
|
||||
$this->actingAs(User::factory()->deleteLocations()->create())
|
||||
->delete(route('locations.destroy', $location))
|
||||
->assertStatus(302)
|
||||
->assertRedirectToRoute('locations.index')
|
||||
->assertSessionHas('error');
|
||||
|
||||
$this->assertNotSoftDeleted($location);
|
||||
}
|
||||
|
||||
public function testCannotDeleteLocationWithAssetsAssigned()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
Asset::factory()->count(5)->assignedToLocation($location)->create();
|
||||
|
||||
$this->actingAs(User::factory()->deleteLocations()->create())
|
||||
->delete(route('locations.destroy', $location))
|
||||
->assertStatus(302)
|
||||
->assertRedirectToRoute('locations.index')
|
||||
->assertSessionHas('error');
|
||||
|
||||
$this->assertNotSoftDeleted($location);
|
||||
}
|
||||
|
||||
public function testCannotDeleteLocationWithChildren()
|
||||
{
|
||||
$parent = Location::factory()->create();
|
||||
Location::factory()->count(5)->create(['parent_id' => $parent->id]);
|
||||
|
||||
$this->actingAs(User::factory()->deleteLocations()->create())
|
||||
->delete(route('locations.destroy', $parent))
|
||||
->assertStatus(302)
|
||||
->assertRedirectToRoute('locations.index')
|
||||
->assertSessionHas('error');
|
||||
|
||||
$this->assertNotSoftDeleted($parent);
|
||||
}
|
||||
|
||||
public function testCannotDeleteLocationWithConsumableAsLocation()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
Consumable::factory()->count(5)->create(['location_id' => $location->id]);
|
||||
|
||||
$this->actingAs(User::factory()->deleteLocations()->create())
|
||||
->delete(route('locations.destroy', $location))
|
||||
->assertStatus(302)
|
||||
->assertRedirectToRoute('locations.index')
|
||||
->assertSessionHas('error');
|
||||
|
||||
$this->assertNotSoftDeleted($location);
|
||||
}
|
||||
|
||||
public function testCannotDeleteLocationWithAccessoriesAssigned()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
Accessory::factory()->count(5)->checkedOutToLocation($location)->create();
|
||||
|
||||
$this->actingAs(User::factory()->deleteLocations()->create())
|
||||
->delete(route('locations.destroy', $location))
|
||||
->assertStatus(302)
|
||||
->assertRedirectToRoute('locations.index')
|
||||
->assertSessionHas('error');
|
||||
|
||||
$this->assertNotSoftDeleted($location);
|
||||
}
|
||||
|
||||
public function testCannotDeleteLocationWithAccessoriesAsLocation()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
Accessory::factory()->count(5)->create(['location_id' => $location->id]);
|
||||
|
||||
$this->actingAs(User::factory()->deleteLocations()->create())
|
||||
->delete(route('locations.destroy', $location))
|
||||
->assertStatus(302)
|
||||
->assertRedirectToRoute('locations.index')
|
||||
->assertSessionHas('error');
|
||||
|
||||
$this->assertNotSoftDeleted($location);
|
||||
}
|
||||
|
||||
public function testCannotDeleteLocationWithPeople()
|
||||
{
|
||||
$location = Location::factory()->create();
|
||||
User::factory()->count(5)->create(['location_id' => $location->id]);
|
||||
|
||||
$this->actingAs(User::factory()->deleteLocations()->create())
|
||||
->delete(route('locations.destroy', $location))
|
||||
->assertStatus(302)
|
||||
->assertRedirectToRoute('locations.index')
|
||||
->assertSessionHas('error');
|
||||
|
||||
$this->assertNotSoftDeleted($location);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user