Clean up Transformers and extract an isDeletable() method to models where it makes sense.

This commit is contained in:
Daniel Meltzer 2020-05-23 13:36:02 -04:00
parent 136df9418f
commit f0546bf689
No known key found for this signature in database
GPG key ID: 91C5C7B09A5B1CA0
32 changed files with 173 additions and 177 deletions

View file

@ -120,16 +120,12 @@ class CategoriesController extends Controller
public function destroy($id)
{
$this->authorize('delete', Category::class);
$category = Category::withCount('models as models_count', 'accessories as accessories_count','consumables as consumables_count','components as components_count')->findOrFail($id);
$category = Category::findOrFail($id);
if ($category->models_count > 0) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.assoc_items', ['asset_type'=>'model'])));
} elseif ($category->accessories_count > 0) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.assoc_items', ['asset_type'=>'accessory'])));
} elseif ($category->consumables_count > 0) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.assoc_items', ['asset_type'=>'consumable'])));
} elseif ($category->components_count > 0) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.assoc_items', ['asset_type'=>'component'])));
if (!$category->isDeletable()) {
return response()->json(
Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.assoc_items', ['asset_type'=>$category->category_type]))
);
}
$category->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/categories/message.delete.success')));

View file

@ -137,24 +137,13 @@ class CompaniesController extends Controller
$company = Company::findOrFail($id);
$this->authorize('delete', $company);
try {
if ( !$company->isDeletable() ) {
return response()
->json(Helper::formatStandardApiResponse('error', null, trans('admin/companies/message.assoc_users')));
}
$company->delete();
return response()
->json(Helper::formatStandardApiResponse('success', null, trans('admin/companies/message.delete.success')));
} catch (\Illuminate\Database\QueryException $exception) {
/*
* NOTE: This happens when there's a foreign key constraint violation
* For example when rows in other tables are referencing this company
*/
if ($exception->getCode() == 23000) {
return response()
->json(Helper::formatStandardApiResponse('error', null, trans('admin/companies/message.assoc_users')));
} else {
throw $exception;
}
}
}
/**

View file

@ -179,6 +179,10 @@ class LocationsController extends Controller
{
$this->authorize('delete', Location::class);
$location = Location::findOrFail($id);
if(!$location->isDeletable()) {
return response()
->json(Helper::formatStandardApiResponse('error', null, trans('admin/companies/message.assoc_users')));
}
$this->authorize('delete', $location);
$location->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/locations/message.delete.success')));

View file

@ -125,15 +125,15 @@ class ManufacturersController extends Controller
{
$this->authorize('delete', Manufacturer::class);
$manufacturer = Manufacturer::withCount('assets as assets_count', 'licenses as licenses_count', 'consumables as consumables_count', 'accessories as accessories_count', 'models as models_count' )->findOrFail($id);
$manufacturer = Manufacturer::findOrFail($id);
$this->authorize('delete', $manufacturer);
if (($manufacturer->assets_count == 0) && ($manufacturer->licenses_count==0) && ($manufacturer->consumables_count==0) && ($manufacturer->accessories_count==0) && ($manufacturer->models_count==0) && ($manufacturer->deleted_at=='')) {
if ($manufacturer->isDeletable()) {
$manufacturer->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/manufacturers/message.delete.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/manufacturers/message.delete.error')));
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/manufacturers/message.assoc_users')));

View file

@ -159,18 +159,12 @@ class CategoriesController extends Controller
{
$this->authorize('delete', Category::class);
// Check if the category exists
if (is_null($category = Category::withCount('models as models_count', 'accessories as accessories_count','consumables as consumables_count','components as components_count')->findOrFail($categoryId))) {
if (is_null($category = Category::findOrFail($categoryId))) {
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.not_found'));
}
if ($category->models_count > 0) {
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'model']));
} elseif ($category->accessories_count > 0) {
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'accessory']));
} elseif ($category->consumables_count > 0) {
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'consumable']));
} elseif ($category->components_count > 0) {
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'component']));
if (!$category->isDeletable()) {
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=> $category->category_type ]));
}
Storage::disk('public')->delete('categories'.'/'.$category->image);

View file

@ -142,8 +142,10 @@ final class CompaniesController extends Controller
}
$this->authorize('delete', $company);
try {
if(!$company->isDeletable()) {
return redirect()->route('companies.index')
->with('error', trans('admin/companies/message.assoc_users'));
}
if ($company->image) {
try {
@ -156,18 +158,6 @@ final class CompaniesController extends Controller
$company->delete();
return redirect()->route('companies.index')
->with('success', trans('admin/companies/message.delete.success'));
} catch (\Illuminate\Database\QueryException $exception) {
/*
* NOTE: This happens when there's a foreign key constraint violation
* For example when rows in other tables are referencing this company
*/
if ($exception->getCode() == 23000) {
return redirect()->route('companies.index')
->with('error', trans('admin/companies/message.assoc_users'));
}
throw $exception;
}
}
public function show($id) {

View file

@ -171,18 +171,14 @@ class LocationsController extends Controller
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.not_found'));
}
if (($location->users()) && ($location->users()->count() > 0)) {
if ($location->users()->count() > 0) {
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_users'));
} elseif (($location->children) && ($location->children->count() > 0)) {
} elseif ($location->children()->count() > 0) {
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_child_loc'));
} elseif (($location->assets()) && ($location->assets()->count() > 0)) {
} elseif ($location->assets()->count() > 0) {
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_assets'));
} elseif (($location->assignedassets()) && ($location->assignedassets()->count() > 0)) {
} elseif ($location->assignedassets()->count() > 0) {
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_assets'));
}
if ($location->image) {

View file

@ -162,7 +162,7 @@ class ManufacturersController extends Controller
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.not_found'));
}
if ($manufacturer->models_count > 0) {
if (!$manufacturer->isDeletable()) {
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.assoc_users'));
}
@ -174,7 +174,6 @@ class ManufacturersController extends Controller
}
}
// Delete the manufacturer
$manufacturer->delete();
// Redirect to the manufacturers management page

View file

@ -45,10 +45,10 @@ class AccessoriesTransformer
];
$permissions_array['available_actions'] = [
'checkout' => Gate::allows('checkout', Accessory::class) ? true : false,
'checkout' => Gate::allows('checkout', Accessory::class),
'checkin' => false,
'update' => Gate::allows('update', Accessory::class) ? true : false,
'delete' => Gate::allows('delete', Accessory::class) ? true : false,
'update' => Gate::allows('update', Accessory::class) ,
'delete' => Gate::allows('delete', Accessory::class),
];
$permissions_array['user_can_checkout'] = false;

View file

@ -58,8 +58,8 @@ class AssetMaintenancesTransformer
];
$permissions_array['available_actions'] = [
'update' => (bool) Gate::allows('update', Asset::class),
'delete' => (bool) Gate::allows('delete', Asset::class),
'update' => Gate::allows('update', Asset::class),
'delete' => Gate::allows('delete', Asset::class),
];
$array += $permissions_array;

View file

@ -54,10 +54,10 @@ class AssetModelsTransformer
];
$permissions_array['available_actions'] = [
'update' => (Gate::allows('update', AssetModel::class) && ($assetmodel->deleted_at=='')) ? true : false,
'delete' => (Gate::allows('delete', AssetModel::class) && ($assetmodel->assets_count==0) && ($assetmodel->deleted_at=='')) ? true : false,
'clone' => (Gate::allows('create', AssetModel::class) && ($assetmodel->deleted_at=='')) ,
'restore' => (Gate::allows('create', AssetModel::class) && ($assetmodel->deleted_at!='')) ? true : false,
'update' => (Gate::allows('update', AssetModel::class) && ($assetmodel->deleted_at=='')),
'delete' => (Gate::allows('delete', AssetModel::class) && ($assetmodel->assets_count==0)),
'clone' => (Gate::allows('create', AssetModel::class) && ($assetmodel->deleted_at=='')),
'restore' => (Gate::allows('create', AssetModel::class) && ($assetmodel->deleted_at!='')),
];
$array += $permissions_array;

View file

@ -114,20 +114,20 @@ class AssetsTransformer
}
$permissions_array['available_actions'] = [
'checkout' => (bool) Gate::allows('checkout', Asset::class),
'checkin' => (bool) Gate::allows('checkin', Asset::class),
'clone' => Gate::allows('create', Asset::class) ? true : false,
'checkout' => Gate::allows('checkout', Asset::class),
'checkin' => Gate::allows('checkin', Asset::class),
'clone' => Gate::allows('create', Asset::class),
'restore' => false,
'update' => (bool) Gate::allows('update', Asset::class),
'delete' => ($asset->assigned_to=='' && Gate::allows('delete', Asset::class) ? true : false),
'delete' => ($asset->assigned_to=='' && Gate::allows('delete', Asset::class)),
];
if ($asset->deleted_at!='') {
$permissions_array['available_actions'] = [
'checkout' => true,
'checkin' => false,
'clone' => Gate::allows('create', Asset::class) ? true : false,
'restore' => Gate::allows('create', Asset::class) ? true : false,
'clone' => Gate::allows('create', Asset::class),
'restore' => Gate::allows('create', Asset::class),
'update' => false,
'delete' => false,
];

View file

@ -27,10 +27,11 @@ class CategoriesTransformer
'id' => (int) $category->id,
'name' => e($category->name),
'image' => ($category->image) ? Storage::disk('public')->url('categories/'.e($category->image)) : null,
'category_type' => e($category->category_type),
'eula' => ($category->getEula()) ? true : false,
'checkin_email' => ($category->checkin_email =='1') ? true : false,
'require_acceptance' => ($category->require_acceptance =='1') ? true : false,
'category_type' => ucwords(e($category->category_type)),
'eula' => ($category->getEula()),
'checkin_email' => ($category->checkin_email =='1'),
'require_acceptance' => ($category->require_acceptance == '1'),
'item_count' => (int) $category->itemCount(),
'assets_count' => (int) $category->assets_count,
'accessories_count' => (int) $category->accessories_count,
'consumables_count' => (int) $category->consumables_count,
@ -41,8 +42,8 @@ class CategoriesTransformer
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Category::class) ? true : false,
'delete' => (Gate::allows('delete', Category::class) && ($category->assets_count == 0) && ($category->accessories_count == 0) && ($category->consumables_count == 0) && ($category->components_count == 0) && ($category->licenses_count == 0)) ? true : false,
'update' => Gate::allows('update', Category::class),
'delete' => $category->isDeletable(),
];
$array += $permissions_array;

View file

@ -38,8 +38,8 @@ class CompaniesTransformer
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Company::class) ? true : false,
'delete' => (Gate::allows('delete', Company::class) && ($company->assets_count == 0) && ($company->accessories_count == 0) && ($company->consumables_count == 0) && ($company->components_count == 0) && ($company->users_count == 0)) ? true : false,
'update' => Gate::allows('update', Company::class),
'delete' => $company->isDeletable()
];
$array += $permissions_array;

View file

@ -28,10 +28,10 @@ class ComponentsAssetsTransformer
];
$permissions_array['available_actions'] = [
'checkout' => Gate::allows('checkout', Asset::class) ? true : false,
'checkin' => Gate::allows('checkin', Asset::class) ? true : false,
'update' => Gate::allows('update', Asset::class) ? true : false,
'delete' => Gate::allows('delete', Asset::class) ? true : false,
'checkout' => Gate::allows('checkout', Asset::class),
'checkin' => Gate::allows('checkin', Asset::class),
'update' => Gate::allows('update', Asset::class),
'delete' => Gate::allows('delete', Asset::class),
];

View file

@ -49,10 +49,10 @@ class ComponentsTransformer
];
$permissions_array['available_actions'] = [
'checkout' => (bool) Gate::allows('checkout', Component::class),
'checkin' => (bool) Gate::allows('checkin', Component::class),
'update' => (bool) Gate::allows('update', Component::class),
'delete' => (bool) Gate::allows('delete', Component::class),
'checkout' => Gate::allows('checkout', Component::class),
'checkin' => Gate::allows('checkin', Component::class),
'update' => Gate::allows('update', Component::class),
'delete' => Gate::allows('delete', Component::class),
];
$array += $permissions_array;

View file

@ -48,10 +48,10 @@ class ConsumablesTransformer
}
$permissions_array['available_actions'] = [
'checkout' => Gate::allows('checkout', Consumable::class) ? true : false,
'checkin' => Gate::allows('checkin', Consumable::class) ? true : false,
'update' => Gate::allows('update', Consumable::class) ? true : false,
'delete' => Gate::allows('delete', Consumable::class) ? true : false,
'checkout' => Gate::allows('checkout', Consumable::class),
'checkin' => Gate::allows('checkin', Consumable::class),
'update' => Gate::allows('update', Consumable::class),
'delete' => Gate::allows('delete', Consumable::class),
];
$array += $permissions_array;
return $array;

View file

@ -47,8 +47,8 @@ class DepartmentsTransformer
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Department::class) ? true : false,
'delete' => (Gate::allows('delete', Department::class) && ($department->users_count==0) && ($department->deleted_at=='')) ? true : false,
'update' => Gate::allows('update', Department::class),
'delete' => (Gate::allows('delete', Department::class) && ($department->users_count==0),
];
$array += $permissions_array;

View file

@ -29,8 +29,8 @@ class DepreciationsTransformer
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Depreciation::class) ? true : false,
'delete' => Gate::allows('delete', Depreciation::class) ? true : false,
'update' => Gate::allows('update', Depreciation::class),
'delete' => Gate::allows('delete', Depreciation::class),
];
$array += $permissions_array;

View file

@ -46,15 +46,15 @@ class LicenseSeatsTransformer
'name'=> e($seat->location()->name)
] : null,
'reassignable' => (bool) $seat->license->reassignable,
'user_can_checkout' => (($seat->assigned_to=='') && ($seat->asset_id=='')) ? true : false,
'user_can_checkout' => (($seat->assigned_to=='') && ($seat->asset_id=='')),
];
$permissions_array['available_actions'] = [
'checkout' => Gate::allows('checkout', License::class) ? true : false,
'checkin' => Gate::allows('checkin', License::class) ? true : false,
'clone' => Gate::allows('create', License::class) ? true : false,
'update' => Gate::allows('update', License::class) ? true : false,
'delete' => Gate::allows('delete', License::class) ? true : false,
'checkout' => Gate::allows('checkout', License::class),
'checkin' => Gate::allows('checkin', License::class),
'clone' => Gate::allows('create', License::class),
'update' => Gate::allows('update', License::class),
'delete' => Gate::allows('delete', License::class),
];
$array += $permissions_array;

View file

@ -45,11 +45,11 @@ class LicensesTransformer
];
$permissions_array['available_actions'] = [
'checkout' => Gate::allows('checkout', License::class) ? true : false,
'checkin' => Gate::allows('checkin', License::class) ? true : false,
'clone' => Gate::allows('create', License::class) ? true : false,
'update' => Gate::allows('update', License::class) ? true : false,
'delete' => Gate::allows('delete', License::class) ? true : false,
'checkout' => Gate::allows('checkout', License::class),
'checkin' => Gate::allows('checkin', License::class),
'clone' => Gate::allows('create', License::class),
'update' => Gate::allows('update', License::class),
'delete' => Gate::allows('delete', License::class),
];
$array += $permissions_array;

View file

@ -61,7 +61,7 @@ class LocationsTransformer
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Location::class) ? true : false,
'delete' => (Gate::allows('delete', Location::class) && ($location->assigned_assets_count==0) && ($location->assets_count==0) && ($location->users_count==0) && ($location->deleted_at=='')) ? true : false,
'delete' => $location->isDeletable(),
];
$array += $permissions_array;

View file

@ -41,9 +41,9 @@ class ManufacturersTransformer
];
$permissions_array['available_actions'] = [
'update' => (($manufacturer->deleted_at=='') && (Gate::allows('update', Manufacturer::class))) ? true : false,
'restore' => (($manufacturer->deleted_at!='') && (Gate::allows('create', Manufacturer::class))) ? true : false,
'delete' => (Gate::allows('delete', Manufacturer::class) && ($manufacturer->assets_count == 0) && ($manufacturer->licenses_count==0) && ($manufacturer->consumables_count==0) && ($manufacturer->accessories_count==0) && ($manufacturer->deleted_at=='')) ? true : false,
'update' => (($manufacturer->deleted_at=='') && (Gate::allows('update', Manufacturer::class))),
'restore' => (($manufacturer->deleted_at!='') && (Gate::allows('create', Manufacturer::class))),
'delete' => $manufacturer->isDeletable(),
];
$array += $permissions_array;

View file

@ -34,7 +34,7 @@ class PredefinedKitsTransformer
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', PredefinedKit::class),
'delete' => Gate::allows('delete', PredefinedKit::class),
'checkout' => Gate::allows('checkout', PredefinedKit::class) ? true : false,
'checkout' => Gate::allows('checkout', PredefinedKit::class),
// 'clone' => Gate::allows('create', PredefinedKit::class),
// 'restore' => Gate::allows('create', PredefinedKit::class),
];

View file

@ -48,8 +48,8 @@ class SuppliersTransformer
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Supplier::class) ? true : false,
'delete' => (Gate::allows('delete', Supplier::class) && ($supplier->assets_count == 0) && ($supplier->licenses_count == 0) && ($supplier->accessories_count == 0)) ? true : false,
'update' => Gate::allows('update', Supplier::class),
'delete' => (Gate::allows('delete', Supplier::class) && ($supplier->assets_count == 0) && ($supplier->licenses_count == 0) && ($supplier->accessories_count == 0)),
];
$array += $permissions_array;

View file

@ -66,10 +66,10 @@ class UsersTransformer
];
$permissions_array['available_actions'] = [
'update' => (Gate::allows('update', User::class) && ($user->deleted_at=='')) ? true : false,
'delete' => (Gate::allows('delete', User::class) && ($user->deleted_at=='') && ($user->assets_count == 0) && ($user->licenses_count == 0) && ($user->accessories_count == 0) && ($user->consumables_count == 0)) ? true : false,
'update' => (Gate::allows('update', User::class) && ($user->deleted_at=='')),
'delete' => (Gate::allows('delete', User::class) && ($user->assets_count == 0) && ($user->licenses_count == 0) && ($user->accessories_count == 0) && ($user->consumables_count == 0)),
'clone' => (Gate::allows('create', User::class) && ($user->deleted_at=='')) ,
'restore' => (Gate::allows('create', User::class) && ($user->deleted_at!='')) ? true : false,
'restore' => (Gate::allows('create', User::class) && ($user->deleted_at!='')),
];
$array += $permissions_array;

View file

@ -5,6 +5,7 @@ use App\Http\Traits\UniqueUndeletedTrait;
use App\Models\Traits\Searchable;
use App\Presenters\Presentable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Gate;
use Watson\Validating\ValidatingTrait;
/**
@ -85,6 +86,19 @@ class Category extends SnipeModel
protected $searchableRelations = [];
/**
* Checks if category can be deleted
*
* @author [Dan Meltzer] [<dmeltzer.devel@gmail.com>]
* @since [v5.0]
* @return bool
*/
public function isDeletable()
{
return (Gate::allows('delete', $this)
&& ($this->itemCount() == 0));
}
/**
* Establishes the category -> accessories relationship
*

View file

@ -5,6 +5,7 @@ use App\Models\Traits\Searchable;
use App\Presenters\Presentable;
use Auth;
use DB;
use Illuminate\Support\Facades\Gate;
use Watson\Validating\ValidatingTrait;
/**
@ -84,7 +85,6 @@ final class Company extends SnipeModel
} else {
return $query->join('users as users_comp', 'users_comp.id', 'user_id')->where('users_comp.company_id', '=', $company_id);
}
}
public static function getIdFromInput($unescaped_input)
@ -143,6 +143,22 @@ final class Company extends SnipeModel
Auth::user()->company_id == null);
}
/**
* Checks if company can be deleted
*
* @author [Dan Meltzer] [<dmeltzer.devel@gmail.com>]
* @since [v5.0]
* @return bool
*/
public function isDeletable() {
return Gate::allows('delete', $this)
&& ($this->assets()->count() === 0)
&& ($this->accessories()->count() === 0)
&& ($this->consumables()->count() === 0)
&& ($this->components()->count() === 0)
&& ($this->users()->count() === 0);
}
public static function getIdForUser($unescaped_input)
{
if (!static::isFullMultipleCompanySupportEnabled() || Auth::user()->isSuperUser()) {

View file

@ -7,10 +7,11 @@ use App\Models\SnipeModel;
use App\Models\Traits\Searchable;
use App\Models\User;
use App\Presenters\Presentable;
use DB;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Gate;
use Watson\Validating\ValidatingTrait;
use DB;
class Location extends SnipeModel
{
@ -86,6 +87,14 @@ class Location extends SnipeModel
'parent' => ['name']
];
public function isDeletable()
{
return Gate::allows('delete', $this)
&& ($this->assignedAssets()->count()===0)
&& ($this->assets()->count()===0)
&& ($this->users()->count()===0);
}
public function users()
{
return $this->hasMany('\App\Models\User', 'location_id');

View file

@ -4,6 +4,7 @@ namespace App\Models;
use App\Models\Traits\Searchable;
use App\Presenters\Presentable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Gate;
use Watson\Validating\ValidatingTrait;
class Manufacturer extends SnipeModel
@ -65,6 +66,14 @@ class Manufacturer extends SnipeModel
protected $searchableRelations = [];
public function isDeletable()
{
return (Gate::allows('delete', $this)
&& ($this->assets()->count() === 0)
&& ($this->licenses()->count() === 0)
&& ($this->consumables()->count() === 0)
&& ($this->accessories()->count() === 0));
}
public function assets()
{

View file

@ -91,7 +91,11 @@ abstract class SnipePermissionsPolicy
*/
public function delete(User $user, $item = null)
{
return $user->hasAccess($this->columnName().'.delete');
$itemConditional = true;
if ($item) {
$itemConditional = empty($item->deleted_at);
}
return $itemConditional && $user->hasAccess($this->columnName().'.delete');
}
/**

View file

@ -43,52 +43,27 @@ class CategoryPresenter extends Presenter
"sortable" => true,
"title" => trans('general.type'),
"visible" => true
], [
"field" => "assets_count",
],[
"field" => "item_count",
"searchable" => false,
"sortable" => true,
"title" => trans('general.assets'),
"title" => trans('general.qty'),
"visible" => true
], [
"field" => "accessories_count",
"searchable" => false,
"sortable" => true,
"title" => trans('general.accessories'),
"visible" => true
], [
"field" => "consumables_count",
"searchable" => false,
"sortable" => true,
"title" => trans('general.consumables'),
"visible" => true
], [
"field" => "components_count",
"searchable" => false,
"sortable" => true,
"title" => trans('general.components'),
"visible" => true
], [
"field" => "licenses_count",
"searchable" => false,
"sortable" => true,
"title" => trans('general.licenses'),
"visible" => true
], [
],[
"field" => "eula",
"searchable" => false,
"sortable" => false,
"title" => trans('admin/categories/table.eula_text'),
"visible" => false,
"formatter" => 'trueFalseFormatter',
], [
],[
"field" => "require_acceptance",
"searchable" => false,
"sortable" => true,
"title" => trans('admin/categories/table.require_acceptance'),
"visible" => true,
"formatter" => 'trueFalseFormatter',
],
[
],[
"field" => "actions",
"searchable" => false,
"sortable" => false,