Merge branch 'develop' of github.com:snipe/snipe-it into develop

This commit is contained in:
snipe 2017-10-01 14:33:02 -07:00
commit abe19a6311
36 changed files with 712 additions and 747 deletions

View file

@ -43,7 +43,7 @@ before_script:
# use the $DB env variable to determine the phpunit.xml to use # use the $DB env variable to determine the phpunit.xml to use
# script: ./vendor/bin/codecept run --env testing-ci # script: ./vendor/bin/codecept run --env testing-ci
script: script:
- ./vendor/bin/codecept run unit --env testing-ci - ./vendor/bin/codecept run unit
# - ./vendor/bin/codecept run acceptance --env=testing-ci # - ./vendor/bin/codecept run acceptance --env=testing-ci
- ./vendor/bin/codecept run functional --env=functional-travis - ./vendor/bin/codecept run functional --env=functional-travis
#script: ./vendor/bin/codecept run #script: ./vendor/bin/codecept run

View file

@ -23,7 +23,7 @@ class LocationsController extends Controller
$allowed_columns = ['id','name','address','address2','city','state','country','zip','created_at', $allowed_columns = ['id','name','address','address2','city','state','country','zip','created_at',
'updated_at','parent_id', 'manager_id']; 'updated_at','parent_id', 'manager_id'];
$locations = Location::select([ $locations = Location::with('parent', 'manager', 'childLocations')->select([
'locations.id', 'locations.id',
'locations.name', 'locations.name',
'locations.address', 'locations.address',
@ -37,7 +37,10 @@ class LocationsController extends Controller
'locations.created_at', 'locations.created_at',
'locations.updated_at', 'locations.updated_at',
'locations.currency' 'locations.currency'
])->withCount('assets')->withCount('users'); ])->withCount('locationAssets')
->withCount('assignedAssets')
->withCount('assets')
->withCount('users');
if ($request->has('search')) { if ($request->has('search')) {
$locations = $locations->TextSearch($request->input('search')); $locations = $locations->TextSearch($request->input('search'));
@ -52,7 +55,6 @@ class LocationsController extends Controller
$total = $locations->count(); $total = $locations->count();
$locations = $locations->skip($offset)->take($limit)->get(); $locations = $locations->skip($offset)->take($limit)->get();
return (new LocationsTransformer)->transformLocations($locations, $total); return (new LocationsTransformer)->transformLocations($locations, $total);
} }
@ -74,7 +76,6 @@ class LocationsController extends Controller
return response()->json(Helper::formatStandardApiResponse('success', (new LocationsTransformer)->transformLocation($location), trans('admin/locations/message.create.success'))); return response()->json(Helper::formatStandardApiResponse('success', (new LocationsTransformer)->transformLocation($location), trans('admin/locations/message.create.success')));
} }
return response()->json(Helper::formatStandardApiResponse('error', null, $location->getErrors())); return response()->json(Helper::formatStandardApiResponse('error', null, $location->getErrors()));
} }
/** /**
@ -109,7 +110,13 @@ class LocationsController extends Controller
$location->fill($request->all()); $location->fill($request->all());
if ($location->save()) { if ($location->save()) {
return response()->json(Helper::formatStandardApiResponse('success', (new LocationsTransformer)->transformLocation($location), trans('admin/locations/message.update.success'))); return response()->json(
Helper::formatStandardApiResponse(
'success',
(new LocationsTransformer)->transformLocation($location),
trans('admin/locations/message.update.success')
)
);
} }
return response()->json(Helper::formatStandardApiResponse('error', null, $location->getErrors())); return response()->json(Helper::formatStandardApiResponse('error', null, $location->getErrors()));
@ -130,6 +137,5 @@ class LocationsController extends Controller
$this->authorize('delete', $location); $this->authorize('delete', $location);
$location->delete(); $location->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/locations/message.delete.success'))); return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/locations/message.delete.success')));
} }
} }

View file

@ -94,7 +94,6 @@ class AssetsController extends Controller
} }
$this->authorize('view', $asset); $this->authorize('view', $asset);
return redirect()->route('hardware.show', $asset->id)->with('topsearch', $topsearch); return redirect()->route('hardware.show', $asset->id)->with('topsearch', $topsearch);
} }
/** /**
@ -126,9 +125,7 @@ class AssetsController extends Controller
if ($request->has('model_id')) { if ($request->has('model_id')) {
$selected_model = AssetModel::find($request->input('model_id')); $selected_model = AssetModel::find($request->input('model_id'));
$view->with('selected_model', $selected_model); $view->with('selected_model', $selected_model);
} else {
} }
return $view; return $view;
} }
@ -168,7 +165,6 @@ class AssetsController extends Controller
// Create the image (if one was chosen.) // Create the image (if one was chosen.)
if (Input::has('image')) { if (Input::has('image')) {
$image = Input::get('image'); $image = Input::get('image');
// After modification, the image is prefixed by mime info like the following: // After modification, the image is prefixed by mime info like the following:
@ -201,7 +197,6 @@ class AssetsController extends Controller
->put('default', $messageBag)); ->put('default', $messageBag));
return response()->json(['image' => $e->getMessage()], 422); return response()->json(['image' => $e->getMessage()], 422);
} }
} }
@ -211,20 +206,15 @@ class AssetsController extends Controller
// Need to investigate and fix. Using static method for now. // Need to investigate and fix. Using static method for now.
$model = AssetModel::find($request->get('model_id')); $model = AssetModel::find($request->get('model_id'));
if ($model->fieldset) { if ($model->fieldset) {
foreach ($model->fieldset->fields as $field) { foreach ($model->fieldset->fields as $field) {
if ($field->field_encrypted=='1') { if ($field->field_encrypted=='1') {
if (Gate::allows('admin')) { if (Gate::allows('admin')) {
$asset->{$field->convertUnicodeDbSlug()} = \Crypt::encrypt($request->input($field->convertUnicodeDbSlug())); $asset->{$field->convertUnicodeDbSlug()} = \Crypt::encrypt($request->input($field->convertUnicodeDbSlug()));
} }
} else { } else {
$asset->{$field->convertUnicodeDbSlug()} = $request->input($field->convertUnicodeDbSlug()); $asset->{$field->convertUnicodeDbSlug()} = $request->input($field->convertUnicodeDbSlug());
} }
} }
} }
@ -291,7 +281,6 @@ class AssetsController extends Controller
public function update(AssetRequest $request, $assetId = null) public function update(AssetRequest $request, $assetId = null)
{ {
// Check if the asset exists // Check if the asset exists
if (!$asset = Asset::find($assetId)) { if (!$asset = Asset::find($assetId)) {
// Redirect to the asset management page with error // Redirect to the asset management page with error
@ -369,7 +358,6 @@ class AssetsController extends Controller
if (Gate::allows('admin')) { if (Gate::allows('admin')) {
$asset->{$field->convertUnicodeDbSlug()} = \Crypt::encrypt(e($request->input($field->convertUnicodeDbSlug()))); $asset->{$field->convertUnicodeDbSlug()} = \Crypt::encrypt(e($request->input($field->convertUnicodeDbSlug())));
} }
} else { } else {
$asset->{$field->convertUnicodeDbSlug()} = $request->input($field->convertUnicodeDbSlug()); $asset->{$field->convertUnicodeDbSlug()} = $request->input($field->convertUnicodeDbSlug());
} }
@ -385,7 +373,6 @@ class AssetsController extends Controller
\Input::flash(); \Input::flash();
\Session::flash('errors', $asset->getErrors()); \Session::flash('errors', $asset->getErrors());
return response()->json(['errors' => $asset->getErrors()], 500); return response()->json(['errors' => $asset->getErrors()], 500);
} }
/** /**
@ -447,7 +434,6 @@ class AssetsController extends Controller
->with('users_list', Helper::usersList()) ->with('users_list', Helper::usersList())
->with('assets_list', Helper::assetsList()) ->with('assets_list', Helper::assetsList())
->with('locations_list', Helper::locationsList()); ->with('locations_list', Helper::locationsList());
} }
/** /**
@ -519,7 +505,6 @@ class AssetsController extends Controller
$this->authorize('checkin', $asset); $this->authorize('checkin', $asset);
return view('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto); return view('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto);
} }
@ -583,7 +568,7 @@ class AssetsController extends Controller
} }
if ($backto=='user') { if ($backto=='user') {
return redirect()->to("admin/users/".$user->id.'/view')->with('success', trans('admin/hardware/message.checkin.success')); return redirect()->route("users.show", $user->id)->with('success', trans('admin/hardware/message.checkin.success'));
} }
return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.checkin.success')); return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.checkin.success'));
} }
@ -607,15 +592,16 @@ class AssetsController extends Controller
$asset = Asset::withTrashed()->find($assetId); $asset = Asset::withTrashed()->find($assetId);
$this->authorize('view', $asset); $this->authorize('view', $asset);
$settings = Setting::getSettings(); $settings = Setting::getSettings();
$audit_log = Actionlog::where('action_type','=','audit')->where('item_id','=',$assetId)->where('item_type','=',Asset::class)->orderBy('created_at','DESC')->first(); $audit_log = Actionlog::where('action_type', '=', 'audit')
->where('item_id', '=', $assetId)
->where('item_type', '=', Asset::class)
->orderBy('created_at', 'DESC')->first();
if (isset($asset)) { if (isset($asset)) {
if (!is_null($asset->assetloc)) { if (!is_null($asset->assetloc)) {
$use_currency = $asset->assetloc->currency; $use_currency = $asset->assetloc->currency;
} else { } else {
if ($settings->default_currency!='') { if ($settings->default_currency!='') {
$use_currency = $settings->default_currency; $use_currency = $settings->default_currency;
} else { } else {
@ -653,7 +639,6 @@ class AssetsController extends Controller
$qr_file = public_path().'/uploads/barcodes/qr-'.str_slug($asset->asset_tag).'-'.str_slug($asset->id).'.png'; $qr_file = public_path().'/uploads/barcodes/qr-'.str_slug($asset->asset_tag).'-'.str_slug($asset->id).'.png';
if (isset($asset->id, $asset->asset_tag)) { if (isset($asset->id, $asset->asset_tag)) {
if (file_exists($qr_file)) { if (file_exists($qr_file)) {
$header = ['Content-type' => 'image/png']; $header = ['Content-type' => 'image/png'];
return response()->file($qr_file, $header); return response()->file($qr_file, $header);
@ -665,7 +650,6 @@ class AssetsController extends Controller
} }
} }
} }
} }
@ -684,7 +668,6 @@ class AssetsController extends Controller
$barcode_file = public_path().'/uploads/barcodes/'.str_slug($settings->alt_barcode).'-'.str_slug($asset->asset_tag).'.png'; $barcode_file = public_path().'/uploads/barcodes/'.str_slug($settings->alt_barcode).'-'.str_slug($asset->asset_tag).'.png';
if (isset($asset->id, $asset->asset_tag)) { if (isset($asset->id, $asset->asset_tag)) {
if (file_exists($barcode_file)) { if (file_exists($barcode_file)) {
$header = ['Content-type' => 'image/png']; $header = ['Content-type' => 'image/png'];
return response()->file($barcode_file, $header); return response()->file($barcode_file, $header);
@ -695,7 +678,6 @@ class AssetsController extends Controller
return response($barcode_obj->getPngData())->header('Content-type', 'image/png'); return response($barcode_obj->getPngData())->header('Content-type', 'image/png');
} }
} }
} }
/** /**
@ -762,7 +744,6 @@ class AssetsController extends Controller
*/ */
public function postImportHistory(Request $request) public function postImportHistory(Request $request)
{ {
if (!ini_get("auto_detect_line_endings")) { if (!ini_get("auto_detect_line_endings")) {
ini_set("auto_detect_line_endings", '1'); ini_set("auto_detect_line_endings", '1');
} }
@ -780,9 +761,7 @@ class AssetsController extends Controller
foreach ($results as $row) { foreach ($results as $row) {
if (is_array($row)) { if (is_array($row)) {
$row = array_change_key_case($row, CASE_LOWER); $row = array_change_key_case($row, CASE_LOWER);
$asset_tag = Helper::array_smart_fetch($row, "asset tag"); $asset_tag = Helper::array_smart_fetch($row, "asset tag");
if (!array_key_exists($asset_tag, $item)) { if (!array_key_exists($asset_tag, $item)) {
@ -797,7 +776,6 @@ class AssetsController extends Controller
$item[$asset_tag][$batch_counter]['email'] = Helper::array_smart_fetch($row, "email"); $item[$asset_tag][$batch_counter]['email'] = Helper::array_smart_fetch($row, "email");
if ($asset = Asset::where('asset_tag', '=', $asset_tag)->first()) { if ($asset = Asset::where('asset_tag', '=', $asset_tag)->first()) {
$item[$asset_tag][$batch_counter]['asset_id'] = $asset->id; $item[$asset_tag][$batch_counter]['asset_id'] = $asset->id;
$base_username = User::generateFormattedNameFromFullName(Setting::getSettings()->username_format, $item[$asset_tag][$batch_counter]['name']); $base_username = User::generateFormattedNameFromFullName(Setting::getSettings()->username_format, $item[$asset_tag][$batch_counter]['name']);
@ -854,12 +832,10 @@ class AssetsController extends Controller
} else { } else {
$status['error'][]['asset'][$asset_tag]['msg'] = 'Asset and user was matched but could not be saved.'; $status['error'][]['asset'][$asset_tag]['msg'] = 'Asset and user was matched but could not be saved.';
} }
} else { } else {
$item[$asset_tag][$batch_counter]['checkedout_to'] = null; $item[$asset_tag][$batch_counter]['checkedout_to'] = null;
$status['error'][]['user'][Helper::array_smart_fetch($row, "name")]['msg'] = 'User does not exist so no checkin log was created.'; $status['error'][]['user'][Helper::array_smart_fetch($row, "name")]['msg'] = 'User does not exist so no checkin log was created.';
} }
} else { } else {
$item[$asset_tag][$batch_counter]['asset_id'] = null; $item[$asset_tag][$batch_counter]['asset_id'] = null;
$status['error'][]['asset'][$asset_tag]['msg'] = 'Asset does not exist so no match was attempted.'; $status['error'][]['asset'][$asset_tag]['msg'] = 'Asset does not exist so no match was attempted.';
@ -875,7 +851,6 @@ class AssetsController extends Controller
// Only do this if a matching user was found // Only do this if a matching user was found
if ((array_key_exists('checkedout_to', $asset_batch[$x])) && ($asset_batch[$x]['checkedout_to']!='')) { if ((array_key_exists('checkedout_to', $asset_batch[$x])) && ($asset_batch[$x]['checkedout_to']!='')) {
if (($total_in_batch > 1) && ($x < $total_in_batch) && (array_key_exists($next, $asset_batch))) { 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'); $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; $asset_batch[$x]['real_checkin'] = $checkin_date;
@ -982,7 +957,6 @@ class AssetsController extends Controller
} }
$log->delete(); $log->delete();
return redirect()->back()->with('success', trans('admin/hardware/message.deletefile.success')); return redirect()->back()->with('success', trans('admin/hardware/message.deletefile.success'));
} }
// Prepare the error message // Prepare the error message
$error = trans('admin/hardware/message.does_not_exist', compact('id')); $error = trans('admin/hardware/message.does_not_exist', compact('id'));
@ -1049,25 +1023,19 @@ class AssetsController extends Controller
if ($request->has('bulk_actions')) { if ($request->has('bulk_actions')) {
if ($request->input('bulk_actions')=='labels') { if ($request->input('bulk_actions')=='labels') {
$count = 0; $count = 0;
return view('hardware/labels') return view('hardware/labels')
->with('assets', Asset::find($asset_ids)) ->with('assets', Asset::find($asset_ids))
->with('settings', Setting::getSettings()) ->with('settings', Setting::getSettings())
->with('count', $count) ->with('count', $count)
->with('settings', ->with('settings', Setting::getSettings());
Setting::getSettings()
);
} elseif ($request->input('bulk_actions')=='delete') { } elseif ($request->input('bulk_actions')=='delete') {
$assets = Asset::with('assignedTo', 'assetloc')->find($asset_ids); $assets = Asset::with('assignedTo', 'assetloc')->find($asset_ids);
$assets->each(function ($asset) { $assets->each(function ($asset) {
$this->authorize('delete', $asset); $this->authorize('delete', $asset);
}); });
return view('hardware/bulk-delete')->with('assets', $assets); return view('hardware/bulk-delete')->with('assets', $assets);
// Bulk edit // Bulk edit
} elseif ($request->input('bulk_actions')=='edit') { } elseif ($request->input('bulk_actions')=='edit') {
return view('hardware/bulk') return view('hardware/bulk')
@ -1150,7 +1118,6 @@ class AssetsController extends Controller
DB::table('assets') DB::table('assets')
->where('id', $key) ->where('id', $key)
->update($update_array); ->update($update_array);
} // endforeach } // endforeach
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.update.success')); return redirect()->to("hardware")->with('success', trans('admin/hardware/message.update.success'));
// no values given, nothing to update // no values given, nothing to update
@ -1172,7 +1139,6 @@ class AssetsController extends Controller
{ {
$this->authorize('delete', Asset::class); $this->authorize('delete', Asset::class);
if (Input::has('ids')) { if (Input::has('ids')) {
$assets = Asset::find(Input::get('ids')); $assets = Asset::find(Input::get('ids'));
foreach ($assets as $asset) { foreach ($assets as $asset) {
@ -1182,7 +1148,6 @@ class AssetsController extends Controller
DB::table('assets') DB::table('assets')
->where('id', $asset->id) ->where('id', $asset->id)
->update($update_array); ->update($update_array);
} // endforeach } // endforeach
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.delete.success')); return redirect()->to("hardware")->with('success', trans('admin/hardware/message.delete.success'));
// no values given, nothing to update // no values given, nothing to update
@ -1286,6 +1251,4 @@ class AssetsController extends Controller
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.audit.success')); return redirect()->to("hardware")->with('success', trans('admin/hardware/message.audit.success'));
} }
} }
} }

View file

@ -519,13 +519,16 @@ class LicensesController extends Controller
//Log the upload to the log //Log the upload to the log
$license->logUpload($filename, e($request->input('notes'))); $license->logUpload($filename, e($request->input('notes')));
} }
// This being called from a modal seems to confuse redirect()->back()
// It thinks we should go to the dashboard. As this is only used
// from the modal at present, hardcode the redirect. Longterm
// maybe we evaluate something else.
if ($upload_success) { if ($upload_success) {
return redirect()->back()->with('success', trans('admin/licenses/message.upload.success')); return redirect()->route('licenses.show', $license->id)->with('success', trans('admin/licenses/message.upload.success'));
} }
return redirect()->back()->with('error', trans('admin/licenses/message.upload.error')); return redirect()->route('licenses.show', $license->id)->with('error', trans('admin/licenses/message.upload.error'));
} }
return redirect()->back()->with('error', trans('admin/licenses/message.upload.nofiles')); return redirect()->route('licenses.show', $license->id)->with('error', trans('admin/licenses/message.upload.nofiles'));
} }
// Prepare the error message // Prepare the error message
$error = trans('admin/licenses/message.does_not_exist', compact('id')); $error = trans('admin/licenses/message.does_not_exist', compact('id'));

View file

@ -29,7 +29,6 @@ class ImportsTransformer
'header_row' => $import->header_row, 'header_row' => $import->header_row,
'first_row' => $import->first_row, 'first_row' => $import->first_row,
'field_map' => $import->field_map, 'field_map' => $import->field_map,
'process_url'=> route('api.imports.importFile', $import->id),
]; ];
return $array; return $array;

View file

@ -38,8 +38,8 @@ class LocationsTransformer
'state' => e($location->state), 'state' => e($location->state),
'country' => e($location->country), 'country' => e($location->country),
'zip' => e($location->zip), 'zip' => e($location->zip),
'assets_checkedout' => $location->assets()->count(), 'assets_checkedout' => $location->location_assets_count,
'assets_default' => $location->assignedassets()->count(), 'assets_default' => $location->assigned_assets_count,
'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'), 'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($location->updated_at, 'datetime'), 'updated_at' => Helper::getFormattedDateObject($location->updated_at, 'datetime'),

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"version":3,"file":"css/AdminLTE.css","sources":[],"mappings":";;;;;;","sourceRoot":""} {"version":3,"file":"css/AdminLTE.css","sources":[],"mappings":";;;;;;A","sourceRoot":""}

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"version":3,"file":"css/app.css","sources":[],"mappings":";;;;;;;;","sourceRoot":""} {"version":3,"file":"css/app.css","sources":[],"mappings":";;;;;;;;A","sourceRoot":""}

File diff suppressed because one or more lines are too long

View file

@ -1,23 +1,12 @@
{ {
"/build/vue.js": "/build/vue.js",
"/mix.js": "/mix.js",
"/build/app.css": "/build/app.535d8af1016a2377e449920c617f0197.css",
"/build/AdminLTE.css": "/build/AdminLTE.3d8a2b2e33baa060b1b324363ad5e1c2.css",
"/build/overrides.css": "/build/overrides.617623c6a96be3e0cbd11c5d4039ec10.css",
"/css/all.css": "/css/all.css",
"/js/all.js": "/js/all.js",
"/css/app.css": "/css/app.css",
"/css/dist/all.css": "/css/dist/all.css",
"/js/dist/all.js": "/js/dist/all.js",
"/css/AdminLTE.css": "/css/AdminLTE.css",
"/css/overrides.css": "/css/overrides.css",
"/css/skin-blue.css": "/css/skin-blue.css",
"/vue.js": "/vue.js", "/vue.js": "/vue.js",
"/css/AdminLTE.css": "/css/AdminLTE.css",
"/css/app.css": "/css/app.css",
"/css/overrides.css": "/css/overrides.css",
"/vue.js.map": "/vue.js.map", "/vue.js.map": "/vue.js.map",
"/mix.js.map": "/mix.js.map",
"/css/AdminLTE.css.map": "/css/AdminLTE.css.map", "/css/AdminLTE.css.map": "/css/AdminLTE.css.map",
"/css/app.css.map": "/css/app.css.map", "/css/app.css.map": "/css/app.css.map",
"/css/overrides.css.map": "/css/overrides.css.map", "/css/overrides.css.map": "/css/overrides.css.map",
"public/css/dist/all.css": "public/css/dist/all.css", "/public/css/dist/all.css": "/public/css/dist/all.css",
"public/js/dist/all.js": "public/js/dist/all.js" "/public/js/dist/all.js": "/public/js/dist/all.js"
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -11,6 +11,8 @@
"doctrine/cache": "^1.6", "doctrine/cache": "^1.6",
"doctrine/common": "^2.7", "doctrine/common": "^2.7",
"doctrine/dbal": "v2.5.13", "doctrine/dbal": "v2.5.13",
"doctrine/inflector": "1.1.*",
"doctrine/instantiator": "1.0.*",
"erusev/parsedown": "^1.6", "erusev/parsedown": "^1.6",
"fideloper/proxy": "^3.1", "fideloper/proxy": "^3.1",
"intervention/image": "^2.3", "intervention/image": "^2.3",
@ -27,10 +29,11 @@
"schuppo/password-strength": "~1.5", "schuppo/password-strength": "~1.5",
"spatie/laravel-backup": "^3.0.0", "spatie/laravel-backup": "^3.0.0",
"tecnickcom/tc-lib-barcode": "^1.15", "tecnickcom/tc-lib-barcode": "^1.15",
"tightenco/ziggy": "^0.4.1",
"unicodeveloper/laravel-password": "^1.0", "unicodeveloper/laravel-password": "^1.0",
"watson/validating": "^3.0", "watson/validating": "^3.0",
"doctrine/instantiator": "1.0.*", "phpspec/prophecy": "1.6.2",
"doctrine/inflector": "1.2.*" "phpdocumentor/reflection-docblock": "3.2.2"
}, },
"require-dev": { "require-dev": {
"fzaninotto/faker": "~1.4", "fzaninotto/faker": "~1.4",

1064
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -255,7 +255,7 @@ return [
Laravel\Tinker\TinkerServiceProvider::class, Laravel\Tinker\TinkerServiceProvider::class,
Unicodeveloper\DumbPassword\DumbPasswordServiceProvider::class, Unicodeveloper\DumbPassword\DumbPasswordServiceProvider::class,
Schuppo\PasswordStrength\PasswordStrengthServiceProvider::class, Schuppo\PasswordStrength\PasswordStrengthServiceProvider::class,
Tightenco\Ziggy\ZiggyServiceProvider::class, // Laravel routes in vue
/* /*
* Application Service Providers... * Application Service Providers...

View file

@ -19,12 +19,14 @@ $factory->defineAs(Actionlog::class, 'asset-checkout', function (Faker\Generator
$company = factory(App\Models\Company::class)->create(); $company = factory(App\Models\Company::class)->create();
$user = factory(App\Models\User::class)->create(['company_id' => $company->id]); $user = factory(App\Models\User::class)->create(['company_id' => $company->id]);
$target = factory(App\Models\User::class)->create(['company_id' => $company->id]); $target = factory(App\Models\User::class)->create(['company_id' => $company->id]);
// $item = factory(App\Models\Asset::class)->create(['company_id' => $company->id]); do {
$item = factory(App\Models\Asset::class)->create(['company_id' => $company->id]);
} while (!$item->isValid());
// dd($item); // dd($item);
return [ return [
'user_id' => $user->id, 'user_id' => $user->id,
'action_type' => 'checkout', 'action_type' => 'checkout',
'item_id' => factory(App\Models\Asset::class)->create(['company_id' => $company->id])->id, 'item_id' => $item->id,
'item_type' => App\Models\Asset::class, 'item_type' => App\Models\Asset::class,
'target_id' => $target->id, 'target_id' => $target->id,
'target_type' => get_class($target), 'target_type' => get_class($target),

Binary file not shown.

BIN
public/js/dist/all.js vendored

Binary file not shown.

View file

@ -67,7 +67,7 @@ tr {
<script> <script>
export default { export default {
props: ['file', 'customFieldUrl'], props: ['file', 'customFields'],
data() { data() {
return { return {
activeFile: this.file, activeFile: this.file,
@ -130,14 +130,13 @@ tr {
{id: 'jobtitle', text: 'Job Title' }, {id: 'jobtitle', text: 'Job Title' },
{id: 'phone_number', text: 'Phone Number' }, {id: 'phone_number', text: 'Phone Number' },
], ],
customFields: [], customFields: this.customFields,
}, },
columnMappings: this.file.field_map || {}, columnMappings: this.file.field_map || {},
activeColumn: null, activeColumn: null,
} }
}, },
created() { created() {
this.fetchCustomFields();
window.eventHub.$on('showDetails', this.toggleExtendedDisplay) window.eventHub.$on('showDetails', this.toggleExtendedDisplay)
this.populateSelect2ActiveItems(); this.populateSelect2ActiveItems();
}, },
@ -155,21 +154,9 @@ tr {
} }
}, },
methods: { methods: {
fetchCustomFields() {
this.$http.get(this.customFieldUrl)
.then( ({data}) => {
data = data.rows;
data.forEach((item) => {
this.columnOptions.customFields.push({
'id': item.db_column_name,
'text': item.name,
})
})
});
},
postSave() { postSave() {
this.statusText = "Processing..."; this.statusText = "Processing...";
this.$http.post(this.file.process_url, { this.$http.post(route('api.imports.importFile', this.file.id), {
'import-update': this.options.update, 'import-update': this.options.update,
'import-type': this.options.importType, 'import-type': this.options.importType,
'column-mappings': this.columnMappings 'column-mappings': this.columnMappings

View file

@ -11,8 +11,6 @@ th {
<script> <script>
require('blueimp-file-upload'); require('blueimp-file-upload');
export default { export default {
props: ['importUrl'],
/* /*
* The component's data. * The component's data.
*/ */
@ -32,13 +30,15 @@ th {
currentPercent: "0", currentPercent: "0",
statusText: '', statusText: '',
visible: false visible: false
} },
customFields: [],
}; };
}, },
mounted() { mounted() {
window.eventHub.$on('importErrors', this.updateImportErrors); window.eventHub.$on('importErrors', this.updateImportErrors);
this.fetchFiles(); this.fetchFiles();
this.fetchCustomFields();
let vm = this; let vm = this;
$('#fileupload').fileupload({ $('#fileupload').fileupload({
dataType: 'json', dataType: 'json',
@ -71,7 +71,7 @@ th {
methods: { methods: {
fetchFiles() { fetchFiles() {
this.$http.get(this.importUrl) this.$http.get(route('api.imports.index'))
.then( ({data}) => this.files = data, // Success .then( ({data}) => this.files = data, // Success
//Fail //Fail
(response) => { (response) => {
@ -80,8 +80,20 @@ th {
this.alert.message="Something went wrong fetching files..."; this.alert.message="Something went wrong fetching files...";
}); });
}, },
fetchCustomFields() {
this.$http.get(route('api.customfields.index'))
.then( ({data}) => {
data = data.rows;
data.forEach((item) => {
this.customFields.push({
'id': item.db_column_name,
'text': item.name,
})
})
});
},
deleteFile(file, key) { deleteFile(file, key) {
this.$http.delete(this.importUrl+"/"+file.id) this.$http.delete(route('api.imports.destroy', file.id))
.then((response) => this.files.splice(key, 1), // Success, remove file from array. .then((response) => this.files.splice(key, 1), // Success, remove file from array.
(response) => {// Fail (response) => {// Fail
this.alert.type="danger"; this.alert.type="danger";
@ -98,7 +110,7 @@ th {
}, },
updateImportErrors(errors) { updateImportErrors(errors) {
this.importErrors = errors; this.importErrors = errors;
} },
}, },
computed: { computed: {

View file

@ -56,6 +56,7 @@
<script> <script>
export default { export default {
props: ['clientsUrl', 'tokensUrl'],
/* /*
* The component's data. * The component's data.
*/ */
@ -91,7 +92,7 @@
* Get all of the authorized tokens for the user. * Get all of the authorized tokens for the user.
*/ */
getTokens() { getTokens() {
this.$http.get('/oauth/tokens') this.$http.get(this.tokensUrl)
.then(response => { .then(response => {
this.tokens = response.data; this.tokens = response.data;
}); });
@ -101,7 +102,7 @@
* Revoke the given token. * Revoke the given token.
*/ */
revoke(token) { revoke(token) {
this.$http.delete('/oauth/tokens/' + token.id) this.$http.delete(this.tokensUrl +'/'+ token.id)
.then(response => { .then(response => {
this.getTokens(); this.getTokens();
}); });

View file

@ -219,6 +219,7 @@
/* /*
* The component's data. * The component's data.
*/ */
props: ['clientsUrl'],
data() { data() {
return { return {
clients: [], clients: [],
@ -271,7 +272,7 @@
* Get all of the OAuth clients for the user. * Get all of the OAuth clients for the user.
*/ */
getClients() { getClients() {
this.$http.get('/oauth/clients') this.$http.get(this.clientsUrl)
.then(response => { .then(response => {
this.clients = response.data; this.clients = response.data;
}); });
@ -289,7 +290,7 @@
*/ */
store() { store() {
this.persistClient( this.persistClient(
'post', '/oauth/clients', 'post', this.clientsUrl,
this.createForm, '#modal-create-client' this.createForm, '#modal-create-client'
); );
}, },
@ -310,7 +311,7 @@
*/ */
update() { update() {
this.persistClient( this.persistClient(
'put', '/oauth/clients/' + this.editForm.id, 'put', this.clientsUrl + '/' + this.editForm.id,
this.editForm, '#modal-edit-client' this.editForm, '#modal-edit-client'
); );
}, },
@ -319,8 +320,10 @@
* Persist the client to storage using the given form. * Persist the client to storage using the given form.
*/ */
persistClient(method, uri, form, modal) { persistClient(method, uri, form, modal) {
console.log('persisting');
form.errors = []; form.errors = [];
console.log('method: ' + method);
this.$http[method](uri, form) this.$http[method](uri, form)
.then(response => { .then(response => {
this.getClients(); this.getClients();
@ -344,7 +347,7 @@
* Destroy the given client. * Destroy the given client.
*/ */
destroy(client) { destroy(client) {
this.$http.delete('/oauth/clients/' + client.id) this.$http.delete(this.clientsUrl +'/' + client.id)
.then(response => { .then(response => {
this.getClients(); this.getClients();
}); });

View file

@ -160,6 +160,7 @@
<script> <script>
export default { export default {
props: ['tokenUrl', 'scopesUrl'],
/* /*
* The component's data. * The component's data.
*/ */
@ -209,7 +210,7 @@
* Get all of the personal access tokens for the user. * Get all of the personal access tokens for the user.
*/ */
getTokens() { getTokens() {
this.$http.get('/oauth/personal-access-tokens') this.$http.get(this.tokenUrl)
.then(response => { .then(response => {
this.tokens = response.data; this.tokens = response.data;
}); });
@ -219,7 +220,7 @@
* Get all of the available scopes. * Get all of the available scopes.
*/ */
getScopes() { getScopes() {
this.$http.get('/oauth/scopes') this.$http.get(this.scopesUrl)
.then(response => { .then(response => {
this.scopes = response.data; this.scopes = response.data;
}); });
@ -240,7 +241,7 @@
this.form.errors = []; this.form.errors = [];
this.$http.post('/oauth/personal-access-tokens', this.form) this.$http.post(this.tokenUrl, this.form)
.then(response => { .then(response => {
this.form.name = ''; this.form.name = '';
this.form.scopes = []; this.form.scopes = [];
@ -293,7 +294,7 @@
* Revoke the given token. * Revoke the given token.
*/ */
revoke(token) { revoke(token) {
this.$http.delete('/oauth/personal-access-tokens/' + token.id) this.$http.delete(this.tokenUrl +'/'+ token.id)
.then(response => { .then(response => {
this.getTokens(); this.getTokens();
}); });

View file

@ -9,7 +9,10 @@
{{-- Page content --}} {{-- Page content --}}
@section('content') @section('content')
@if (!config('app.lock_passwords')) @if (!config('app.lock_passwords'))
<passport-personal-access-tokens></passport-personal-access-tokens> <passport-personal-access-tokens
token-url="{{ url('oauth/personal-access-tokens') }}"
scopes-url="{{ url('oauth/scopes') }}">
</passport-personal-access-tokens>
@else @else
<p class="help-block">{{ trans('general.feature_disabled') }}</p> <p class="help-block">{{ trans('general.feature_disabled') }}</p>
@endif @endif

View file

@ -4,7 +4,7 @@
<p>{{ trans('mail.a_user_canceled') }} <a href="{{ url('/') }}"> {{ $snipeSettings->site_name }}</a>. </p> <p>{{ trans('mail.a_user_canceled') }} <a href="{{ url('/') }}"> {{ $snipeSettings->site_name }}</a>. </p>
<p>{{ trans('mail.user') }} <a href="{{ url('/') }}/admin/users/{{ $user_id }}/view">{{ $requested_by }}</a><br> <p>{{ trans('mail.user') }} <a href="{{ route('users.show', $user_id) }}">{{ $requested_by }}</a><br>
{{ trans('mail.item') }} <a href="{{ $item_url }}">{{ $item_name }}</a> ({{ $item_type }}) <br> {{ trans('mail.item') }} <a href="{{ $item_url }}">{{ $item_name }}</a> ({{ $item_type }}) <br>
{{ trans('mail.canceled') }} {{ $requested_date }} {{ trans('mail.canceled') }} {{ $requested_date }}
</p> </p>

View file

@ -4,7 +4,7 @@
<p>{{ trans('mail.a_user_requested') }} <a href="{{ url('/') }}"> {{ $snipeSettings->site_name }}</a>. </p> <p>{{ trans('mail.a_user_requested') }} <a href="{{ url('/') }}"> {{ $snipeSettings->site_name }}</a>. </p>
<p>{{ trans('mail.user') }} <a href="{{ url('/') }}/admin/users/{{ $user_id }}/view">{{ $requested_by }}</a><br> <p>{{ trans('mail.user') }} <a href="{{ route('users.show', $user_id) }}">{{ $requested_by }}</a><br>
{{ trans('mail.item') }} <a href="{{ $item_url }}">{{ $item_name }}</a> ({{ $item_type }}) <br> {{ trans('mail.item') }} <a href="{{ $item_url }}">{{ $item_name }}</a> ({{ $item_type }}) <br>
{{ trans('mail.requested') }} {{ $requested_date }} {{ trans('mail.requested') }} {{ $requested_date }}
@if ($item_quantity > 1) @if ($item_quantity > 1)

View file

@ -15,7 +15,7 @@
@for($i=0; $count > $i; $i++) @for($i=0; $count > $i; $i++)
<tr> <tr>
<td> <td>
<a href="{{ url('/') }}/admin/{{ $data[$i]['type'] }}/{{ $data[$i]['id'] }}/view">{{ $data[$i]['name'] }}</a> <a href="{{ route($data[$i]['type'].'.show', $data[$i]['id']) }}">{{ $data[$i]['name'] }}</a>
</td> </td>
<td>{{ $data[$i]['type'] }}</td> <td>{{ $data[$i]['type'] }}</td>
<td>{{ $data[$i]['remaining'] }}</td> <td>{{ $data[$i]['remaining'] }}</td>

View file

@ -16,7 +16,7 @@
{{-- Page content --}} {{-- Page content --}}
@section('content') @section('content')
<div id="app"> <div id="app">
<importer inline-template import-url="{{route('api.imports.index')}}" v-cloak> <importer inline-template v-cloak>
<div class="row"> <div class="row">
<alert v-show="alert.visible" :alert-type="alert.type" v-on:hide="alert.visible = false">@{{ alert.message }}</alert> <alert v-show="alert.visible" :alert-type="alert.type" v-on:hide="alert.visible = false">@{{ alert.message }}</alert>
<errors :errors="importErrors"></errors> <errors :errors="importErrors"></errors>
@ -65,7 +65,7 @@
<import-file <import-file
:key="currentFile.id" :key="currentFile.id"
:file="currentFile" :file="currentFile"
customFieldUrl="{{route('api.customfields.index')}}" :custom-fields="customFields"
@alert="updateAlert(alert)"> @alert="updateAlert(alert)">
</import-file> </import-file>
</template> </template>

View file

@ -31,8 +31,6 @@
window.Laravel = { csrfToken: '{{ csrf_token() }}' }; window.Laravel = { csrfToken: '{{ csrf_token() }}' };
</script> </script>
<style nonce="{{ csrf_token() }}"> <style nonce="{{ csrf_token() }}">
@if ($snipeSettings) @if ($snipeSettings)
@if ($snipeSettings->header_color) @if ($snipeSettings->header_color)
@ -68,8 +66,6 @@
} }
</style> </style>
<script nonce="{{ csrf_token() }}"> <script nonce="{{ csrf_token() }}">
window.snipeit = { window.snipeit = {
settings: { settings: {
@ -77,7 +73,8 @@
} }
}; };
</script> </script>
<!-- Add laravel route sinto javascript Primarily useful for vue.-->
@routes
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]> <!--[if lt IE 9]>

View file

@ -14,8 +14,8 @@
@section('content') @section('content')
@if (!config('app.lock_passwords')) @if (!config('app.lock_passwords'))
<div id="app"> <div id="app">
<passport-clients></passport-clients> <passport-clients clients-url="{{ url('oauth/clients') }}"></passport-clients>
<passport-authorized-clients></passport-authorized-clients> <passport-authorized-clients clients-url="{{ url('oauth/clients') }}" tokens-url="{{ url('oauth/tokens') }}"></passport-authorized-clients>
</div> </div>
@else @else
<p class="help-block">{{ trans('general.feature_disabled') }}</p> <p class="help-block">{{ trans('general.feature_disabled') }}</p>

View file

@ -1,8 +1,8 @@
-- MySQL dump 10.13 Distrib 5.7.18, for Linux (x86_64) -- MySQL dump 10.13 Distrib 5.7.19, for Linux (x86_64)
-- --
-- Host: localhost Database: snipeittests -- Host: localhost Database: snipeittests
-- ------------------------------------------------------ -- ------------------------------------------------------
-- Server version 5.7.18-0ubuntu0.16.10.1 -- Server version 5.7.19-0ubuntu0.17.04.1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
@ -1347,7 +1347,7 @@ CREATE TABLE `users` (
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `users_activation_code_index` (`activation_code`), KEY `users_activation_code_index` (`activation_code`),
KEY `users_reset_password_code_index` (`reset_password_code`) KEY `users_reset_password_code_index` (`reset_password_code`)
) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; ) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
-- --
@ -1392,4 +1392,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2017-05-22 20:08:33 -- Dump completed on 2017-10-01 15:36:56

View file

@ -1,10 +1,16 @@
<?php <?php
namespace Helper; namespace Helper;
use Illuminate\Support\Facades\Artisan;
// here you can define custom actions // here you can define custom actions
// all public methods declared in helper class will be available in $I // all public methods declared in helper class will be available in $I
class Api extends \Codeception\Module class Api extends \Codeception\Module
{ {
public function setupDatabase()
{
Artisan::call('migrate');
Artisan::call('db:seed');
}
} }

View file

@ -11,3 +11,4 @@ modules:
environment_file: .env.testing environment_file: .env.testing
disable_middleware: true disable_middleware: true
cleanup: true cleanup: true

View file

@ -9,15 +9,16 @@ class ApiAssetsCest
public function _before(ApiTester $I) public function _before(ApiTester $I)
{ {
$I->setupDatabase();
$this->faker = \Faker\Factory::create(); $this->faker = \Faker\Factory::create();
$this->user = \App\Models\User::find(1); $this->user = \App\Models\User::find(1);
$I->amBearerAuthenticated($I->getToken($this->user)); $I->amBearerAuthenticated($I->getToken($this->user));
} }
/** @test */ /** @test */
public function indexAssets(ApiTester $I) public function indexAssets(ApiTester $I)
{ {
$I->wantTo('Get a list of assets'); $I->wantTo('Get a list of assets');
// setup // setup