diff --git a/.all-contributorsrc b/.all-contributorsrc
index 4b205114c..37d93b9ed 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -829,6 +829,15 @@
"test",
"code"
]
+ },
+ {
+ "login": "Gelob",
+ "name": "Ryan",
+ "avatar_url": "https://avatars3.githubusercontent.com/u/422752?v=4",
+ "profile": "https://github.com/Gelob",
+ "contributions": [
+ "doc"
+ ]
}
]
}
diff --git a/README.md b/README.md
index 0e6326a45..dff4a3481 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
[](https://travis-ci.org/snipe/snipe-it) [](http://waffle.io/snipe/snipe-it) []() [](https://crowdin.com/project/snipe-it) [](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://hub.docker.com/r/snipe/snipe-it/) [](https://twitter.com/snipeyhead) [](https://zenhub.io) [](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
-[](#contributors)
+[](#contributors)
## Snipe-IT - Open Source Asset Management System
@@ -68,7 +68,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
| [
Gil Rutkowski](http://FlashingCursor.com)
[π»](https://github.com/snipe/snipe-it/commits?author=flashingcursor "Code") | [
Desmond Morris](http://www.desmondmorris.com)
[π»](https://github.com/snipe/snipe-it/commits?author=desmondmorris "Code") | [
Nick Peelman](http://peelman.us)
[π»](https://github.com/snipe/snipe-it/commits?author=peelman "Code") | [
Abraham Vegh](https://abrahamvegh.com)
[π»](https://github.com/snipe/snipe-it/commits?author=abrahamvegh "Code") | [
Mohamed Rashid](https://github.com/rashivkp)
[π](https://github.com/snipe/snipe-it/commits?author=rashivkp "Documentation") | [
Kasey](http://hinchk.github.io)
[π»](https://github.com/snipe/snipe-it/commits?author=HinchK "Code") | [
Brett](https://github.com/BrettFagerlund)
[β οΈ](https://github.com/snipe/snipe-it/commits?author=BrettFagerlund "Tests") |
| [
Jason Spriggs](http://jasonspriggs.com)
[π»](https://github.com/snipe/snipe-it/commits?author=jasonspriggs "Code") | [
Nate Felton](http://n8felton.wordpress.com)
[π»](https://github.com/snipe/snipe-it/commits?author=n8felton "Code") | [
Manasses Ferreira](http://homepages.dcc.ufmg.br/~manassesferreira)
[π»](https://github.com/snipe/snipe-it/commits?author=manassesferreira "Code") | [
Steve](https://github.com/steveelwood)
[β οΈ](https://github.com/snipe/snipe-it/commits?author=steveelwood "Tests") | [
matc](http://twitter.com/matc)
[β οΈ](https://github.com/snipe/snipe-it/commits?author=matc "Tests") | [
Cole R. Davis](http://www.davisracingteam.com)
[β οΈ](https://github.com/snipe/snipe-it/commits?author=VanillaNinjaD "Tests") | [
gibsonjoshua55](https://github.com/gibsonjoshua55)
[π»](https://github.com/snipe/snipe-it/commits?author=gibsonjoshua55 "Code") |
| [
Robin Temme](https://github.com/zwerch)
[π»](https://github.com/snipe/snipe-it/commits?author=zwerch "Code") | [
Iman](https://github.com/imanghafoori1)
[π»](https://github.com/snipe/snipe-it/commits?author=imanghafoori1 "Code") | [
Richard Hofman](https://github.com/richardhofman6)
[π»](https://github.com/snipe/snipe-it/commits?author=richardhofman6 "Code") | [
gizzmojr](https://github.com/gizzmojr)
[π»](https://github.com/snipe/snipe-it/commits?author=gizzmojr "Code") | [
Jenny Li](https://github.com/imjennyli)
[π](https://github.com/snipe/snipe-it/commits?author=imjennyli "Documentation") | [
Geoff Young](https://github.com/GeoffYoung)
[π»](https://github.com/snipe/snipe-it/commits?author=GeoffYoung "Code") | [
Elliot Blackburn](http://www.elliotblackburn.com)
[π](https://github.com/snipe/snipe-it/commits?author=BlueHatbRit "Documentation") |
-| [
TΓ΅nis Ormisson](http://andmemasin.eu)
[π»](https://github.com/snipe/snipe-it/commits?author=TonisOrmisson "Code") | [
Nicolai Essig](http://www.nicolai-essig.de)
[π»](https://github.com/snipe/snipe-it/commits?author=thakilla "Code") | [
Danielle](https://github.com/techincolor)
[π](https://github.com/snipe/snipe-it/commits?author=techincolor "Documentation") | [
Lawrence](https://github.com/TheVakman)
[β οΈ](https://github.com/snipe/snipe-it/commits?author=TheVakman "Tests") [π](https://github.com/snipe/snipe-it/issues?q=author%3ATheVakman "Bug reports") | [
uknzaeinozpas](https://github.com/uknzaeinozpas)
[β οΈ](https://github.com/snipe/snipe-it/commits?author=uknzaeinozpas "Tests") [π»](https://github.com/snipe/snipe-it/commits?author=uknzaeinozpas "Code") |
+| [
TΓ΅nis Ormisson](http://andmemasin.eu)
[π»](https://github.com/snipe/snipe-it/commits?author=TonisOrmisson "Code") | [
Nicolai Essig](http://www.nicolai-essig.de)
[π»](https://github.com/snipe/snipe-it/commits?author=thakilla "Code") | [
Danielle](https://github.com/techincolor)
[π](https://github.com/snipe/snipe-it/commits?author=techincolor "Documentation") | [
Lawrence](https://github.com/TheVakman)
[β οΈ](https://github.com/snipe/snipe-it/commits?author=TheVakman "Tests") [π](https://github.com/snipe/snipe-it/issues?q=author%3ATheVakman "Bug reports") | [
uknzaeinozpas](https://github.com/uknzaeinozpas)
[β οΈ](https://github.com/snipe/snipe-it/commits?author=uknzaeinozpas "Tests") [π»](https://github.com/snipe/snipe-it/commits?author=uknzaeinozpas "Code") | [
Ryan](https://github.com/Gelob)
[π](https://github.com/snipe/snipe-it/commits?author=Gelob "Documentation") |
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php
index 3976d473d..d41d2c093 100644
--- a/app/Http/Controllers/Api/AssetsController.php
+++ b/app/Http/Controllers/Api/AssetsController.php
@@ -72,6 +72,8 @@ class AssetsController extends Controller
'updated_at',
'purchase_date',
'purchase_cost',
+ 'last_audit_date',
+ 'next_audit_date',
'warranty_months',
];
@@ -675,7 +677,11 @@ class AssetsController extends Controller
if ($asset) {
+ // We don't want to log this as a normal update, so let's bypass that
+ $asset->unsetEventDispatcher();
$asset->next_audit_date = $request->input('next_audit_date');
+ $asset->last_audit_date = date('Y-m-d h:i:s');
+
if ($asset->save()) {
$log = $asset->logAudit(request('note'),request('location_id'));
return response()->json(Helper::formatStandardApiResponse('success', [
diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php
index 84f38fe15..27bb31fbf 100644
--- a/app/Http/Controllers/Api/UsersController.php
+++ b/app/Http/Controllers/Api/UsersController.php
@@ -68,11 +68,11 @@ class UsersController extends Controller
}
if ($request->has('company_id')) {
- $users = $users->where('company_id', '=', $request->input('company_id'));
+ $users = $users->where('users.company_id', '=', $request->input('company_id'));
}
if ($request->has('location_id')) {
- $users = $users->where('location_id', '=', $request->input('location_id'));
+ $users = $users->where('users.location_id', '=', $request->input('location_id'));
}
if ($request->has('group_id')) {
diff --git a/app/Http/Controllers/AssetsController.php b/app/Http/Controllers/AssetsController.php
index ffbe5ad40..a2598dca6 100755
--- a/app/Http/Controllers/AssetsController.php
+++ b/app/Http/Controllers/AssetsController.php
@@ -402,13 +402,6 @@ class AssetsController extends Controller
$asset->delete();
- $logaction = new Actionlog();
- $logaction->item_type = Asset::class;
- $logaction->item_id = $asset->id;
- $logaction->created_at = date("Y-m-d H:i:s");
- $logaction->user_id = Auth::user()->id;
- $logaction->logaction('deleted');
-
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.delete.success'));
}
@@ -919,6 +912,14 @@ class AssetsController extends Controller
if (isset($asset->id)) {
// Restore the asset
Asset::withTrashed()->where('id', $assetId)->restore();
+
+ $logaction = new Actionlog();
+ $logaction->item_type = Asset::class;
+ $logaction->item_id = $asset->id;
+ $logaction->created_at = date("Y-m-d H:i:s");
+ $logaction->user_id = Auth::user()->id;
+ $logaction->logaction('restored');
+
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.restore.success'));
}
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
@@ -1255,6 +1256,7 @@ class AssetsController extends Controller
return view('hardware/audit')->with('asset', $asset)->with('next_audit_date', $dt)->with('locations_list');
}
+
public function auditStore(Request $request, $id)
{
$this->authorize('audit', Asset::class);
@@ -1270,7 +1272,11 @@ class AssetsController extends Controller
}
$asset = Asset::findOrFail($id);
+ // We don't want to log this as a normal update, so let's bypass that
+ $asset->unsetEventDispatcher();
+
$asset->next_audit_date = $request->input('next_audit_date');
+ $asset->last_audit_date = date('Y-m-d h:i:s');
if ($asset->save()) {
$asset->logAudit(request('note'), request('location_id'));
diff --git a/app/Http/Controllers/LicensesController.php b/app/Http/Controllers/LicensesController.php
index 444783677..559f979fa 100755
--- a/app/Http/Controllers/LicensesController.php
+++ b/app/Http/Controllers/LicensesController.php
@@ -362,7 +362,14 @@ class LicensesController extends Controller
// Redirect to the asset management page with error
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found'));
}
- $this->authorize('checkin', $licenseSeat);
+
+ if (is_null($license = License::find($licenseSeat->license_id))) {
+ // Redirect to the asset management page with error
+ return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found'));
+ }
+
+
+ $this->authorize('checkout', $license);
return view('licenses/checkin', compact('licenseSeat'))->with('backto', $backTo);
}
@@ -386,8 +393,7 @@ class LicensesController extends Controller
}
$license = License::find($licenseSeat->license_id);
-
- $this->authorize('checkin', $licenseSeat);
+ $this->authorize('checkout', $license);
if (!$license->reassignable) {
// Not allowed to checkin
diff --git a/app/Http/Controllers/ManufacturersController.php b/app/Http/Controllers/ManufacturersController.php
index c936b90e5..39a8f7acf 100755
--- a/app/Http/Controllers/ManufacturersController.php
+++ b/app/Http/Controllers/ManufacturersController.php
@@ -35,6 +35,7 @@ class ManufacturersController extends Controller
*/
public function index()
{
+ $this->authorize('index', Manufacturer::class);
return view('manufacturers/index', compact('manufacturers'));
}
@@ -49,6 +50,7 @@ class ManufacturersController extends Controller
*/
public function create()
{
+ $this->authorize('create', Manufacturer::class);
return view('manufacturers/edit')->with('item', new Manufacturer);
}
@@ -65,6 +67,7 @@ class ManufacturersController extends Controller
public function store(ImageUploadRequest $request)
{
+ $this->authorize('edit', Manufacturer::class);
$manufacturer = new Manufacturer;
$manufacturer->name = $request->input('name');
$manufacturer->user_id = Auth::user()->id;
@@ -104,6 +107,7 @@ class ManufacturersController extends Controller
*/
public function edit($id = null)
{
+ $this->authorize('edit', Manufacturer::class);
// Check if the manufacturer exists
if (is_null($item = Manufacturer::find($id))) {
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.does_not_exist'));
@@ -125,6 +129,7 @@ class ManufacturersController extends Controller
*/
public function update(ImageUploadRequest $request, $manufacturerId = null)
{
+ $this->authorize('edit', Manufacturer::class);
// Check if the manufacturer exists
if (is_null($manufacturer = Manufacturer::find($manufacturerId))) {
// Redirect to the manufacturer page
@@ -186,6 +191,7 @@ 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
@@ -224,6 +230,7 @@ class ManufacturersController extends Controller
*/
public function show($manufacturerId = null)
{
+ $this->authorize('view', Manufacturer::class);
$manufacturer = Manufacturer::find($manufacturerId);
if (isset($manufacturer->id)) {
diff --git a/app/Http/Controllers/ReportsController.php b/app/Http/Controllers/ReportsController.php
index ba93c0da4..834aa91db 100644
--- a/app/Http/Controllers/ReportsController.php
+++ b/app/Http/Controllers/ReportsController.php
@@ -535,6 +535,14 @@ class ReportsController extends Controller
$header[] = trans('general.updated_at');
}
+ if ($request->has('last_audit_date')) {
+ $header[] = trans('general.last_audit');
+ }
+
+ if ($request->has('next_audit_date')) {
+ $header[] = trans('general.next_audit_date');
+ }
+
if ($request->has('notes')) {
$header[] = trans('general.notes');
}
@@ -709,6 +717,14 @@ class ReportsController extends Controller
$row[] = ($asset->updated_at) ? $asset->updated_at : '';
}
+ if ($request->has('last_audit_date')) {
+ $row[] = ($asset->last_audit_date) ? $asset->last_audit_date : '';
+ }
+
+ if ($request->has('next_audit_date')) {
+ $row[] = ($asset->next_audit_date) ? $asset->next_audit_date : '';
+ }
+
if ($request->has('notes')) {
$row[] = ($asset->notes) ? $asset->notes : '';
}
diff --git a/app/Http/Transformers/AssetsTransformer.php b/app/Http/Transformers/AssetsTransformer.php
index 0f8109dc1..c37a53478 100644
--- a/app/Http/Transformers/AssetsTransformer.php
+++ b/app/Http/Transformers/AssetsTransformer.php
@@ -69,6 +69,8 @@ class AssetsTransformer
'warranty_expires' => ($asset->warranty_months > 0) ? Helper::getFormattedDateObject($asset->warranty_expires, 'date') : null,
'created_at' => Helper::getFormattedDateObject($asset->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($asset->updated_at, 'datetime'),
+ 'last_audit_date' => Helper::getFormattedDateObject($asset->last_audit_date, 'datetime'),
+ 'next_audit_date' => Helper::getFormattedDateObject($asset->next_audit_date, 'date'),
'deleted_at' => Helper::getFormattedDateObject($asset->deleted_at, 'datetime'),
'purchase_date' => Helper::getFormattedDateObject($asset->purchase_date, 'date'),
'last_checkout' => Helper::getFormattedDateObject($asset->last_checkout, 'datetime'),
diff --git a/app/Models/Asset.php b/app/Models/Asset.php
index fe3589817..6ecc883a3 100644
--- a/app/Models/Asset.php
+++ b/app/Models/Asset.php
@@ -49,7 +49,9 @@ class Asset extends Depreciable
'deleted_at',
'purchase_date',
'last_checkout',
- 'expected_checkin'
+ 'expected_checkin',
+ 'last_audit_date',
+ 'next_audit_date'
];
@@ -68,6 +70,7 @@ class Asset extends Depreciable
'status' => 'integer',
'purchase_cost' => 'numeric|nullable',
'next_audit_date' => 'date|nullable',
+ 'last_audit_date' => 'date|nullable',
];
/**
diff --git a/app/Models/User.php b/app/Models/User.php
index 4cb790e28..b1de55443 100755
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -13,6 +13,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
use App\Http\Traits\UniqueUndeletedTrait;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
+use DB;
class User extends SnipeModel implements AuthenticatableContract, CanResetPasswordContract
{
@@ -441,7 +442,7 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
//Ugly, ugly code because Laravel sucks at self-joins
->orWhere(function ($query) use ($search) {
- $query->whereRaw("users.manager_id IN (select id from users where first_name LIKE ? OR last_name LIKE ?)", ["%$search%", "%$search%"]);
+ $query->whereRaw(DB::getTablePrefix()."users.manager_id IN (select id from ".DB::getTablePrefix()."users where first_name LIKE ? OR last_name LIKE ?)", ["%$search%", "%$search%"]);
});
diff --git a/app/Policies/ManufacturerPolicy.php b/app/Policies/ManufacturerPolicy.php
new file mode 100644
index 000000000..8800b46c3
--- /dev/null
+++ b/app/Policies/ManufacturerPolicy.php
@@ -0,0 +1,13 @@
+ false,
"title" => trans('admin/hardware/form.expected_checkin'),
"formatter" => "dateDisplayFormatter"
+ ], [
+ "field" => "last_audit_date",
+ "searchable" => false,
+ "sortable" => true,
+ "visible" => false,
+ "title" => trans('general.last_audit'),
+ "formatter" => "dateDisplayFormatter"
+ ], [
+ "field" => "next_audit_date",
+ "searchable" => false,
+ "sortable" => true,
+ "visible" => false,
+ "title" => trans('general.next_audit_date'),
+ "formatter" => "dateDisplayFormatter"
],
];
diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php
index 264bce970..da21b1c7c 100644
--- a/app/Providers/AuthServiceProvider.php
+++ b/app/Providers/AuthServiceProvider.php
@@ -14,6 +14,7 @@ use App\Models\License;
use App\Models\Location;
use App\Models\Statuslabel;
use App\Models\Supplier;
+use App\Models\Manufacturer;
use App\Models\User;
use App\Policies\AccessoryPolicy;
use App\Policies\AssetModelPolicy;
@@ -28,6 +29,7 @@ use App\Policies\LocationPolicy;
use App\Policies\StatuslabelPolicy;
use App\Policies\SupplierPolicy;
use App\Policies\UserPolicy;
+use App\Policies\ManufacturerPolicy;
use Carbon\Carbon;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
@@ -38,6 +40,8 @@ class AuthServiceProvider extends ServiceProvider
/**
* The policy mappings for the application.
*
+ * See SnipePermissionsPolicy for additional information.
+ *
* @var array
*/
protected $policies = [
@@ -54,6 +58,7 @@ class AuthServiceProvider extends ServiceProvider
Statuslabel::class => StatuslabelPolicy::class,
Supplier::class => SupplierPolicy::class,
User::class => UserPolicy::class,
+ Manufacturer::class => ManufacturerPolicy::class,
];
/**
@@ -126,6 +131,7 @@ class AuthServiceProvider extends ServiceProvider
|| $user->can('view', \App\Models\Department::class)
|| $user->can('view', \App\Models\Location::class)
|| $user->can('view', \App\Models\Company::class)
+ || $user->can('view', \App\Models\Manufacturer::class)
|| $user->can('view', \App\Models\Depreciation::class);
});
}
diff --git a/config/version.php b/config/version.php
index 9ed0644a2..e86d97ffc 100644
--- a/config/version.php
+++ b/config/version.php
@@ -1,10 +1,10 @@
'v4.1.8-pre',
- 'full_app_version' => 'v4.1.8-pre - build 3034',
- 'build_version' => '3034',
+ 'full_app_version' => 'v4.1.8-pre - build 3068-gceca76b',
+ 'build_version' => '3068',
'prerelease_version' => '',
- 'hash_version' => 'g4f3c932',
- 'full_hash' => 'v4.1.7-37-g4f3c932',
+ 'hash_version' => 'gceca76b',
+ 'full_hash' => 'v4.1.7-34-gceca76b',
'branch' => 'master',
);
diff --git a/database/migrations/2017_12_12_010457_normalize_asset_last_audit_date.php b/database/migrations/2017_12_12_010457_normalize_asset_last_audit_date.php
new file mode 100644
index 000000000..cf80c2faa
--- /dev/null
+++ b/database/migrations/2017_12_12_010457_normalize_asset_last_audit_date.php
@@ -0,0 +1,49 @@
+datetime('last_audit_date')->after('assigned_type')->nullable()->default(null);
+ });
+
+ // Grab the latest info from the Actionlog table where the action is 'audit'
+ $audits = Actionlog::selectRaw('MAX(created_at) AS created_at, item_id')->where('action_type', 'audit')->where('item_type', Asset::class)->groupBy('item_id')->orderBy('created_at', 'desc')->get();
+
+ if ($audits) {
+ foreach ($audits as $audit) {
+ $assets = Asset::where('id', $audit->item_id)->first();
+ $assets->last_audit_date = $audit->created_at;
+ $assets->unsetEventDispatcher();
+ $assets->save();
+ }
+ }
+
+
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('assets', function (Blueprint $table) {
+ $table->dropColumn('last_audit_date');
+ });
+ }
+}
diff --git a/resources/lang/en/general.php b/resources/lang/en/general.php
index b50afe081..94acace65 100644
--- a/resources/lang/en/general.php
+++ b/resources/lang/en/general.php
@@ -151,6 +151,7 @@
'recent_activity' => 'Recent Activity',
'remove_company' => 'Remove Company Association',
'reports' => 'Reports',
+ 'restored' => 'restored',
'requested' => 'Requested',
'request_canceled' => 'Request Canceled',
'save' => 'Save',
diff --git a/resources/views/hardware/view.blade.php b/resources/views/hardware/view.blade.php
index a55de3839..6ee49939d 100755
--- a/resources/views/hardware/view.blade.php
+++ b/resources/views/hardware/view.blade.php
@@ -32,19 +32,22 @@
{{-- Page content --}}
@section('content')