Compare commits

...

8 Commits

Author SHA1 Message Date
snipe 16014945b6 Merge remote-tracking branch 'origin/develop' 2016-08-16 18:23:36 -07:00
snipe 44821b9667 Fixes #2404 Only update name of asset if it isn't null. 2016-08-16 18:23:20 -07:00
snipe c5d7a1fdd6 Merge remote-tracking branch 'origin/develop' 2016-08-16 18:21:05 -07:00
snipe 29c4189419 Bumped version 2016-08-16 18:20:42 -07:00
Daniel Meltzer 7ef4f23d0f Validate that purchase_cost is a numeric value. (#2452) 2016-08-16 18:18:50 -07:00
timwsuqld 8232cefbba Fix path to snipeit-ssl.crt (#2428) 2016-08-16 13:03:55 -07:00
Daniel Meltzer a852c624d3 Fix 2347 (#2394)
* Prevent multiple checkouts of the same asset.

This adds a new method to the Asset model, availableForCheckout.
Port getDataTable to use availableForCheckout instead of doing the
check manually.

Fixes Issue #2347

* Use availableForCheckout in categories controller.  Also gate the checkin/checkout actions here.

* Use gate and availableForCheckout in manufactuers as well.
2016-08-16 13:02:42 -07:00
snipe 7edf1db101 Small tweaks to history 2016-08-12 19:03:32 -07:00
12 changed files with 85 additions and 63 deletions
+30 -30
View File
@@ -530,6 +530,8 @@ class AssetsController extends Controller
return redirect()->to('hardware')->with('error', trans('admin/hardware/message.does_not_exist'));
} elseif (!Company::isCurrentUserHasAccess($asset)) {
return redirect()->to('hardware')->with('error', trans('general.insufficient_permissions'));
} elseif (!$asset->availableForCheckout()) {
return redirect()->to('hardware')->with('error', trans('admin/hardware/message.checkout.not_available'));
}
$user = User::find(e(Input::get('assigned_to')));
@@ -1044,7 +1046,7 @@ class AssetsController extends Controller
$results = $csv->fetchAssoc();
$item = array();
$errors = array();
$status = array();
foreach($results as $row) {
@@ -1058,7 +1060,8 @@ class AssetsController extends Controller
}
$batch_counter = count($item[$asset_tag]);
$item[$asset_tag][$batch_counter]['date'] = date('Y-m-d H:i:s', strtotime(Helper::array_smart_fetch($row, "date")));
$item[$asset_tag][$batch_counter]['checkout_date'] = Carbon::parse(Helper::array_smart_fetch($row, "date"))->format('Y-m-d H:i:s');
$item[$asset_tag][$batch_counter]['asset_tag'] = Helper::array_smart_fetch($row, "asset tag");
$item[$asset_tag][$batch_counter]['name'] = Helper::array_smart_fetch($row, "name");
$item[$asset_tag][$batch_counter]['email'] = Helper::array_smart_fetch($row, "email");
@@ -1113,7 +1116,7 @@ class AssetsController extends Controller
'user_id' => Auth::user()->id,
'note' => 'Checkout imported by '.Auth::user()->fullName().' from history importer',
'checkedout_to' => $item[$asset_tag][$batch_counter]['user_id'],
'created_at' => $item[$asset_tag][$batch_counter]['date'],
'created_at' => $item[$asset_tag][$batch_counter]['checkout_date'],
'action_type' => 'checkout'
)
);
@@ -1136,36 +1139,35 @@ class AssetsController extends Controller
// Loop through and backfill the checkins
foreach ($item as $key => $asset_batch) {
$batch_counter = 0;
for($x = 0; $x < count($asset_batch); $x++) {
$total_in_batch = count($asset_batch);
for($x = 0; $x < $total_in_batch; $x++) {
$next = $x + 1;
// Only do this if a matching user was found
if ($asset_batch[$x]['checkedout_to']!='') {
$batch_counter++;
if ((count($asset_batch) != 1) && ($batch_counter < count($asset_batch))) {
$checkin_date = date('Y-m-d H:i:s',(strtotime($asset_batch[$x]['date']) + 10));
if (($total_in_batch > 1) && ($x < $total_in_batch) && (array_key_exists($next,$asset_batch))) {
$checkin_date = Carbon::parse($asset_batch[$next]['checkout_date'])->subDay(1)->format('Y-m-d H:i:s');
$asset_batch[$x]['real_checkin'] = $checkin_date;
Actionlog::firstOrCreate(array(
'asset_id' => $asset_batch[$x]['asset_id'],
'asset_type' => 'hardware',
'user_id' => Auth::user()->id,
'note' => 'Checkin imported by '.Auth::user()->fullName().' from history importer',
'user_id' => Auth::user()->id,
'note' => 'Checkin imported by ' . Auth::user()->fullName() . ' from history importer',
'checkedout_to' => null,
'created_at' => $checkin_date,
'action_type' => 'checkin'
'created_at' => $checkin_date,
'action_type' => 'checkin'
)
);
}
}
}
}
return View::make('hardware/history')->with('status',$status);
}
@@ -1725,19 +1727,17 @@ class AssetsController extends Controller
$actions = '<a href="'.route('restore/hardware', $asset->id).'" title="Restore asset" data-toggle="tooltip" class="btn btn-warning btn-sm"><i class="fa fa-recycle icon-white"></i></a>';
}
if ($asset->assetstatus) {
if (($asset->assetstatus->deployable != 0) && ($asset->deleted_at=='')) {
if (($asset->assigned_to !='') && ($asset->assigned_to > 0)) {
if (Gate::allows('assets.checkin')) {
$inout = '<a href="' . route('checkin/hardware',
$asset->id) . '" class="btn btn-primary btn-sm" title="Checkin this asset" data-toggle="tooltip">' . trans('general.checkin') . '</a>';
}
} else {
if (Gate::allows('assets.checkout')) {
$inout = '<a href="' . route('checkout/hardware',
$asset->id) . '" class="btn btn-info btn-sm" title="Checkout this asset to a user" data-toggle="tooltip">' . trans('general.checkout') . '</a>';
}
}
if (($asset->availableForCheckout()))
{
if (Gate::allows('assets.checkout')) {
$inout = '<a href="' . route('checkout/hardware',
$asset->id) . '" class="btn btn-info btn-sm" title="Checkout this asset to a user" data-toggle="tooltip">' . trans('general.checkout') . '</a>';
}
} else {
if (Gate::allows('assets.checkin')) {
$inout = '<a href="' . route('checkin/hardware',
$asset->id) . '" class="btn btn-primary btn-sm" title="Checkin this asset" data-toggle="tooltip">' . trans('general.checkin') . '</a>';
}
}
@@ -1,13 +1,14 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Helpers\Helper;
use App\Models\Category as Category;
use App\Models\Company;
use App\Models\Setting;
use Auth;
use DB;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Input;
use Lang;
use Redirect;
@@ -344,13 +345,13 @@ class CategoriesController extends Controller
$actions = '<a href="'.route('restore/hardware', $asset->id).'" class="btn btn-warning btn-sm"><i class="fa fa-recycle icon-white"></i></a>';
}
if ($asset->assetstatus) {
if ($asset->assetstatus->deployable != 0) {
if (($asset->assigned_to !='') && ($asset->assigned_to > 0)) {
$inout = '<a href="'.route('checkin/hardware', $asset->id).'" class="btn btn-primary btn-sm">'.trans('general.checkin').'</a>';
} else {
$inout = '<a href="'.route('checkout/hardware', $asset->id).'" class="btn btn-info btn-sm">'.trans('general.checkout').'</a>';
}
if ($asset->availableForCheckout()) {
if (Gate::allows('assets.checkout')) {
$inout = '<a href="'.route('checkout/hardware', $asset->id).'" class="btn btn-info btn-sm">'.trans('general.checkout').'</a>';
}
} else {
if (Gate::allows('assets.checkin')) {
$inout = '<a href="'.route('checkin/hardware', $asset->id).'" class="btn btn-primary btn-sm">'.trans('general.checkin').'</a>';
}
}
@@ -2,14 +2,15 @@
namespace App\Http\Controllers;
use App\Models\Company;
use App\Models\Manufacturer;
use App\Models\Setting;
use Auth;
use Illuminate\Support\Facades\Gate;
use Input;
use Lang;
use App\Models\Manufacturer;
use Redirect;
use App\Models\Setting;
use Str;
use View;
use Auth;
/**
* This controller handles all actions related to Manufacturers for
@@ -293,13 +294,13 @@ class ManufacturersController extends Controller
$actions = '<a href="'.route('restore/hardware', $asset->id).'" class="btn btn-warning btn-sm"><i class="fa fa-recycle icon-white"></i></a>';
}
if ($asset->assetstatus) {
if ($asset->assetstatus->deployable != 0) {
if (($asset->assigned_to !='') && ($asset->assigned_to > 0)) {
$inout = '<a href="'.route('checkin/hardware', $asset->id).'" class="btn btn-primary btn-sm">'.trans('general.checkin').'</a>';
} else {
$inout = '<a href="'.route('checkout/hardware', $asset->id).'" class="btn btn-info btn-sm">'.trans('general.checkout').'</a>';
}
if ($asset->availableForCheckout()) {
if (Gate::allows('assets.checkout')) {
$inout = '<a href="'.route('checkout/hardware', $asset->id).'" class="btn btn-info btn-sm">'.trans('general.checkout').'</a>';
}
} else {
if (Gate::allows('assets.checkin')) {
$inout = '<a href="'.route('checkin/hardware', $asset->id).'" class="btn btn-primary btn-sm">'.trans('general.checkin').'</a>';
}
}
+1
View File
@@ -37,6 +37,7 @@ class AssetRequest extends Request
'supplier_id' => 'integer',
'status' => 'integer',
'asset_tag' => 'required',
'purchase_cost' => 'numeric',
];
+6 -5
View File
@@ -22,11 +22,12 @@ class Accessory extends Model
* Accessory validation rules
*/
public $rules = array(
'name' => 'required|min:3|max:255',
'qty' => 'required|integer|min:1',
'category_id' => 'required|integer',
'company_id' => 'integer',
'min_amt' => 'integer|min:1',
'name' => 'required|min:3|max:255',
'qty' => 'required|integer|min:1',
'category_id' => 'required|integer',
'company_id' => 'integer',
'min_amt' => 'integer|min:1',
'purchase_cost' => 'numeric',
);
+19 -6
View File
@@ -55,6 +55,7 @@ class Asset extends Depreciable
'supplier_id' => 'integer',
'asset_tag' => 'required|min:1|max:255|unique_undeleted',
'status' => 'integer',
'purchase_cost' => 'numeric',
];
@@ -72,22 +73,36 @@ class Asset extends Depreciable
}
public function availableForCheckout()
{
return (
empty($this->assigned_to) &&
$this->assetstatus->deployable == 1 &&
empty($this->deleted_at)
);
}
/**
* Checkout asset
*/
public function checkOutToUser($user, $admin, $checkout_at = null, $expected_checkin = null, $note = null, $name = null)
{
if (!$user) {
return false;
}
if ($expected_checkin) {
$this->expected_checkin = $expected_checkin ;
$this->expected_checkin = $expected_checkin;
}
$this->last_checkout = $checkout_at;
$this->assigneduser()->associate($user);
$this->name = $name;
if($name != null)
{
$this->name = $name;
}
$settings = Setting::getSettings();
@@ -95,9 +110,7 @@ class Asset extends Depreciable
$this->accepted="pending";
}
if (!$user) {
return false;
}
if ($this->save()) {
+1
View File
@@ -34,6 +34,7 @@ class Component extends Model
'category_id' => 'required|integer',
'company_id' => 'integer',
'purchase_date' => 'date',
'purchase_cost' => 'numeric',
);
/**
+1
View File
@@ -29,6 +29,7 @@ class Consumable extends Model
'category_id' => 'required|integer',
'company_id' => 'integer',
'min_amt' => 'integer|min:1',
'purchase_cost' => 'numeric',
);
/**
+2 -2
View File
@@ -1,5 +1,5 @@
<?php
return array (
'app_version' => '3.3.0-beta',
'hash_version' => '3.3.0-beta-19-g7a0843e',
'app_version' => 'v3.3.0',
'hash_version' => 'v3.3.0-3-g7ef4f23',
);
+1 -1
View File
@@ -50,7 +50,7 @@
# when the CA certificates are directly appended to the server
# certificate for convinience.
#SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt
SSLCertificateChainFile /etc/ssl/private/snipeit-ssl.crt
SSLCertificateChainFile /var/lib/snipeit/ssl/snipeit-ssl.crt
# Certificate Authority (CA):
# Set the CA certificate verification path where to find CA
+2 -1
View File
@@ -52,7 +52,8 @@ return array(
'checkout' => array(
'error' => 'Asset was not checked out, please try again',
'success' => 'Asset checked out successfully.',
'user_does_not_exist' => 'That user is invalid. Please try again.'
'user_does_not_exist' => 'That user is invalid. Please try again.',
'not_available' => 'That asset is not available for checkout!'
),
'checkin' => array(
@@ -38,6 +38,8 @@
<p><strong>Date</strong> should be the checkout date. <strong>Tag</strong> should be the asset tag. <strong>Name</strong> should be the user's name (firstname lastname).</p>
<p><strong>History should be ordered by date in ascending order.</strong></p>
<div class="form-group">
<label for="first_name" class="col-sm-3 control-label">{{ trans('admin/users/general.usercsv') }}</label>
<div class="col-sm-9">