Improvement: Better documentation, small refactors (#6017)

* Better documentation, small refactors

* Small comment fixes
This commit is contained in:
snipe 2018-08-01 00:06:41 -07:00 committed by GitHub
parent 6ae096a56f
commit 2c38036123
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 1661 additions and 427 deletions

View file

@ -76,10 +76,4 @@ class CreateAdmin extends Command
}
// protected function getArguments()
// {
// return array(
// array('username', InputArgument::REQUIRED, 'Username'),
// );
// }
}

View file

@ -49,6 +49,12 @@ class Kernel extends ConsoleKernel
$schedule->command('backup:clean')->daily();
}
/**
* This method is required by Laravel to handle any console routes
* that are defined in routes/console.php
*
* @return void
*/
protected function commands()
{
require base_path('routes/console.php');

View file

@ -114,15 +114,15 @@ class CategoriesController extends Controller
public function destroy($id)
{
$this->authorize('delete', Category::class);
$category = Category::findOrFail($id);
$category = Category::withCount('models as models_count', 'accessories as accessories_count','consumables as consumables_count','components as components_count')->findOrFail($id);
if ($category->has_models() > 0) {
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) {
} 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) {
} 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) {
} elseif ($category->components_count > 0) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.assoc_items', ['asset_type'=>'component'])));
}
$category->delete();

View file

@ -110,10 +110,10 @@ class DepreciationsController extends Controller
public function destroy($id)
{
$this->authorize('delete', Depreciation::class);
$depreciation = Depreciation::findOrFail($id);
$depreciation = Depreciation::withCount('models as models_count')->findOrFail($id);
$this->authorize('delete', $depreciation);
if ($depreciation->has_models() > 0) {
if ($depreciation->models_count > 0) {
return response()->json(Helper::formatStandardApiResponse('error', trans('admin/depreciations/message.assoc_users')));
}

View file

@ -168,20 +168,21 @@ class CategoriesController extends Controller
{
$this->authorize('delete', Category::class);
// Check if the category exists
if (is_null($category = Category::find($categoryId))) {
if (is_null($category = Category::withCount('models as models_count', 'accessories as accessories_count','consumables as consumables_count','components as components_count')->findOrFail($categoryId))) {
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.not_found'));
}
if ($category->has_models() > 0) {
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']));
} 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']));
}
$category->delete();
// Redirect to the locations management page
return redirect()->route('categories.index')->with('success', trans('admin/categories/message.delete.success'));

View file

@ -150,13 +150,13 @@ class DepreciationsController extends Controller
public function destroy($depreciationId)
{
// Check if the depreciation exists
if (is_null($depreciation = Depreciation::find($depreciationId))) {
if (is_null($depreciation = Depreciation::withCount('models as models_count')->find($depreciationId))) {
return redirect()->route('depreciations.index')->with('error', trans('admin/depreciations/message.not_found'));
}
$this->authorize('delete', $depreciation);
if ($depreciation->has_models() > 0) {
if ($depreciation->models_count > 0) {
// Redirect to the asset management page
return redirect()->route('depreciations.index')->with('error', trans('admin/depreciations/message.assoc_users'));
}

View file

@ -152,14 +152,11 @@ class ManufacturersController extends Controller
public function destroy($manufacturerId)
{
$this->authorize('delete', Manufacturer::class);
// Check if the manufacturer exists
if (is_null($manufacturer = Manufacturer::find($manufacturerId))) {
// Redirect to the manufacturers page
if (is_null($manufacturer = Manufacturer::withCount('models as models_count')->find($manufacturerId))) {
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.not_found'));
}
if ($manufacturer->has_models() > 0) {
// Redirect to the asset management page
if ($manufacturer->models_count > 0) {
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.assoc_users'));
}
@ -167,7 +164,7 @@ class ManufacturersController extends Controller
try {
unlink(public_path().'/uploads/manufacturers/'.$manufacturer->image);
} catch (\Exception $e) {
\Log::error($e);
}
}

View file

@ -113,6 +113,13 @@ abstract class Importer
// Cached Values for import lookups
protected $customFields;
/**
* Sets up the database transaction and logging for the importer
*
* @return void
* @author Daniel Meltzer
* @since 5.0
*/
public function import()
{
$headerRow = $this->csv->fetchOne();

View file

@ -101,13 +101,26 @@ class Accessory extends SnipeModel
/**
* Establishes the accessory -> supplier relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function supplier()
{
return $this->belongsTo('\App\Models\Supplier', 'supplier_id');
}
/**
* Sets the requestable attribute on the accessory
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return void
*/
public function setRequestableAttribute($value)
{
if ($value == '') {
@ -117,24 +130,49 @@ class Accessory extends SnipeModel
return;
}
/**
* Establishes the accessory -> company relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function company()
{
return $this->belongsTo('\App\Models\Company', 'company_id');
}
/**
* Establishes the accessory -> location relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function location()
{
return $this->belongsTo('\App\Models\Location', 'location_id');
}
/**
* Establishes the accessory -> category relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function category()
{
return $this->belongsTo('\App\Models\Category', 'category_id')->where('category_type', '=', 'accessory');
}
/**
* Get action logs for this accessory
*/
* Returns the action logs associated with the accessory
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assetlog()
{
return $this->hasMany('\App\Models\Actionlog', 'item_id')->where('item_type', Accessory::class)->orderBy('created_at', 'desc')->withTrashed();
@ -173,6 +211,16 @@ class Accessory extends SnipeModel
}
/**
* Sets the full image url
*
* @todo this should probably be moved out of the model and into a
* presenter or service provider
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return string
*/
public function getImageUrl() {
if ($this->image) {
return url('/').'/uploads/accessories/'.$this->image;
@ -181,31 +229,77 @@ class Accessory extends SnipeModel
}
/**
* Establishes the accessory -> users relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function users()
{
return $this->belongsToMany('\App\Models\User', 'accessories_users', 'accessory_id', 'assigned_to')->withPivot('id')->withTrashed();
}
/**
* Checks whether or not the accessory has users
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return int
*/
public function hasUsers()
{
return $this->belongsToMany('\App\Models\User', 'accessories_users', 'accessory_id', 'assigned_to')->count();
}
/**
* Establishes the accessory -> manufacturer relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function manufacturer()
{
return $this->belongsTo('\App\Models\Manufacturer', 'manufacturer_id');
}
/**
* Determins whether or not an email should be sent for checkin/checkout of this
* accessory based on the category it belongs to.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return boolean
*/
public function checkin_email()
{
return $this->category->checkin_email;
}
/**
* Determines whether or not the accessory should require the user to
* accept it via email.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return boolean
*/
public function requireAcceptance()
{
return $this->category->require_acceptance;
}
/**
* Checks for a category-specific EULA, and if that doesn't exist,
* checks for a settings level EULA
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return string
*/
public function getEula()
{
@ -219,6 +313,13 @@ class Accessory extends SnipeModel
return null;
}
/**
* Check how many items of an accessory remain
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return int
*/
public function numRemaining()
{
$checkedout = $this->users->count();

View file

@ -41,9 +41,15 @@ class Actionlog extends SnipeModel
*/
protected $searchableRelations = [
'company' => ['name']
];
];
// Overridden from Builder to automatically add the company
/**
* Override from Builder to automatically add the company
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public static function boot()
{
parent::boot();
@ -60,17 +66,39 @@ class Actionlog extends SnipeModel
}
});
}
// Eloquent Relationships below
/**
* Establishes the actionlog -> item relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function item()
{
return $this->morphTo('item')->withTrashed();
}
/**
* Establishes the actionlog -> company relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function company()
{
return $this->hasMany('\App\Models\Company', 'id', 'company_id');
}
/**
* Establishes the actionlog -> item type relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function itemType()
{
@ -80,6 +108,13 @@ class Actionlog extends SnipeModel
return camel_case(class_basename($this->item_type));
}
/**
* Establishes the actionlog -> target type relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function targetType()
{
if ($this->target_type == User::class) {
@ -88,28 +123,14 @@ class Actionlog extends SnipeModel
return camel_case(class_basename($this->target_type));
}
public function parseItemRoute()
{
if ($this->itemType() == "asset") {
$itemroute = 'assets';
} elseif ($this->itemType() == "accessory") {
$itemroute = 'accessories';
} elseif ($this->itemType()=="consumable") {
$itemroute = 'consumables';
} elseif ($this->itemType()=="license") {
$itemroute = 'licenses';
} elseif ($this->itemType()=="component") {
$itemroute = 'components';
} else {
$itemroute = '';
}
return $itemroute;
}
/**
* Establishes the actionlog -> uploads relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function uploads()
{
return $this->morphTo('item')
@ -117,39 +138,62 @@ class Actionlog extends SnipeModel
->withTrashed();
}
/**
* Establishes the actionlog -> userlog relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function userlog()
{
return $this->target();
}
/**
* Establishes the actionlog -> user relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function user()
{
return $this->belongsTo(User::class, 'user_id')
->withTrashed();
}
/**
* Establishes the actionlog -> target relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function target()
{
return $this->morphTo('target')->withTrashed();
}
public function childlogs()
{
return $this->hasMany('\App\Models\ActionLog', 'thread_id');
}
public function parentlog()
{
return $this->belongsTo('\App\Models\ActionLog', 'thread_id');
}
/**
* Establishes the actionlog -> location relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function location() {
return $this->belongsTo('\App\Models\Location', 'location_id' )->withTrashed();
}
/**
* Check if the file exists, and if it does, force a download
**/
* Check if the file exists, and if it does, force a download
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return string | false
*/
public function get_src($type = 'assets', $fieldname = 'filename')
{
if ($this->filename!='') {
@ -162,8 +206,12 @@ class Actionlog extends SnipeModel
/**
* Get the parent category name
*/
* Saves the log record with the action type
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return boolean
*/
public function logaction($actiontype)
{
@ -176,6 +224,13 @@ class Actionlog extends SnipeModel
}
}
/**
* Calculate the number of days until the next audit
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return int
*/
public function daysUntilNextAudit($monthInterval = 12, $asset = null) {
$now = Carbon::now();
@ -192,6 +247,13 @@ class Actionlog extends SnipeModel
return $next_audit_days;
}
/**
* Calculate the date of the next audit
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return \Datetime
*/
public function calcNextAuditDate($monthInterval = 12, $asset = null) {
$last_audit_date = Carbon::parse($this->created_at);
@ -204,12 +266,12 @@ class Actionlog extends SnipeModel
}
/**
* getListingOfActionLogsChronologicalOrder
*
* @return mixed
* @author Vincent Sposato <vincent.sposato@gmail.com>
* @version v1.0
*/
* Gets action logs in chronological order, excluding uploads
*
* @author Vincent Sposato <vincent.sposato@gmail.com>
* @since v1.0
* @return \Illuminate\Database\Eloquent\Collection
*/
public function getListingOfActionLogsChronologicalOrder()
{

View file

@ -174,12 +174,26 @@ class Asset extends Depreciable
return null;
}
/**
* Establishes the asset -> company relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function company()
{
return $this->belongsTo('\App\Models\Company', 'company_id');
}
/**
* Determines if an asset is available for checkout
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return boolean
*/
public function availableForCheckout()
{
if (
@ -192,8 +206,13 @@ class Asset extends Depreciable
return false;
}
/**
* Checkout asset
* Checks the asset out to the target
*
* @todo The admin parameter is never used. Can probably be removed.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param User $user
* @param User $admin
* @param Carbon $checkout_at
@ -201,8 +220,9 @@ class Asset extends Depreciable
* @param string $note
* @param null $name
* @return bool
* @since [v3.0]
* @return boolean
*/
//FIXME: The admin parameter is never used. Can probably be removed.
public function checkOut($target, $admin = null, $checkout_at = null, $expected_checkin = null, $note = null, $name = null, $location = null)
{
if (!$target) {
@ -253,6 +273,13 @@ class Asset extends Depreciable
return false;
}
/**
* Sets the detailedNameAttribute
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return string
*/
public function getDetailedNameAttribute()
{
if ($this->assignedto) {
@ -263,31 +290,54 @@ class Asset extends Depreciable
return $this->asset_tag . ' - ' . $this->name . ' (' . $user_name . ') ' . ($this->model) ? $this->model->name: '';
}
public function validationRules($id = '0')
/**
* Pulls in the validation rules
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return array
*/
public function validationRules()
{
return $this->rules;
}
/**
* Set depreciation relationship
*/
* Establishes the asset -> depreciation relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function depreciation()
{
return $this->model->belongsTo('\App\Models\Depreciation', 'depreciation_id');
}
/**
* Get components assigned to this asset
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function components()
{
return $this->belongsToMany('\App\Models\Component', 'components_assets', 'asset_id', 'component_id')->withPivot('id', 'assigned_qty')->withTrashed();
}
/**
* Get depreciation attribute from associated asset model
*/
/**
* Get depreciation attribute from associated asset model
*
* @todo Is this still needed?
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function get_depreciation()
{
if (($this->model) && ($this->model->depreciation)) {
@ -295,9 +345,14 @@ class Asset extends Depreciable
}
}
/**
* Get uploads for this asset
*/
/**
* Get uploads for this asset
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function uploads()
{
return $this->hasMany('\App\Models\Actionlog', 'item_id')
@ -307,29 +362,58 @@ class Asset extends Depreciable
->orderBy('created_at', 'desc');
}
/**
* Determines whether the asset is checked out to a user
*
* Even though we allow allow for checkout to things beyond users
* this method is an easy way of seeing if we are checked out to a user.
* @return mixed
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return boolean
*/
public function checkedOutToUser()
{
return $this->assignedType() === self::USER;
}
/**
* Get the target this asset is checked out to
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assignedTo()
{
return $this->morphTo('assigned', 'assigned_type', 'assigned_to');
}
/**
* Gets assets assigned to this asset
*
* Sigh.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assignedAssets()
{
return $this->morphMany('App\Models\Asset', 'assigned', 'assigned_type', 'assigned_to')->withTrashed();
}
/**
* Get the asset's location based on the assigned user
**/
/**
* Get the asset's location based on the assigned user
*
* @todo Refactor this if possible. It's awful.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return \ArrayObject
*/
public function assetLoc($iterations = 1,$first_asset = null)
{
if (!empty($this->assignedType())) {
@ -364,19 +448,40 @@ class Asset extends Depreciable
return $this->defaultLoc;
}
/**
* Gets the lowercased name of the type of target the asset is assigned to
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return string
*/
public function assignedType()
{
return strtolower(class_basename($this->assigned_type));
}
/**
* Get the asset's location based on default RTD location
**/
/**
* Get the asset's location based on default RTD location
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function defaultLoc()
{
return $this->belongsTo('\App\Models\Location', 'rtd_location_id');
}
/**
* Get the image URL of the asset.
*
* Check first to see if there is a specific image uploaded to the asset,
* and if not, check for an image uploaded to the asset model.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return string | false
*/
public function getImageUrl()
{
if ($this->image && !empty($this->image)) {
@ -388,9 +493,13 @@ class Asset extends Depreciable
}
/**
* Get action logs for this asset
*/
/**
* Get the asset's logs
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assetlog()
{
return $this->hasMany('\App\Models\Actionlog', 'item_id')
@ -400,7 +509,11 @@ class Asset extends Depreciable
}
/**
* Get checkouts
* Get the list of checkouts for this asset
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function checkouts()
{
@ -410,7 +523,11 @@ class Asset extends Depreciable
}
/**
* Get checkins
* Get the list of checkins for this asset
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function checkins()
{
@ -421,7 +538,11 @@ class Asset extends Depreciable
}
/**
* Get user requests
* Get the asset's user requests
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function userRequests()
{
@ -432,71 +553,65 @@ class Asset extends Depreciable
}
/**
* assetmaintenances
* Get improvements for this asset
*
* @return mixed
* @author Vincent Sposato <vincent.sposato@gmail.com>
* @version v1.0
*/
/**
* Get maintenances for this asset
*
* @author Vincent Sposato <vincent.sposato@gmail.com>
* @since 1.0
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assetmaintenances()
{
return $this->hasMany('\App\Models\AssetMaintenance', 'asset_id')
->orderBy('created_at', 'desc');
}
/**
* Get action logs for this asset
*/
/**
* Get action logs history for this asset
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function adminuser()
{
return $this->belongsTo('\App\Models\User', 'user_id');
}
/**
* Get total assets
*/
public static function assetcount()
{
return Company::scopeCompanyables(Asset::where('physical', '=', '1'))
->whereNull('deleted_at', 'and')
->count();
}
/**
* Get total assets not checked out
*/
public static function availassetcount()
{
return Asset::RTD()
->whereNull('deleted_at')
->count();
}
/**
* Get requestable assets
*/
public static function getRequestable()
{
return Asset::Requestable()
->whereNull('deleted_at')
->count();
}
/**
* Get asset status
*/
/**
* Establishes the asset -> status relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assetstatus()
{
return $this->belongsTo('\App\Models\Statuslabel', 'status_id');
}
/**
* Establishes the asset -> model relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function model()
{
return $this->belongsTo('\App\Models\AssetModel', 'model_id')->withTrashed();
}
/**
* Return the assets with a warranty expiring within x days
*
* @param $days
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return mixed
*/
public static function getExpiringWarrantee($days = 30)
{
return Asset::where('archived', '=', '0')
@ -510,25 +625,50 @@ class Asset extends Depreciable
->get();
}
/**
* Get the license seat information
**/
/**
* Establishes the asset -> assigned licenses relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function licenses()
{
return $this->belongsToMany('\App\Models\License', 'license_seats', 'asset_id', 'license_id');
}
/**
* Establishes the asset -> status relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function licenseseats()
{
return $this->hasMany('\App\Models\LicenseSeat', 'asset_id');
}
/**
* Establishes the asset -> aupplier relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function supplier()
{
return $this->belongsTo('\App\Models\Supplier', 'supplier_id');
}
/**
* Establishes the asset -> location relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function location()
{
return $this->belongsTo('\App\Models\Location', 'location_id');
@ -536,9 +676,13 @@ class Asset extends Depreciable
/**
* Get auto-increment
*/
/**
* Get the next autoincremented asset tag
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return string | false
*/
public static function autoincrement_asset()
{
$settings = \App\Models\Setting::getSettings();
@ -561,10 +705,15 @@ class Asset extends Depreciable
}
}
/*
* Get the next base number for the auto-incrementer. We'll add the zerofill and
* prefixes on the fly as we generate the number
/**
* Get the next base number for the auto-incrementer.
*
* We'll add the zerofill and prefixes on the fly as we generate the number.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return int
*/
public static function nextAutoIncrement($assets)
{
@ -590,23 +739,53 @@ class Asset extends Depreciable
/**
* Add zerofilling based on Settings
*
* We'll add the zerofill and prefixes on the fly as we generate the number.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return string
*/
public static function zerofill($num, $zerofill = 3)
{
return str_pad($num, $zerofill, '0', STR_PAD_LEFT);
}
/**
* Determine whether to send a checkin/checkout email based on
* asset model category
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return boolean
*/
public function checkin_email()
{
return $this->model->category->checkin_email;
}
/**
* Determine whether this asset requires acceptance by the assigned user
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return boolean
*/
public function requireAcceptance()
{
return $this->model->category->require_acceptance;
}
/**
* Checks for a category-specific EULA, and if that doesn't exist,
* checks for a settings level EULA
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return string | false
*/
public function getEula()
{
$Parsedown = new \Parsedown();
@ -620,91 +799,92 @@ class Asset extends Depreciable
}
}
/**
* -----------------------------------------------
* BEGIN QUERY SCOPES
* -----------------------------------------------
**/
/**
* Run additional, advanced searches.
*
* @param Illuminate\Database\Eloquent\Builder $query
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param array $terms The search terms
* @return Illuminate\Database\Eloquent\Builder
* @return \Illuminate\Database\Eloquent\Builder
*/
public function advancedTextSearch(Builder $query, array $terms) {
/**
* Assigned user
*/
$query = $query->leftJoin('users as assets_users',function ($leftJoin) {
/**
* Assigned user
*/
$query = $query->leftJoin('users as assets_users',function ($leftJoin) {
$leftJoin->on("assets_users.id", "=", "assets.assigned_to")
->where("assets.assigned_type", "=", User::class);
});
});
foreach($terms as $term) {
foreach($terms as $term) {
$query = $query
->orWhere('assets_users.first_name', 'LIKE', '%'.$term.'%')
->orWhere('assets_users.last_name', 'LIKE', '%'.$term.'%')
->orWhere('assets_users.username', 'LIKE', '%'.$term.'%')
->orWhereRaw('CONCAT('.DB::getTablePrefix().'assets_users.first_name," ",'.DB::getTablePrefix().'assets_users.last_name) LIKE ?', ["%$term%", "%$term%"]);
$query = $query
->orWhere('assets_users.first_name', 'LIKE', '%'.$term.'%')
->orWhere('assets_users.last_name', 'LIKE', '%'.$term.'%')
->orWhere('assets_users.username', 'LIKE', '%'.$term.'%')
->orWhereRaw('CONCAT('.DB::getTablePrefix().'assets_users.first_name," ",'.DB::getTablePrefix().'assets_users.last_name) LIKE ?', ["%$term%", "%$term%"]);
}
}
/**
* Assigned location
*/
$query = $query->leftJoin('locations as assets_locations',function ($leftJoin) {
$leftJoin->on("assets_locations.id","=","assets.assigned_to")
->where("assets.assigned_type","=",Location::class);
});
/**
* Assigned location
*/
$query = $query->leftJoin('locations as assets_locations',function ($leftJoin) {
$leftJoin->on("assets_locations.id","=","assets.assigned_to")
->where("assets.assigned_type","=",Location::class);
});
foreach($terms as $term) {
foreach($terms as $term) {
$query = $query->orWhere('assets_locations.name', 'LIKE', '%'.$term.'%');
$query = $query->orWhere('assets_locations.name', 'LIKE', '%'.$term.'%');
}
}
/**
* Assigned assets
*/
$query = $query->leftJoin('assets as assigned_assets',function ($leftJoin) {
$leftJoin->on('assigned_assets.id', '=', 'assets.assigned_to')
->where('assets.assigned_type', '=', Asset::class);
});
/**
* Assigned assets
*/
$query = $query->leftJoin('assets as assigned_assets',function ($leftJoin) {
$leftJoin->on('assigned_assets.id', '=', 'assets.assigned_to')
->where('assets.assigned_type', '=', Asset::class);
});
foreach($terms as $term) {
foreach($terms as $term) {
$query = $query->orWhere('assigned_assets.name', 'LIKE', '%'.$term.'%');
}
$query = $query->orWhere('assigned_assets.name', 'LIKE', '%'.$term.'%');
return $query;
}
return $query;
}
/**
* -----------------------------------------------
* BEGIN QUERY SCOPES
* -----------------------------------------------
**/
/**
* Query builder scope for hardware
*
* @param \Illuminate\Database\Query\Builder $query Query builder instance
*
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
/**
* Query builder scope for hardware
*
* @param \Illuminate\Database\Query\Builder $query Query builder instance
*
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeHardware($query)
{
return $query->where('physical', '=', '1');
}
/**
* Query builder scope for pending assets
*
* @param \Illuminate\Database\Query\Builder $query Query builder instance
*
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
/**
* Query builder scope for pending assets
*
* @param \Illuminate\Database\Query\Builder $query Query builder instance
*
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopePending($query)
{

View file

@ -22,7 +22,6 @@ class AssetMaintenance extends Model implements ICompanyableChild
protected $dates = [ 'deleted_at', 'start_date' , 'completion_date'];
protected $table = 'asset_maintenances';
// Declaring rules for form validation
protected $rules = [
'asset_id' => 'required|integer',
'supplier_id' => 'required|integer',

View file

@ -87,44 +87,92 @@ class AssetModel extends SnipeModel
'depreciation' => ['name'],
'category' => ['name'],
'manufacturer' => ['name'],
];
];
/**
* Establishes the model -> assets relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assets()
{
return $this->hasMany('\App\Models\Asset', 'model_id');
}
/**
* Establishes the model -> category relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function category()
{
return $this->belongsTo('\App\Models\Category', 'category_id');
}
/**
* Establishes the model -> depreciation relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function depreciation()
{
return $this->belongsTo('\App\Models\Depreciation', 'depreciation_id');
}
public function adminuser()
{
return $this->belongsTo('\App\Models\User', 'user_id');
}
/**
* Establishes the model -> manufacturer relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function manufacturer()
{
return $this->belongsTo('\App\Models\Manufacturer', 'manufacturer_id');
}
/**
* Establishes the model -> fieldset relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function fieldset()
{
return $this->belongsTo('\App\Models\CustomFieldset', 'fieldset_id');
}
/**
* Establishes the model -> custom field default values relationship
*
* @author hannah tinkler
* @since [v4.3]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function defaultValues()
{
return $this->belongsToMany('\App\Models\CustomField', 'models_custom_fields')->withPivot('default_value');
}
/**
* Gets the full url for the image
*
* @todo this should probably be moved
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function getImageUrl() {
if ($this->image) {
return url('/').'/uploads/models/'.$this->image;
@ -141,8 +189,8 @@ class AssetModel extends SnipeModel
/**
* Query builder scope for Deleted assets
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @return Illuminate\Database\Query\Builder Modified query builder
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeDeleted($query)

View file

@ -80,31 +80,62 @@ class Category extends SnipeModel
*/
protected $searchableRelations = [];
public function has_models()
{
return $this->hasMany('\App\Models\AssetModel', 'category_id')->count();
}
/**
* Establishes the category -> accessories relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function accessories()
{
return $this->hasMany('\App\Models\Accessory');
}
/**
* Establishes the category -> licenses relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.3]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function licenses()
{
return $this->hasMany('\App\Models\License');
}
/**
* Establishes the category -> consumables relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function consumables()
{
return $this->hasMany('\App\Models\Consumable');
}
/**
* Establishes the category -> consumables relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function components()
{
return $this->hasMany('\App\Models\Component');
}
/**
* Get the number of items in the category
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return int
*/
public function itemCount()
{
switch ($this->category_type) {
@ -120,16 +151,38 @@ class Category extends SnipeModel
return '0';
}
/**
* Establishes the category -> assets relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assets()
{
return $this->hasManyThrough('\App\Models\Asset', '\App\Models\AssetModel', 'category_id', 'model_id');
}
/**
* Establishes the category -> models relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function models()
{
return $this->hasMany('\App\Models\AssetModel', 'category_id');
}
/**
* Checks for a category-specific EULA, and if that doesn't exist,
* checks for a settings level EULA
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return string | null
*/
public function getEula()
{
@ -145,15 +198,22 @@ class Category extends SnipeModel
}
/**
* scopeRequiresAcceptance
* -----------------------------------------------
* BEGIN QUERY SCOPES
* -----------------------------------------------
**/
/**
* Query builder scope for whether or not the category requires acceptance
*
* @param $query
*
* @return mixed
* @author Vincent Sposato <vincent.sposato@gmail.com>
* @version v1.0
*
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeRequiresAcceptance($query)
{

View file

@ -86,43 +86,89 @@ class Component extends SnipeModel
'category' => ['name'],
'company' => ['name'],
'location' => ['name'],
];
];
/**
* Establishes the component -> location relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function location()
{
return $this->belongsTo('\App\Models\Location', 'location_id');
}
/**
* Establishes the component -> assets relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assets()
{
return $this->belongsToMany('\App\Models\Asset', 'components_assets')->withPivot('id', 'assigned_qty', 'created_at', 'user_id');
}
/**
* Establishes the component -> admin user relationship
*
* @todo this is probably not needed - refactor
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function admin()
{
return $this->belongsTo('\App\Models\User', 'user_id');
}
/**
* Establishes the component -> company relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function company()
{
return $this->belongsTo('\App\Models\Company', 'company_id');
}
/**
* Establishes the component -> category relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function category()
{
return $this->belongsTo('\App\Models\Category', 'category_id');
}
/**
* Get action logs for this consumable
*/
* Establishes the component -> action logs relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assetlog()
{
return $this->hasMany('\App\Models\Actionlog', 'item_id')->where('item_type', Component::class)->orderBy('created_at', 'desc')->withTrashed();
}
/**
* Check how many items within a component are remaining
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return int
*/
public function numRemaining()
{
$checkedout = 0;
@ -140,10 +186,10 @@ class Component extends SnipeModel
/**
* Query builder scope to order on company
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param string $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderCategory($query, $order)
{
@ -153,10 +199,10 @@ class Component extends SnipeModel
/**
* Query builder scope to order on company
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param string $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderLocation($query, $order)
{
@ -167,10 +213,10 @@ class Component extends SnipeModel
/**
* Query builder scope to order on company
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param string $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderCompany($query, $order)
{

View file

@ -88,8 +88,21 @@ class Consumable extends SnipeModel
'company' => ['name'],
'location' => ['name'],
'manufacturer' => ['name'],
];
];
/**
* Sets the attribute of whether or not the consumable is requestable
*
* This isn't really implemented yet, as you can't currently request a consumable
* however it will be implemented in the future, and we needed to include
* this method here so all of our polymorphic methods don't break.
*
* @todo Update this comment once it's been implemented
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function setRequestableAttribute($value)
{
if ($value == '') {
@ -99,44 +112,98 @@ class Consumable extends SnipeModel
return;
}
/**
* Establishes the consumable -> admin user relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function admin()
{
return $this->belongsTo('\App\Models\User', 'user_id');
}
/**
* Establishes the component -> assignments relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function consumableAssignments()
{
return $this->hasMany('\App\Models\ConsumableAssignment');
}
/**
* Establishes the component -> company relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function company()
{
return $this->belongsTo('\App\Models\Company', 'company_id');
}
/**
* Establishes the component -> manufacturer relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function manufacturer()
{
return $this->belongsTo('\App\Models\Manufacturer', 'manufacturer_id');
}
/**
* Establishes the component -> location relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function location()
{
return $this->belongsTo('\App\Models\Location', 'location_id');
}
/**
* Establishes the component -> category relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function category()
{
return $this->belongsTo('\App\Models\Category', 'category_id');
}
/**
* Get action logs for this consumable
*/
* Establishes the component -> action logs relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assetlog()
{
return $this->hasMany('\App\Models\Actionlog', 'item_id')->where('item_type', Consumable::class)->orderBy('created_at', 'desc')->withTrashed();
}
/**
* Gets the full image url for the consumable
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return string | false
*/
public function getImageUrl() {
if ($this->image) {
return url('/').'/uploads/consumables/'.$this->image;
@ -145,27 +212,52 @@ class Consumable extends SnipeModel
}
/**
* Establishes the component -> users relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function users()
{
return $this->belongsToMany('\App\Models\User', 'consumables_users', 'consumable_id', 'assigned_to')->withPivot('user_id')->withTrashed()->withTimestamps();
}
public function hasUsers()
{
return $this->belongsToMany('\App\Models\User', 'consumables_users', 'consumable_id', 'assigned_to')->count();
}
/**
* Determine whether to send a checkin/checkout email based on
* asset model category
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return boolean
*/
public function checkin_email()
{
return $this->category->checkin_email;
}
}
/**
* Determine whether this asset requires acceptance by the assigned user
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return boolean
*/
public function requireAcceptance()
{
return $this->category->require_acceptance;
}
/**
* Checks for a category-specific EULA, and if that doesn't exist,
* checks for a settings level EULA
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return string | false
*/
public function getEula()
{
@ -181,6 +273,13 @@ class Consumable extends SnipeModel
}
/**
* Checks the number of available consumables
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return int
*/
public function numRemaining()
{
$checkedout = $this->users->count();
@ -192,10 +291,10 @@ class Consumable extends SnipeModel
/**
* Query builder scope to order on company
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param string $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderCategory($query, $order)
{
@ -205,10 +304,10 @@ class Consumable extends SnipeModel
/**
* Query builder scope to order on location
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderLocation($query, $order)
{
@ -218,10 +317,10 @@ class Consumable extends SnipeModel
/**
* Query builder scope to order on manufacturer
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param string $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderManufacturer($query, $order)
{
@ -232,10 +331,10 @@ class Consumable extends SnipeModel
/**
* Query builder scope to order on company
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param string $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderCompany($query, $order)
{

View file

@ -46,10 +46,15 @@ class CustomField extends Model
'show_in_email',
];
// This is confusing, since it's actually the custom fields table that
// we're usually modifying, but since we alter the assets table, we have to
// say that here, otherwise the new fields get added onto the custom fields
// table instead of the assets table.
/**
* This is confusing, since it's actually the custom fields table that
* we're usually modifying, but since we alter the assets table, we have to
* say that here, otherwise the new fields get added onto the custom fields
* table instead of the assets table.
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @since [v3.0]
*/
public static $table_name = "assets";
@ -138,16 +143,37 @@ class CustomField extends Model
});
}
/**
* Establishes the customfield -> fieldset relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function fieldset()
{
return $this->belongsToMany('\App\Models\CustomFieldset');
}
/**
* Establishes the customfield -> admin user relationship
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function user()
{
return $this->belongsTo('\App\Models\User');
}
/**
* Establishes the customfield -> default values relationship
*
* @author Hannah Tinkler
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function defaultValues()
{
return $this->belongsToMany('\App\Models\AssetModel', 'models_custom_fields')->withPivot('default_value');
@ -169,11 +195,28 @@ class CustomField extends Model
})->first();
}
/**
* Checks the format of the attribute
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param $value string
* @since [v3.0]
* @return boolean
*/
public function check_format($value)
{
return preg_match('/^'.$this->attributes['format'].'$/', $value)===1;
}
/**
* Gets the DB column name.
*
* @todo figure out if this is still needed? I don't know WTF it's for.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function db_column_name()
{
return $this->db_column;
@ -188,7 +231,7 @@ class CustomField extends Model
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.4]
* @return Array
* @return string
*/
public function getFormatAttribute($value)
{
@ -205,7 +248,7 @@ class CustomField extends Model
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.4]
* @return Array
* @return array
*/
public function setFormatAttribute($value)
{
@ -221,7 +264,7 @@ class CustomField extends Model
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.4]
* @return Array
* @return array
*/
public function formatFieldValuesAsArray()
{
@ -249,7 +292,7 @@ class CustomField extends Model
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.4]
* @return Boolean
* @return boolean
*/
public function isFieldDecryptable($string)
{
@ -266,7 +309,7 @@ class CustomField extends Model
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.4]
* @return Boolean
* @return boolean
*/
public function convertUnicodeDbSlug($original = null)
{
@ -287,7 +330,7 @@ class CustomField extends Model
* @author [V. Cordes] [<volker@fdatek.de>]
* @param int $id
* @since [v4.1.10]
* @return Array
* @return array
*/
public function validationRules()
{

View file

@ -22,23 +22,52 @@ class CustomFieldset extends Model
*/
protected $injectUniqueIdentifier = true;
use ValidatingTrait;
/**
* Establishes the fieldset -> field relationship
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function fields()
{
return $this->belongsToMany('\App\Models\CustomField')->withPivot(["required","order"])->orderBy("pivot_order");
}
/**
* Establishes the fieldset -> models relationship
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function models()
{
return $this->hasMany('\App\Models\AssetModel', "fieldset_id");
}
/**
* Establishes the fieldset -> admin user relationship
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function user()
{
return $this->belongsTo('\App\Models\User'); //WARNING - not all CustomFieldsets have a User!!
}
/**
* Determine the validation rules we should apply based on the
* custom field format
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return array
*/
public function validation_rules()
{
$rules=[];

View file

@ -60,18 +60,27 @@ class Department extends SnipeModel
*
* @var array
*/
protected $searchableRelations = [];
protected $searchableRelations = [];
/**
* Establishes the department -> company relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function company()
{
return $this->belongsTo('\App\Models\Company', 'company_id');
}
/**
* Even though we allow allow for checkout to things beyond users
* this method is an easy way of seeing if we are checked out to a user.
* @return mixed
* Establishes the department -> users relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function users()
{
@ -80,15 +89,24 @@ class Department extends SnipeModel
/**
* Return the manager in charge of the dept
* @return mixed
*/
* Establishes the department -> manager relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function manager()
{
return $this->belongsTo('\App\Models\User', 'manager_id');
}
/**
* Establishes the department -> location relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function location()
{
return $this->belongsTo('\App\Models\Location', 'location_id');

View file

@ -48,14 +48,28 @@ class Depreciation extends SnipeModel
*/
protected $searchableRelations = [];
public function has_models()
/**
* Establishes the depreciation -> models relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v5.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function models()
{
return $this->hasMany('\App\Models\AssetModel', 'depreciation_id')->count();
return $this->hasMany('\App\Models\AssetModel', 'depreciation_id');
}
public function has_licenses()
/**
* Establishes the depreciation -> licenses relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v5.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function licenses()
{
return $this->hasMany('\App\Models\License', 'depreciation_id')->count();
return $this->hasMany('\App\Models\License', 'depreciation_id');
}
}

View file

@ -37,17 +37,27 @@ class Group extends SnipeModel
*
* @var array
*/
protected $searchableRelations = [];
protected $searchableRelations = [];
/**
* Get user groups
*/
* Establishes the groups -> users relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function users()
{
return $this->belongsToMany('\App\Models\User', 'users_groups');
}
/**
* Decode JSON permissions into array
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return array
*/
public function decodePermissions()
{
return json_decode($this->permissions, true);

View file

@ -110,8 +110,14 @@ class License extends Depreciable
protected $searchableRelations = [
'manufacturer' => ['name'],
'company' => ['name'],
];
];
/**
* Update seat counts when the license is updated
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
*/
public static function boot()
{
parent::boot();
@ -128,6 +134,13 @@ class License extends Depreciable
});
}
/**
* Balance seat counts
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public static function adjustSeatCount($license, $oldSeats, $newSeats)
{
// If the seats haven't changed, continue on happily.
@ -181,15 +194,37 @@ class License extends Depreciable
return true;
}
/**
* Sets the attribute for whether or not the license is maintained
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return mixed
*/
public function setMaintainedAttribute($value)
{
$this->attributes['maintained'] = filter_var($value, FILTER_VALIDATE_BOOLEAN);
}
/**
* Sets the reassignable attribute
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return mixed
*/
public function setReassignableAttribute($value)
{
$this->attributes['reassignable'] = filter_var($value, FILTER_VALIDATE_BOOLEAN);
}
/**
* Sets expiration date attribute
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return mixed
*/
public function setExpirationDateAttribute($value)
{
@ -201,6 +236,13 @@ class License extends Depreciable
$this->attributes['expiration_date'] = $value;
}
/**
* Sets termination date attribute
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return mixed
*/
public function setTerminationDateAttribute($value)
{
if ($value == '' || $value == '0000-00-00') {
@ -211,31 +253,74 @@ class License extends Depreciable
$this->attributes['termination_date'] = $value;
}
/**
* Establishes the license -> company relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function company()
{
return $this->belongsTo('\App\Models\Company', 'company_id');
}
/**
* Establishes the license -> category relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function category()
{
return $this->belongsTo('\App\Models\Category', 'category_id');
}
/**
* Establishes the license -> manufacturer relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function manufacturer()
{
return $this->belongsTo('\App\Models\Manufacturer', 'manufacturer_id');
}
/**
* Determine whether the user should be emailed on checkin/checkout
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return boolean
*/
public function checkin_email()
{
return $this->category->checkin_email;
}
/**
* Determine whether the user should be required to accept the license
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.0]
* @return boolean
*/
public function requireAcceptance()
{
return $this->category->require_acceptance;
}
/**
* Checks for a category-specific EULA, and if that doesn't exist,
* checks for a settings level EULA
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return string | false
*/
public function getEula()
{
$Parsedown = new \Parsedown();
@ -250,7 +335,11 @@ class License extends Depreciable
}
/**
* Get the assigned user
* Establishes the license -> assigned user relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assignedusers()
{
@ -258,8 +347,12 @@ class License extends Depreciable
}
/**
* Get asset logs for this asset
*/
* Establishes the license -> action logs relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assetlog()
{
return $this->hasMany('\App\Models\Actionlog', 'item_id')
@ -268,8 +361,12 @@ class License extends Depreciable
}
/**
* Get uploads for this asset
*/
* Establishes the license -> action logs -> uploads relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function uploads()
{
return $this->hasMany('\App\Models\Actionlog', 'item_id')
@ -281,16 +378,26 @@ class License extends Depreciable
/**
* Get admin user for this asset
*/
* Establishes the license -> admin user relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function adminuser()
{
return $this->belongsTo('\App\Models\User', 'user_id');
}
/**
* Get total licenses
*/
* Returns the total number of all license seats
*
* @todo this can probably be refactored at some point. We don't need counting methods.
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return int
*/
public static function assetcount()
{
return LicenseSeat::whereNull('deleted_at')
@ -299,8 +406,14 @@ class License extends Depreciable
/**
* Get total licenses
*/
* Return the number of seats for this asset
*
* @todo this can also probably be refactored at some point.
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function totalSeatsByLicenseID()
{
return LicenseSeat::where('license_id', '=', $this->id)
@ -308,12 +421,28 @@ class License extends Depreciable
->count();
}
// We do this to eager load the "count" of seats from the controller. Otherwise calling "count()" on each model results in n+1
/**
* Establishes the license -> seat relationship
*
* We do this to eager load the "count" of seats from the controller.
* Otherwise calling "count()" on each model results in n+1 sadness.
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function licenseSeatsRelation()
{
return $this->hasMany(LicenseSeat::class)->whereNull('deleted_at')->selectRaw('license_id, count(*) as count')->groupBy('license_id');
}
/**
* Sets the license seat count attribute
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return int
*/
public function getLicenseSeatsCountAttribute()
{
if ($this->licenseSeatsRelation->first()) {
@ -324,8 +453,12 @@ class License extends Depreciable
}
/**
* Get total licenses not checked out
*/
* Returns the number of total available seats across all licenses
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return int
*/
public static function availassetcount()
{
return LicenseSeat::whereNull('assigned_to')
@ -335,7 +468,11 @@ class License extends Depreciable
}
/**
* Get the number of available seats
* Returns the number of total available seats for this license
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function availCount()
{
@ -345,6 +482,13 @@ class License extends Depreciable
->whereNull('deleted_at');
}
/**
* Sets the available seats attribute
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return mixed
*/
public function getAvailSeatsCountAttribute()
{
if ($this->availCount->first()) {
@ -355,8 +499,11 @@ class License extends Depreciable
}
/**
* Get the number of assigned seats
* Retuns the number of assigned seats for this asset
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assignedCount()
{
@ -366,9 +513,15 @@ class License extends Depreciable
});
}
/**
* Sets the assigned seats attribute
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return int
*/
public function getAssignedSeatsCountAttribute()
{
// dd($this->licenseSeatsRelation->first());
if ($this->assignedCount->first()) {
return $this->assignedCount->first()->count;
}
@ -376,6 +529,13 @@ class License extends Depreciable
return 0;
}
/**
* Calculates the number of remaining seats
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return int
*/
public function remaincount()
{
$total = $this->licenseSeatsCount;
@ -385,7 +545,11 @@ class License extends Depreciable
}
/**
* Get the total number of seats
* Returns the total number of seats for this license
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return int
*/
public function totalcount()
{
@ -396,21 +560,37 @@ class License extends Depreciable
}
/**
* Get license seat data
* Establishes the license -> seats relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function licenseseats()
{
return $this->hasMany('\App\Models\LicenseSeat');
}
/**
* Establishes the license -> supplier relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function supplier()
{
return $this->belongsTo('\App\Models\Supplier', 'supplier_id');
}
/*
* Get the next available free seat - used by
/**
* Gets the next available free seat - used by
* the API to populate next_seat
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return mixed
*/
public function freeSeat()
{
@ -424,15 +604,28 @@ class License extends Depreciable
->first();
}
/*
* Get the next available free seat - used by
* the API to populate next_seat
*/
/**
* Establishes the license -> free seats relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function freeSeats()
{
return $this->hasMany('\App\Models\LicenseSeat')->whereNull('assigned_to')->whereNull('deleted_at')->whereNull('asset_id');
}
/**
* Returns expiring licenses
*
* @todo should refactor. I don't like get() in model methods
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public static function getExpiringLicenses($days = 60)
{
@ -448,10 +641,10 @@ class License extends Depreciable
/**
* Query builder scope to order on manufacturer
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param string $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderManufacturer($query, $order)
{
@ -463,7 +656,7 @@ class License extends Depreciable
* Query builder scope to order on supplier
*
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
* @param string $order Order
*
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
@ -476,10 +669,10 @@ class License extends Depreciable
/**
* Query builder scope to order on company
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderCompany($query, $order)
{

View file

@ -28,21 +28,50 @@ class LicenseSeat extends Model implements ICompanyableChild
return ['asset', 'license'];
}
/**
* Establishes the seat -> license relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function license()
{
return $this->belongsTo('\App\Models\License', 'license_id');
}
/**
* Establishes the seat -> assignee relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function user()
{
return $this->belongsTo('\App\Models\User', 'assigned_to')->withTrashed();
}
/**
* Establishes the seat -> asset relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function asset()
{
return $this->belongsTo('\App\Models\Asset', 'asset_id')->withTrashed();
}
/**
* Determines the assigned seat's location based on user
* or asset its assigned to
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.0]
* @return string
*/
public function location()
{
if (($this->user) && ($this->user->location)) {

View file

@ -79,11 +79,25 @@ class Location extends SnipeModel
'parent' => ['name']
];
/**
* Establishes the location -> users relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function users()
{
return $this->hasMany('\App\Models\User', 'location_id');
}
/**
* Establishes the location -> assets relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assets()
{
return $this->hasMany('\App\Models\Asset', 'location_id')
@ -94,52 +108,103 @@ class Location extends SnipeModel
});
}
/**
* Establishes the location -> asset's RTD relationship
*
* This used to have an ...->orHas() clause that referred to
* assignedAssets, and that was probably incorrect, as well as
* definitely was setting fire to the query-planner. So don't do that.
*
* It is arguable that we should have a '...->whereNull('assigned_to')
* bit in there, but that isn't always correct either (in the case
* where a user has no location, for example).
*
* In all likelihood, we need to denorm an "effective_location" column
* into Assets to make this slightly less miserable.
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function rtd_assets()
{
/* This used to have an ...->orHas() clause that referred to
assignedAssets, and that was probably incorrect, as well as
definitely was setting fire to the query-planner. So don't do that.
It is arguable that we should have a '...->whereNull('assigned_to')
bit in there, but that isn't always correct either (in the case
where a user has no location, for example).
In all likelyhood, we need to denorm an "effective_location" column
into Assets to make this slightly less miserable.
/*
*/
return $this->hasMany('\App\Models\Asset', 'rtd_location_id');
}
/**
* Establishes the location -> parent location relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function parent()
{
return $this->belongsTo('\App\Models\Location', 'parent_id','id');
}
/**
* Establishes the location -> manager relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function manager()
{
return $this->belongsTo('\App\Models\User', 'manager_id');
}
/**
* Establishes the location -> child locations relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function childLocations()
{
return $this->hasMany('\App\Models\Location', 'parent_id');
}
// I don't think we need this anymore since we de-normed location_id in assets?
/**
* Establishes the location -> assigned assets relationship
*
* I don't think we need this anymore since we de-normed location_id in assets?
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assignedAssets()
{
return $this->morphMany('App\Models\Asset', 'assigned', 'assigned_type', 'assigned_to')->withTrashed();
}
/**
* Sets the location-specific OU attribute
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return mixed
*/
public function setLdapOuAttribute($ldap_ou)
{
return $this->attributes['ldap_ou'] = empty($ldap_ou) ? null : $ldap_ou;
}
/**
* Recursion to determine location hierarchy
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return mixed
*/
public static function getLocationHierarchy($locations, $parent_id = null)
{
$op = array();
foreach ($locations as $location) {
@ -163,7 +228,15 @@ class Location extends SnipeModel
return $op;
}
/**
* Flattens the location array for display on the front-end
*
* @todo maybe move to presenters?
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public static function flattenLocationsArray($location_options_array = null)
{
$location_options = array();
@ -193,14 +266,15 @@ class Location extends SnipeModel
/**
* Query builder scope to order on parent
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
* We have to use a Left join here, or it will only return results with parents
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param string $order Order
*
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderParent($query, $order)
{
// Left join here, or it will only return results with parents
return $query->leftJoin('locations as parent_loc', 'locations.parent_id', '=', 'parent_loc.id')->orderBy('parent_loc.name', $order);
}
@ -208,7 +282,7 @@ class Location extends SnipeModel
* Query builder scope to order on manager name
*
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
* @param string $order Order
*
* @return \Illuminate\Database\Query\Builder Modified query builder
*/

View file

@ -66,11 +66,6 @@ class Manufacturer extends SnipeModel
public function has_models()
{
return $this->hasMany('\App\Models\AssetModel', 'manufacturer_id')->count();
}
public function assets()
{
return $this->hasManyThrough('\App\Models\Asset', '\App\Models\AssetModel', 'manufacturer_id', 'model_id');

View file

@ -50,19 +50,28 @@ class Statuslabel extends SnipeModel
*
* @var array
*/
protected $searchableRelations = [];
protected $searchableRelations = [];
/**
* Get assets with associated status label
* Establishes the status label -> assets relationship
*
* @return \Illuminate\Support\Collection
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assets()
{
return $this->hasMany('\App\Models\Asset', 'status_id');
}
/**
* Gets the status label type
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return string
*/
public function getStatuslabelType()
{
@ -78,6 +87,11 @@ class Statuslabel extends SnipeModel
}
/**
* Query builder scope to for pending status types
*
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopePending()
{
return $this->where('pending', '=', 1)
@ -85,6 +99,11 @@ class Statuslabel extends SnipeModel
->where('deployable', '=', 0);
}
/**
* Query builder scope for archived status types
*
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeArchived()
{
return $this->where('pending', '=', 0)
@ -92,6 +111,11 @@ class Statuslabel extends SnipeModel
->where('deployable', '=', 0);
}
/**
* Query builder scope for deployable status types
*
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeDeployable()
{
return $this->where('pending', '=', 0)
@ -99,7 +123,13 @@ class Statuslabel extends SnipeModel
->where('deployable', '=', 1);
}
/**
* Helper function to determine type attributes
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return string
*/
public static function getStatuslabelTypesForDB($type)
{

View file

@ -66,13 +66,30 @@ class Supplier extends SnipeModel
protected $fillable = ['name','address','address2','city','state','country','zip','phone','fax','email','contact','url','notes'];
// Eager load counts.
// We do this to eager load the "count" of seats from the controller. Otherwise calling "count()" on each model results in n+1
/**
* Eager load counts
*
* We do this to eager load the "count" of seats from the controller.
* Otherwise calling "count()" on each model results in n+1.
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assetsRelation()
{
return $this->hasMany(Asset::class)->whereNull('deleted_at')->selectRaw('supplier_id, count(*) as count')->groupBy('supplier_id');
}
/**
* Sets the license seat count attribute
*
* @todo I don't see the licenseSeatsRelation here?
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function getLicenseSeatsCountAttribute()
{
if ($this->licenseSeatsRelation->first()) {
@ -81,21 +98,50 @@ class Supplier extends SnipeModel
return 0;
}
/**
* Establishes the supplier -> assets relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assets()
{
return $this->hasMany('\App\Models\Asset', 'supplier_id');
}
/**
* Establishes the supplier -> accessories relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function accessories()
{
return $this->hasMany('\App\Models\Accessory', 'supplier_id');
}
/**
* Establishes the supplier -> asset maintenances relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function asset_maintenances()
{
return $this->hasMany('\App\Models\AssetMaintenance', 'supplier_id');
}
/**
* Return the number of assets by supplier
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return int
*/
public function num_assets()
{
if ($this->assetsRelation->first()) {
@ -105,16 +151,39 @@ class Supplier extends SnipeModel
return 0;
}
/**
* Establishes the supplier -> license relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function licenses()
{
return $this->hasMany('\App\Models\License', 'supplier_id');
}
/**
* Return the number of licenses by supplier
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return int
*/
public function num_licenses()
{
return $this->licenses()->count();
}
/**
* Add http to the url in suppliers if the user didn't give one
*
* @todo this should be handled via validation, no?
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function addhttp($url)
{
if (!preg_match("~^(?:f|ht)tps?://~i", $url)) {

View file

@ -1,14 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Throttle extends Model
{
protected $table = 'throttle';
public function user()
{
return $this->belongsTo('User', 'user_id');
}
}

View file

@ -100,8 +100,18 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
'department' => ['name'],
'groups' => ['name'],
'manager' => ['first_name', 'last_name', 'username']
];
];
/**
* Check user permissions
*
* Parses the user and group permission masks to see if the user
* is authorized to do the thing
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return boolean
*/
public function hasAccess($section)
{
if ($this->isSuperUser()) {
@ -136,6 +146,13 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
return false;
}
/**
* Checks if the user is a SuperUser
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return boolean
*/
public function isSuperUser()
{
if (!$user_permissions = json_decode($this->permissions, true)) {
@ -158,26 +175,63 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
}
/**
* Establishes the user -> company relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function company()
{
return $this->belongsTo('\App\Models\Company', 'company_id');
}
/**
* Establishes the user -> department relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function department()
{
return $this->belongsTo('\App\Models\Department', 'department_id');
}
/**
* Checks activated status
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return boolean
*/
public function isActivated()
{
return $this->activated ==1;
}
/**
* Returns the full name attribute
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return string
*/
public function getFullNameAttribute()
{
return $this->first_name . " " . $this->last_name;
}
/**
* Returns the complete name attribute with username
*
* @todo refactor this so it's less repetitive and dumb
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return string
*/
public function getCompleteNameAttribute()
{
return $this->last_name . ", " . $this->first_name . " (" . $this->username . ")";
@ -198,7 +252,11 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
/**
* Get assets assigned to this user
* Establishes the user -> assets relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assets()
{
@ -206,7 +264,14 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
}
/**
* Get assets assigned to this user
* Establishes the user -> maintenances relationship
*
* This would only be used to return maintenances that this user
* created.
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assetmaintenances()
{
@ -214,7 +279,11 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
}
/**
* Get accessories assigned to this user
* Establishes the user -> accessories relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function accessories()
{
@ -222,7 +291,11 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
}
/**
* Get consumables assigned to this user
* Establishes the user -> consumables relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function consumables()
{
@ -230,7 +303,11 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
}
/**
* Get licenses assigned to this user
* Establishes the user -> license seats relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function licenses()
{
@ -238,78 +315,105 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
}
/**
* Get action logs for this user
* Establishes the user -> actionlogs relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function userlog()
{
return $this->hasMany('\App\Models\Actionlog', 'target_id')->orderBy('created_at', 'DESC')->withTrashed();
}
/**
* Establishes the user -> location relationship
*
* Get the asset's location based on the assigned user
* @todo - this should be removed once we're sure we've switched it
* to location()
**/
*
* @todo - this should be removed once we're sure we've switched it to location()
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function userloc()
{
return $this->belongsTo('\App\Models\Location', 'location_id')->withTrashed();
}
/**
* Get the asset's location based on the assigned user
**/
* Establishes the user -> location relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function location()
{
return $this->belongsTo('\App\Models\Location', 'location_id')->withTrashed();
}
/**
* Get the user's manager based on the assigned user
**/
* Establishes the user -> manager relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function manager()
{
return $this->belongsTo('\App\Models\User', 'manager_id')->withTrashed();
}
/**
* Get any locations the user manages.
**/
* Establishes the user -> managed locations relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function managedLocations()
{
return $this->hasMany('\App\Models\Location', 'manager_id')->withTrashed();
}
/**
* Get user groups
* Establishes the user -> groups relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v1.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function groups()
{
return $this->belongsToMany('\App\Models\Group', 'users_groups');
}
public function accountStatus()
{
if ($this->throttle) {
if ($this->throttle->suspended==1) {
return 'suspended';
} elseif ($this->throttle->banned==1) {
return 'banned';
} else {
return false;
}
} else {
return false;
}
}
/**
* Establishes the user -> assets relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v4.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assetlog()
{
return $this->hasMany('\App\Models\Asset', 'id')->withTrashed();
}
/**
* Get uploads for this asset
* Establishes the user -> uploads relationship
*
* @todo I don't think we use this?
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function uploads()
{
@ -321,28 +425,54 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
}
/**
* Fetch Items User has requested
* Establishes the user -> requested assets relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function checkoutRequests()
{
return $this->belongsToMany(Asset::class, 'checkout_requests', 'user_id', 'requestable_id')->whereNull('canceled_at');
}
public function throttle()
{
return $this->hasOne('\App\Models\Throttle');
}
/**
* Query builder scope to return deleted users
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
*
* @param string $query
* @return \Illuminate\Database\Query\Builder
*/
public function scopeGetDeleted($query)
{
return $query->withTrashed()->whereNotNull('deleted_at');
}
/**
* Query builder scope to return NOT-deleted users
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
*
* @param string $query
* @return \Illuminate\Database\Query\Builder
*/
public function scopeGetNotDeleted($query)
{
return $query->whereNull('deleted_at');
}
/**
* Query builder scope to return users by email or username
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
*
* @param string $query
* @param string $user_username
* @param string $user_email
* @return \Illuminate\Database\Query\Builder
*/
public function scopeMatchEmailOrUsername($query, $user_username, $user_email)
{
return $query->where('email', '=', $user_email)
@ -350,6 +480,15 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
->orWhere('username', '=', $user_email);
}
/**
* Generate email from full name
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
*
* @param string $query
* @return string
*/
public static function generateEmailFromFullName($name)
{
$username = User::generateFormattedNameFromFullName($name, Setting::getSettings()->email_format);
@ -422,9 +561,9 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
/**
* Run additional, advanced searches.
*
* @param Illuminate\Database\Eloquent\Builder $query
* @param array $term The search terms
* @return Illuminate\Database\Eloquent\Builder
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param array $terms The search terms
* @return \Illuminate\Database\Eloquent\Builder
*/
public function advancedTextSearch(Builder $query, array $terms) {
@ -435,7 +574,13 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
return $query;
}
/**
* Query builder scope to return users by group
*
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param int $id
* @return \Illuminate\Database\Query\Builder
*/
public function scopeByGroup($query, $id) {
return $query->whereHas('groups', function ($query) use ($id) {
$query->where('groups.id', '=', $id);
@ -445,9 +590,8 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
/**
* Query builder scope for Deleted users
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeDeleted($query)
@ -459,10 +603,10 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
/**
* Query builder scope to order on manager
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param string $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderManager($query, $order)
{
@ -473,10 +617,10 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
/**
* Query builder scope to order on company
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param string $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderLocation($query, $order)
{
@ -487,10 +631,10 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
/**
* Query builder scope to order on department
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param string $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderDepartment($query, $order)
{

View file

@ -34,7 +34,7 @@ class CategoryTest extends BaseTest
$category = $this->createValidCategory('asset-desktop-category');
$models = factory(App\Models\AssetModel::class, 5)->states('mbp-13-model')->create(['category_id' => $category->id]);
$this->assertEquals(5, $category->has_models());
$this->assertEquals(5, $category->models->count());
$this->assertCount(5, $category->models);
$models->each(function($model) {

View file

@ -32,7 +32,7 @@ class DepreciationTest extends BaseTest
$this->createValidAssetModel();
$depreciation = $this->createValidDepreciation('computer', ['name' => 'New Depreciation']);
$models = factory(App\Models\AssetModel::class, 5)->states('mbp-13-model')->create(['depreciation_id'=>$depreciation->id]);
$this->assertEquals(5,$depreciation->has_models());
$this->assertEquals(5,$depreciation->models->count());
}
public function testADepreciationHasLicenses()