mirror of
https://github.com/snipe/snipe-it.git
synced 2025-01-03 09:57:45 -08:00
Merge branch 'develop'
# Conflicts: # config/version.php
This commit is contained in:
commit
b934d2e504
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api;
|
|||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\AssetRequest;
|
||||
use App\Http\Requests\AssetCheckoutRequest;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
|
@ -506,7 +507,7 @@ class AssetsController extends Controller
|
|||
* @since [v4.0]
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function checkout(Request $request, $asset_id)
|
||||
public function checkout(AssetCheckoutRequest $request, $asset_id)
|
||||
{
|
||||
$this->authorize('checkout', Asset::class);
|
||||
$asset = Asset::findOrFail($asset_id);
|
||||
|
@ -522,27 +523,37 @@ class AssetsController extends Controller
|
|||
'id' => $asset->id,
|
||||
'asset_tag' => $asset->asset_tag,
|
||||
];
|
||||
if ($request->has('user_id')) {
|
||||
$target = User::find($request->input('user_id'));
|
||||
$location = $target->location_id;
|
||||
$error_payload['target_id'] = $request->input('user_id');
|
||||
$error_payload['target_type'] = User::class;
|
||||
// Don't let the user check an asset out to itself
|
||||
} elseif ($request->has('asset_id')) {
|
||||
$target = Asset::where('id','!=',$asset_id)->find($request->input('asset_id'));
|
||||
$location = $target->location_id;
|
||||
$error_payload['target_id'] = $request->input('asset_id');
|
||||
$error_payload['target_type'] = Asset::class;
|
||||
} elseif ($request->has('location_id')) {
|
||||
$target = Location::find($request->input('location_id'));
|
||||
$location = $target->id;
|
||||
$target = Location::find($request->input('location_id'));
|
||||
$error_payload['target_id'] = $request->input('location_id');
|
||||
$error_payload['target_type'] = Location::class;
|
||||
|
||||
|
||||
// This item is checked out to a location
|
||||
if (request('checkout_to_type')=='location') {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
$asset->location_id = ($target) ? $target->id : '';
|
||||
$error_payload['target_id'] = $request->input('assigned_location');
|
||||
$error_payload['target_type'] = 'location';
|
||||
|
||||
} elseif (request('checkout_to_type')=='asset') {
|
||||
$target = Asset::where('id','!=',$assetId)->find(request('assigned_asset'));
|
||||
$asset->location_id = $target->rtd_location_id;
|
||||
// Override with the asset's location_id if it has one
|
||||
if ($target->location_id!='') {
|
||||
$asset->location_id = ($target) ? $target->location_id : '';
|
||||
}
|
||||
$error_payload['target_id'] = $request->input('assigned_asset');
|
||||
$error_payload['target_type'] = 'asset';
|
||||
|
||||
} elseif (request('checkout_to_type')=='user') {
|
||||
// Fetch the target and set the asset's new location_id
|
||||
$target = User::find(request('assigned_user'));
|
||||
$asset->location_id = ($target) ? $target->location_id : '';
|
||||
$error_payload['target_id'] = $request->input('assigned_user');
|
||||
$error_payload['target_type'] = 'user';
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!isset($target)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', $error_payload, 'No valid checkout target specified for asset '.e($asset->asset_tag).'.'));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', $error_payload, 'Checkout target for asset '.e($asset->asset_tag).' is invalid - '.$error_payload['target_type'].' does not exist.'));
|
||||
}
|
||||
|
||||
|
||||
|
@ -557,11 +568,11 @@ class AssetsController extends Controller
|
|||
$asset->location_id = $target->rtd_location_id;
|
||||
}
|
||||
|
||||
$asset->location_id = $location;
|
||||
|
||||
|
||||
|
||||
|
||||
if ($asset->checkOut($target, Auth::user(), $checkout_at, $expected_checkin, $note, $asset_name, $location)) {
|
||||
if ($asset->checkOut($target, Auth::user(), $checkout_at, $expected_checkin, $note, $asset_name, $asset->location_id)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkout.success')));
|
||||
}
|
||||
|
||||
|
|
|
@ -431,8 +431,13 @@ class AssetsController extends Controller
|
|||
|
||||
$this->authorize('checkout', $asset);
|
||||
|
||||
if ($asset->availableForCheckout()) {
|
||||
return view('hardware/checkout', compact('asset'));
|
||||
}
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkout.not_available'));
|
||||
|
||||
// Get the dropdown of users and then pass it to the checkout view
|
||||
return view('hardware/checkout', compact('asset'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -454,11 +459,13 @@ class AssetsController extends Controller
|
|||
}
|
||||
$this->authorize('checkout', $asset);
|
||||
$admin = Auth::user();
|
||||
|
||||
|
||||
|
||||
// This item is checked out to a location
|
||||
if (request('checkout_to_type')=='location') {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
$asset->location_id = ($target) ? $target->id : '';
|
||||
|
||||
} elseif (request('checkout_to_type')=='asset') {
|
||||
$target = Asset::where('id','!=',$assetId)->find(request('assigned_asset'));
|
||||
$asset->location_id = $target->rtd_location_id;
|
||||
|
@ -466,16 +473,16 @@ class AssetsController extends Controller
|
|||
if ($target->location_id!='') {
|
||||
$asset->location_id = ($target) ? $target->location_id : '';
|
||||
}
|
||||
} else {
|
||||
|
||||
} elseif (request('checkout_to_type')=='user') {
|
||||
// Fetch the target and set the asset's new location_id
|
||||
$target = User::find(request('assigned_user'));
|
||||
$asset->location_id = ($target) ? $target->location_id : '';
|
||||
}
|
||||
|
||||
|
||||
// No valid target was found - error out
|
||||
if (!$target) {
|
||||
return redirect()->to("hardware/$assetId/checkout")->with('error', trans('admin/hardware/message.checkout.error'))->withErrors($asset->getErrors());
|
||||
return redirect()->back()->with('error', trans('admin/hardware/message.checkout.error'))->withErrors($asset->getErrors());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,9 +24,10 @@ class AssetCheckoutRequest extends Request
|
|||
public function rules()
|
||||
{
|
||||
$rules = [
|
||||
"assigned_user" => 'required_without_all:assigned_asset,assigned_location',
|
||||
"assigned_asset" => 'required_without_all:assigned_user,assigned_location|different:'.$this->id,
|
||||
"assigned_location" => 'required_without_all:assigned_user,assigned_asset',
|
||||
"assigned_user" => 'required_without_all:assigned_asset,assigned_location',
|
||||
"assigned_asset" => 'required_without_all:assigned_user,assigned_location|different:'.$this->id,
|
||||
"assigned_location" => 'required_without_all:assigned_user,assigned_asset',
|
||||
"checkout_to_type" => 'required|in:asset,location,user'
|
||||
];
|
||||
|
||||
|
||||
|
|
|
@ -16,12 +16,17 @@ class CustomField extends Model
|
|||
public static $PredefinedFormats=[
|
||||
"ANY" => "",
|
||||
"ALPHA" => "alpha",
|
||||
"ALPHA-DASH" => "alpha_dash",
|
||||
"NUMERIC" => "numeric",
|
||||
"ALPHA-NUMERIC" => "alpha_num",
|
||||
"EMAIL" => "email",
|
||||
"DATE" => "date",
|
||||
"URL" => "url",
|
||||
"NUMERIC" => "numeric",
|
||||
"MAC" => "regex:/^[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}$/",
|
||||
"IP" => "ip",
|
||||
"IPV4" => "ipv4",
|
||||
"IPV6" => "ipv6",
|
||||
"MAC" => "regex:/^[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}$/",
|
||||
"BOOLEAN" => "boolean",
|
||||
];
|
||||
|
||||
public $rules = [
|
||||
|
@ -30,27 +35,54 @@ class CustomField extends Model
|
|||
|
||||
// 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
|
||||
// say that here, otherwise the new fields get added onto the custom fields
|
||||
// table instead of the assets table.
|
||||
public static $table_name = "assets";
|
||||
|
||||
|
||||
/**
|
||||
* Convert the custom field's name property to a db-safe string.
|
||||
*
|
||||
* We could probably have used str_slug() here but not sure what it would
|
||||
* do with previously existing values. - @snipe
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.4]
|
||||
* @return String
|
||||
*/
|
||||
public static function name_to_db_name($name)
|
||||
{
|
||||
return "_snipeit_" . preg_replace("/[^a-zA-Z0-9]/", "_", strtolower($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set some boot methods for creating and updating.
|
||||
*
|
||||
* There is never ever a time when we wouldn't want to be updating those asset
|
||||
* column names and the values of the db column name in the custom fields table
|
||||
* if they have changed, so we handle that here so that we don't have to remember
|
||||
* to do it in the controllers.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.4]
|
||||
* @return Boolean
|
||||
*/
|
||||
public static function boot()
|
||||
{
|
||||
self::created(function ($custom_field) {
|
||||
|
||||
// column exists - nothing to do here
|
||||
// Column already exists on the assets table - nothing to do here.
|
||||
// This *shouldn't* happen in the wild.
|
||||
if (Schema::hasColumn(CustomField::$table_name, $custom_field->convertUnicodeDbSlug())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update the column name in the assets table
|
||||
Schema::table(CustomField::$table_name, function ($table) use ($custom_field) {
|
||||
$table->text($custom_field->convertUnicodeDbSlug())->nullable();
|
||||
});
|
||||
|
||||
// Update the db_column property in the custom fields table
|
||||
$custom_field->db_column = $custom_field->convertUnicodeDbSlug();
|
||||
$custom_field->save();
|
||||
});
|
||||
|
@ -58,8 +90,9 @@ class CustomField extends Model
|
|||
|
||||
self::updating(function ($custom_field) {
|
||||
|
||||
// Column already exists. Nothing to update.
|
||||
// Column already exists on the assets table - nothing to do here.
|
||||
if ($custom_field->isDirty("name")) {
|
||||
|
||||
if (Schema::hasColumn(CustomField::$table_name, $custom_field->convertUnicodeDbSlug())) {
|
||||
return true;
|
||||
}
|
||||
|
@ -113,11 +146,22 @@ class CustomField extends Model
|
|||
return $this->db_column;
|
||||
}
|
||||
|
||||
// mutators for 'format' attribute
|
||||
/**
|
||||
* Mutator for the 'format' attribute.
|
||||
*
|
||||
* This is used by the dropdown to store the laravel-specific
|
||||
* validator strings in the database but still return the
|
||||
* user-friendly text in the dropdowns, and in the custom fields display.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.4]
|
||||
* @return Array
|
||||
*/
|
||||
public function getFormatAttribute($value)
|
||||
{
|
||||
foreach (self::$PredefinedFormats as $name => $pattern) {
|
||||
if ($pattern===$value) {
|
||||
\Log::debug($name.'=>'.$pattern);
|
||||
if ($pattern === $value) {
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
|
@ -168,6 +212,13 @@ class CustomField extends Model
|
|||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the field is encrypted
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.4]
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isFieldDecryptable($string)
|
||||
{
|
||||
if (($this->field_encrypted=='1') && ($string!='')) {
|
||||
|
@ -177,6 +228,14 @@ class CustomField extends Model
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert non-UTF-8 or weirdly encoded text into something that
|
||||
* won't break the database.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.4]
|
||||
* @return Boolean
|
||||
*/
|
||||
public function convertUnicodeDbSlug($original = null)
|
||||
{
|
||||
$name = $original ? $original : $this->name;
|
||||
|
|
|
@ -289,10 +289,8 @@ class AssetPresenter extends Presenter
|
|||
$imagePath = '';
|
||||
if ($this->image && !empty($this->image)) {
|
||||
$imagePath = $this->image;
|
||||
return 'poop';
|
||||
} elseif ($this->model && !empty($this->model->image)) {
|
||||
$imagePath = $this->model->image;
|
||||
return 'fart';
|
||||
}
|
||||
if (!empty($imagePath)) {
|
||||
return config('app.url').'/uploads/assets/'.$imagePath;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<?php
|
||||
return array (
|
||||
'app_version' => 'v4.1.6',
|
||||
'full_app_version' => 'v4.1.6 - build 2963-g83c8449',
|
||||
'app_version' => 'v4.1.6-pre',
|
||||
'full_app_version' => 'v4.1.6-pre - build 2963-g83c8449',
|
||||
'build_version' => '2963',
|
||||
'prerelease_version' => '',
|
||||
'hash_version' => 'g83c8449',
|
||||
'full_hash' => 'v4.1.5-57-g83c8449',
|
||||
'branch' => 'master',
|
||||
);
|
||||
);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
"/css/app.css.map": "/css/app.css.map?id=bdbe05e6ecd70ccfac72",
|
||||
"/css/overrides.css.map": "/css/overrides.css.map?id=898c91d4a425b01b589b",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=7c3842d2639193ac7e88",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=7e993fb3b457ccc72b3f",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=7b52ead3a55086ea1f8d",
|
||||
"/css/build/all.css": "/css/build/all.css?id=7c3842d2639193ac7e88",
|
||||
"/js/build/all.js": "/js/build/all.js?id=7e993fb3b457ccc72b3f"
|
||||
"/js/build/all.js": "/js/build/all.js?id=7b52ead3a55086ea1f8d"
|
||||
}
|
|
@ -268,7 +268,7 @@ $(document).ready(function () {
|
|||
$('#assigned_user').hide();
|
||||
$('#assigned_location').hide();
|
||||
$('.notification-callout').fadeOut();
|
||||
|
||||
|
||||
} else if (assignto_type == 'location') {
|
||||
$('#current_assets_box').fadeOut();
|
||||
$('#assigned_asset').hide();
|
||||
|
@ -276,6 +276,7 @@ $(document).ready(function () {
|
|||
$('#assigned_location').show();
|
||||
$('.notification-callout').fadeOut();
|
||||
} else {
|
||||
|
||||
$('#assigned_asset').hide();
|
||||
$('#assigned_user').show();
|
||||
$('#assigned_location').hide();
|
||||
|
@ -283,7 +284,7 @@ $(document).ready(function () {
|
|||
$('#current_assets_box').fadeIn();
|
||||
}
|
||||
$('.notification-callout').fadeIn();
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -96,7 +96,7 @@
|
|||
@endif
|
||||
|
||||
@if ($component->order_number)
|
||||
<div class="col-md-12" style="padding-bottom: 5px;"><strong>{{ trans('admin/components/general.order') }}:</strong>
|
||||
<div class="col-md-12" style="padding-bottom: 5px;"><strong>{{ trans('general.order_number') }}:</strong>
|
||||
{{ $component->order_number }} </div>
|
||||
@endif
|
||||
</div>
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
<div class="box box-default">
|
||||
<div class="box-body">
|
||||
|
||||
<!-- Name -->
|
||||
<div class="form-group {{ $errors->has('name') ? ' has-error' : '' }}">
|
||||
<label for="name" class="col-md-4 control-label">
|
||||
|
@ -71,7 +70,7 @@
|
|||
{{ trans('admin/custom_fields/general.field_format') }}
|
||||
</label>
|
||||
<div class="col-md-6 required">
|
||||
{{ Form::select("format",\App\Helpers\Helper::predefined_formats(),"ANY", array('class'=>'format select2 form-control')) }}
|
||||
{{ Form::select("format",\App\Helpers\Helper::predefined_formats(), $field->format, array('class'=>'format select2 form-control')) }}
|
||||
{!! $errors->first('format', '<span class="alert-msg"><i class="fa fa-times"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -82,10 +81,12 @@
|
|||
{{ trans('admin/custom_fields/general.field_custom_format') }}
|
||||
</label>
|
||||
<div class="col-md-6 required">
|
||||
{{ Form::text('custom_format', Input::old('custom_format', (($field->format!='') && ($field->format!='ANY')) ? $field->format : ''), array('class' => 'form-control', 'id' => 'custom_format', 'placeholder'=>'regex:/^[0-9]{15}$/')) }}
|
||||
|
||||
{{ Form::text('custom_format', Input::old('custom_format', (($field->format!='') && (stripos($field->format,'regex')===0)) ? $field->format : ''), array('class' => 'form-control', 'id' => 'custom_format', 'placeholder'=>'regex:/^[0-9]{15}$/')) }}
|
||||
<p class="help-block">{!! trans('admin/custom_fields/general.field_custom_format_help') !!}</p>
|
||||
|
||||
{!! $errors->first('custom_format', '<span class="alert-msg"><i class="fa fa-times"></i> :message</span>') !!}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -143,6 +144,7 @@
|
|||
// If the custom_regex is ever NOT the last element in the format
|
||||
// listbox, we will need to refactor this.
|
||||
if ($('#custom_format').val()!='') {
|
||||
// console.log('value is ' + $('#custom_format').val());
|
||||
$('.format').prop('selectedIndex', $('.format')[0].options.length - 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<div class="btn-group" data-toggle="buttons">
|
||||
@if ((isset($user_select)) && ($user_select!='false'))
|
||||
<label class="btn btn-default active">
|
||||
<input name="checkout_to_type" value="user" type="radio" selected><i class="fa fa-user"></i> {{ trans('general.user') }}
|
||||
<input name="checkout_to_type" value="user" type="radio" checked="checked"><i class="fa fa-user"></i> {{ trans('general.user') }}
|
||||
</label>
|
||||
@endif
|
||||
@if ((isset($asset_select)) && ($asset_select!='false'))
|
||||
|
@ -17,6 +17,8 @@
|
|||
<input name="checkout_to_type" value="location" class="active" type="radio"><i class="fa fa-map-marker"></i> {{ trans('general.location') }}
|
||||
</label>
|
||||
@endif
|
||||
|
||||
{!! $errors->first('checkout_to_type', '<span class="alert-msg"><i class="fa fa-times"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue