Compare commits
1 Commits
added-tele
...
maybe-new-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cbae5ce9ab |
@@ -4189,24 +4189,6 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "mckaygerhard",
|
||||
"name": "Герхард PICCORO Lenz McKAY ",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1571724?v=4",
|
||||
"profile": "https://github-readme-stats.vercel.app/api?username=mckaygerhard",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "FlorestanII",
|
||||
"name": "Johannes Pollitt",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/15015119?v=4",
|
||||
"profile": "https://github.com/FlorestanII",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -68,7 +68,6 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
||||
| [<img src="https://avatars.githubusercontent.com/u/181059?v=4" width="110px;"/><br /><sub>Juan Font</sub>](https://github.com/juanfont)<br />[💻](https://github.com/snipe/snipe-it/commits?author=juanfont "Code") | [<img src="https://avatars.githubusercontent.com/u/13137708?v=4" width="110px;"/><br /><sub>Juho Taipale</sub>](https://github.com/juhotaipale)<br />[💻](https://github.com/snipe/snipe-it/commits?author=juhotaipale "Code") | [<img src="https://avatars.githubusercontent.com/u/1007419?v=4" width="110px;"/><br /><sub>Korvin Szanto</sub>](https://github.com/KorvinSzanto)<br />[💻](https://github.com/snipe/snipe-it/commits?author=KorvinSzanto "Code") | [<img src="https://avatars.githubusercontent.com/u/8513053?v=4" width="110px;"/><br /><sub>Lewis Foster</sub>](https://lewisfoster.foo/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sniff122 "Code") | [<img src="https://avatars.githubusercontent.com/u/33877541?v=4" width="110px;"/><br /><sub>Logan Swartzendruber</sub>](https://github.com/loganswartz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=loganswartz "Code") | [<img src="https://avatars.githubusercontent.com/u/1156208?v=4" width="110px;"/><br /><sub>Lorenzo P.</sub>](https://github.com/lopezio)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lopezio "Code") | [<img src="https://avatars.githubusercontent.com/u/33946590?v=4" width="110px;"/><br /><sub>Lukas Jung</sub>](https://github.com/m4us1ne)<br />[💻](https://github.com/snipe/snipe-it/commits?author=m4us1ne "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/10965027?v=4" width="110px;"/><br /><sub>Ellie</sub>](https://leafedfox.xyz/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=LeafedFox "Code") | [<img src="https://avatars.githubusercontent.com/u/20960555?v=4" width="110px;"/><br /><sub>GA Stamper</sub>](https://github.com/gastamper)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gastamper "Code") | [<img src="https://avatars.githubusercontent.com/u/206553556?v=4" width="110px;"/><br /><sub>Guillaume Lefranc</sub>](https://github.com/gl-pup)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gl-pup "Code") | [<img src="https://avatars.githubusercontent.com/u/733892?v=4" width="110px;"/><br /><sub>Hajo Möller</sub>](https://github.com/dasjoe)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dasjoe "Code") | [<img src="https://avatars.githubusercontent.com/u/3420063?v=4" width="110px;"/><br /><sub>Istvan Basa</sub>](https://github.com/pottom)<br />[💻](https://github.com/snipe/snipe-it/commits?author=pottom "Code") | [<img src="https://avatars.githubusercontent.com/u/810824?v=4" width="110px;"/><br /><sub>JJ Asghar</sub>](https://jjasghar.github.io/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jjasghar "Code") | [<img src="https://avatars.githubusercontent.com/u/40404495?v=4" width="110px;"/><br /><sub>James E. Msenga</sub>](https://github.com/JemCdo)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JemCdo "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/6865786?v=4" width="110px;"/><br /><sub>Jan Felix Wiebe</sub>](https://github.com/jfwiebe)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jfwiebe "Code") | [<img src="https://avatars.githubusercontent.com/u/43412008?v=4" width="110px;"/><br /><sub>Jo Drexl</sub>](https://www.nfon.com/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=drexljo "Code") | [<img src="https://avatars.githubusercontent.com/u/4807843?v=4" width="110px;"/><br /><sub>Austin Sasko</sub>](https://github.com/austinsasko)<br />[💻](https://github.com/snipe/snipe-it/commits?author=austinsasko "Code") | [<img src="https://avatars.githubusercontent.com/u/4875039?v=4" width="110px;"/><br /><sub>Jasson</sub>](http://jassoncordones.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JassonCordones "Code") | [<img src="https://avatars.githubusercontent.com/u/76069640?v=4" width="110px;"/><br /><sub>Okean</sub>](https://github.com/Tinyblargon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Tinyblargon "Code") | [<img src="https://avatars.githubusercontent.com/u/6515064?v=4" width="110px;"/><br /><sub>Alejandro Medrano</sub>](https://www.lst.tfo.upm.es/alejandro-medrano/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=amedranogil "Code") | [<img src="https://avatars.githubusercontent.com/u/58696401?v=4" width="110px;"/><br /><sub>Lukas Kraic</sub>](https://github.com/lukaskraic)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lukaskraic "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/1571724?v=4" width="110px;"/><br /><sub>Герхард PICCORO Lenz McKAY </sub>](https://github-readme-stats.vercel.app/api?username=mckaygerhard)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mckaygerhard "Code") | [<img src="https://avatars.githubusercontent.com/u/15015119?v=4" width="110px;"/><br /><sub>Johannes Pollitt</sub>](https://github.com/FlorestanII)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FlorestanII "Code") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\CheckoutRequest;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class CleanOldCheckoutRequests extends Command
|
||||
{
|
||||
private int $deletions = 0;
|
||||
private int $skips = 0;
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:clean-old-checkout-requests';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Removes checkout requests that reference deleted assets or users.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$requests = CheckoutRequest::with([
|
||||
'user' => function ($query) {
|
||||
$query->withTrashed();
|
||||
},
|
||||
'requestedItem' => function ($query) {
|
||||
$query->withTrashed();
|
||||
},
|
||||
])->get();
|
||||
|
||||
$this->info("Processing {$requests->count()} checkout requests");
|
||||
|
||||
$this->withProgressBar($requests, function ($request) {
|
||||
if ($this->shouldForceDelete($request)) {
|
||||
$request->forceDelete();
|
||||
$this->deletions++;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->shouldSoftDelete($request)) {
|
||||
$request->delete();
|
||||
$this->deletions++;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->skips++;
|
||||
});
|
||||
|
||||
$this->info("Final deletion count: $this->deletions, and skip count: $this->skips");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function shouldForceDelete(CheckoutRequest $request)
|
||||
{
|
||||
// check if the requestable or user relationship is null
|
||||
return !$request->requestable || !$request->user;
|
||||
}
|
||||
|
||||
private function shouldSoftDelete(CheckoutRequest $request)
|
||||
{
|
||||
return $request->requestable->trashed() || $request->user->trashed();
|
||||
}
|
||||
}
|
||||
@@ -96,7 +96,7 @@ class MoveUploadsToNewDisk extends Command
|
||||
$private_uploads['assets'] = glob('storage/private_uploads/assets'."/*.*");
|
||||
$private_uploads['signatures'] = glob('storage/private_uploads/signatures'."/*.*");
|
||||
$private_uploads['audits'] = glob('storage/private_uploads/audits'."/*.*");
|
||||
$private_uploads['assetmodels'] = glob('storage/private_uploads/models'."/*.*");
|
||||
$private_uploads['assetmodels'] = glob('storage/private_uploads/assetmodels'."/*.*");
|
||||
$private_uploads['imports'] = glob('storage/private_uploads/imports'."/*.*");
|
||||
$private_uploads['licenses'] = glob('storage/private_uploads/licenses'."/*.*");
|
||||
$private_uploads['users'] = glob('storage/private_uploads/users'."/*.*");
|
||||
|
||||
@@ -62,19 +62,19 @@ class Purge extends Command
|
||||
$assetcount = $assets->count();
|
||||
$this->info($assets->count().' assets purged.');
|
||||
$asset_assoc = 0;
|
||||
$maintenances = 0;
|
||||
$asset_maintenances = 0;
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
$this->info('- Asset "'.$asset->present()->name().'" deleted.');
|
||||
$asset_assoc += $asset->assetlog()->count();
|
||||
$asset->assetlog()->forceDelete();
|
||||
$maintenances += $asset->maintenances()->count();
|
||||
$asset->maintenances()->forceDelete();
|
||||
$asset_maintenances += $asset->assetmaintenances()->count();
|
||||
$asset->assetmaintenances()->forceDelete();
|
||||
$asset->forceDelete();
|
||||
}
|
||||
|
||||
$this->info($asset_assoc.' corresponding log records purged.');
|
||||
$this->info($maintenances.' corresponding maintenance records purged.');
|
||||
$this->info($asset_maintenances.' corresponding maintenance records purged.');
|
||||
|
||||
$locations = Location::whereNotNull('deleted_at')->withTrashed()->get();
|
||||
$this->info($locations->count().' locations purged.');
|
||||
|
||||
@@ -243,8 +243,6 @@ class RestoreFromBackup extends Command
|
||||
$private_dirs = [
|
||||
'storage/private_uploads/accessories',
|
||||
'storage/private_uploads/assetmodels',
|
||||
'storage/private_uploads/maintenances',
|
||||
'storage/private_uploads/models',
|
||||
'storage/private_uploads/assets', // these are asset _files_, not the pictures.
|
||||
'storage/private_uploads/audits',
|
||||
'storage/private_uploads/components',
|
||||
@@ -262,10 +260,9 @@ class RestoreFromBackup extends Command
|
||||
];
|
||||
$public_dirs = [
|
||||
'public/uploads/accessories',
|
||||
'public/uploads/assetmodels',
|
||||
'public/uploads/maintenances',
|
||||
'public/uploads/assets', // these are asset _pictures_, not asset files
|
||||
'public/uploads/avatars',
|
||||
//'public/uploads/barcodes', // we don't want this, let the barcodes be regenerated
|
||||
'public/uploads/categories',
|
||||
'public/uploads/companies',
|
||||
'public/uploads/components',
|
||||
|
||||
@@ -138,13 +138,13 @@ class Handler extends ExceptionHandler
|
||||
if (in_array('bulkedit', $ids, true)) {
|
||||
$error_array = session()->get('bulk_asset_errors');
|
||||
return redirect()
|
||||
->route('hardware.index')
|
||||
->route('hardware.bulkedit')
|
||||
->withErrors($error_array, 'bulk_asset_errors')
|
||||
->withInput();
|
||||
}
|
||||
|
||||
// This gets the MVC model name from the exception and formats in a way that's less fugly
|
||||
$model_name = trim(strtolower(implode(" ", preg_split('/(?=[A-Z])/', last(explode('\\', $e->getModel()))))));
|
||||
// This gets the MVC model name from the exception and formats in a way that's less fugly
|
||||
$model_name = strtolower(implode(" ", preg_split('/(?=[A-Z])/', last(explode('\\', $e->getModel())))));
|
||||
$route = str_plural(strtolower(last(explode('\\', $e->getModel())))).'.index';
|
||||
|
||||
// Sigh.
|
||||
@@ -160,7 +160,9 @@ class Handler extends ExceptionHandler
|
||||
$route = 'maintenances.index';
|
||||
} elseif ($route === 'licenseseats.index') {
|
||||
$route = 'licenses.index';
|
||||
} elseif (($route === 'customfieldsets.index') || ($route === 'customfields.index')) {
|
||||
} elseif ($route === 'customfields.index') {
|
||||
$route = 'fields.index';
|
||||
} elseif ($route === 'customfieldsets.index') {
|
||||
$route = 'fields.index';
|
||||
}
|
||||
|
||||
|
||||
@@ -1197,30 +1197,19 @@ class Helper
|
||||
'webp' => 'far fa-image',
|
||||
'avif' => 'far fa-image',
|
||||
'svg' => 'fas fa-vector-square',
|
||||
|
||||
// word
|
||||
'doc' => 'far fa-file-word',
|
||||
'docx' => 'far fa-file-word',
|
||||
|
||||
// Excel
|
||||
'xls' => 'far fa-file-excel',
|
||||
'xlsx' => 'far fa-file-excel',
|
||||
'ods' => 'far fa-file-excel',
|
||||
|
||||
// Presentation
|
||||
'ppt' => 'far fa-file-powerpoint',
|
||||
'odp' => 'far fa-file-powerpoint',
|
||||
|
||||
// archive
|
||||
'zip' => 'fas fa-file-archive',
|
||||
'rar' => 'fas fa-file-archive',
|
||||
|
||||
//Text
|
||||
'odt' => 'far fa-file-alt',
|
||||
'txt' => 'far fa-file-alt',
|
||||
'rtf' => 'far fa-file-alt',
|
||||
'xml' => 'fas fa-code',
|
||||
|
||||
// Misc
|
||||
'pdf' => 'far fa-file-pdf',
|
||||
'lic' => 'far fa-save',
|
||||
@@ -1554,6 +1543,11 @@ class Helper
|
||||
|
||||
// return to previous page
|
||||
if ($redirect_option === 'back') {
|
||||
if ($backUrl === route('home')) {
|
||||
return redirect()->to($backUrl)
|
||||
->with('warning', trans('general.page_error'));
|
||||
}
|
||||
|
||||
return redirect()->to($backUrl);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,8 +43,6 @@ class IconHelper
|
||||
return 'fa-regular fa-envelope';
|
||||
case 'phone':
|
||||
return 'fa-solid fa-phone';
|
||||
case 'mobile':
|
||||
return 'fas fa-mobile-screen-button';
|
||||
case 'long-arrow-right':
|
||||
return 'fas fa-long-arrow-alt-right';
|
||||
case 'download':
|
||||
|
||||
@@ -29,7 +29,7 @@ class StorageHelper
|
||||
|
||||
public static function getMediaType($file_with_path) {
|
||||
|
||||
// Get the file extension and determine the media type
|
||||
// The file exists and is allowed to be displayed inline
|
||||
if (Storage::exists($file_with_path)) {
|
||||
$fileinfo = pathinfo($file_with_path);
|
||||
$extension = strtolower($fileinfo['extension']);
|
||||
@@ -51,15 +51,6 @@ class StorageHelper
|
||||
case 'webm':
|
||||
case 'mov':
|
||||
return 'video';
|
||||
case 'doc':
|
||||
case 'docx':
|
||||
return 'document';
|
||||
case 'txt':
|
||||
return 'text';
|
||||
case 'xls':
|
||||
case 'xlsx':
|
||||
case 'ods':
|
||||
return 'spreadsheet';
|
||||
default:
|
||||
return $extension; // Default for unknown types
|
||||
}
|
||||
|
||||
@@ -90,12 +90,7 @@ class AccessoriesController extends Controller
|
||||
$accessory = $request->handleImages($accessory);
|
||||
}
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
}
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
// Was the accessory created?
|
||||
if ($accessory->save()) {
|
||||
// Redirect to the new accessory page
|
||||
|
||||
132
app/Http/Controllers/Accessories/AccessoriesFilesController.php
Normal file
132
app/Http/Controllers/Accessories/AccessoriesFilesController.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Accessories;
|
||||
|
||||
use App\Helpers\StorageHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Accessory;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
use \Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class AccessoriesFilesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Validates and stores files associated with a accessory.
|
||||
*
|
||||
* @param UploadFileRequest $request
|
||||
* @param int $accessoryId
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @todo Switch to using the AssetFileRequest form request validator.
|
||||
*/
|
||||
public function store(UploadFileRequest $request, $accessoryId = null) : RedirectResponse
|
||||
{
|
||||
|
||||
if (config('app.lock_passwords')) {
|
||||
return redirect()->route('accessories.show', ['accessory'=>$accessoryId])->with('error', trans('general.feature_disabled'));
|
||||
}
|
||||
|
||||
$accessory = Accessory::find($accessoryId);
|
||||
|
||||
if (isset($accessory->id)) {
|
||||
$this->authorize('accessories.files', $accessory);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
if (! Storage::exists('private_uploads/accessories')) {
|
||||
Storage::makeDirectory('private_uploads/accessories', 775);
|
||||
}
|
||||
|
||||
foreach ($request->file('file') as $file) {
|
||||
|
||||
$file_name = $request->handleFile('private_uploads/accessories/', 'accessory-'.$accessory->id, $file);
|
||||
//Log the upload to the log
|
||||
$accessory->logUpload($file_name, e($request->input('notes')));
|
||||
}
|
||||
|
||||
|
||||
return redirect()->route('accessories.show', $accessory->id)->withFragment('files')->with('success', trans('general.file_upload_success'));
|
||||
|
||||
}
|
||||
|
||||
return redirect()->route('accessories.show', $accessory->id)->withFragment('files')->with('error', trans('general.no_files_uploaded'));
|
||||
}
|
||||
// Prepare the error message
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the selected accessory file.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $accessoryId
|
||||
* @param int $fileId
|
||||
*/
|
||||
public function destroy($accessoryId = null, $fileId = null) : RedirectResponse
|
||||
{
|
||||
if ($accessory = Accessory::find($accessoryId)) {
|
||||
$this->authorize('update', $accessory);
|
||||
|
||||
if ($log = Actionlog::find($fileId)) {
|
||||
|
||||
if (Storage::exists('private_uploads/accessories/'.$log->filename)) {
|
||||
try {
|
||||
Storage::delete('private_uploads/accessories/' . $log->filename);
|
||||
$log->delete();
|
||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
|
||||
} catch (\Exception $e) {
|
||||
Log::debug($e);
|
||||
return redirect()->route('accessories.index')->with('error', trans('general.file_does_not_exist'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return redirect()->route('accessories.show', ['accessory' => $accessory])->withFragment('files')->with('error', trans('general.log_record_not_found'));
|
||||
}
|
||||
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the selected file to be viewed.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.4]
|
||||
* @param int $accessoryId
|
||||
* @param int $fileId
|
||||
*/
|
||||
public function show($accessoryId = null, $fileId = null) : View | RedirectResponse | Response | BinaryFileResponse | StreamedResponse
|
||||
{
|
||||
|
||||
|
||||
// the accessory is valid
|
||||
if ($accessory = Accessory::find($accessoryId)) {
|
||||
$this->authorize('view', $accessory);
|
||||
$this->authorize('accessories.files', $accessory);
|
||||
|
||||
if ($log = Actionlog::whereNotNull('filename')->where('item_id', $accessory->id)->find($fileId)) {
|
||||
$file = 'private_uploads/accessories/'.$log->filename;
|
||||
|
||||
try {
|
||||
return StorageHelper::showOrDownloadFile($file, $log->filename);
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->route('accessories.show', ['accessory' => $accessory])->with('error', trans('general.file_not_found'));
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->route('accessories.show', ['accessory' => $accessory])->withFragment('files')->with('error', trans('general.log_record_not_found'));
|
||||
|
||||
}
|
||||
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -232,7 +232,6 @@ class AcceptanceController extends Controller
|
||||
'signature' => ($sig_filename) ? storage_path() . '/private_uploads/signatures/' . $sig_filename : null,
|
||||
'logo' => $path_logo,
|
||||
'date_settings' => $branding_settings->date_display_format,
|
||||
'admin' => auth()->user()->present()?->fullName,
|
||||
];
|
||||
|
||||
if ($pdf_view_route!='') {
|
||||
@@ -348,7 +347,6 @@ class AcceptanceController extends Controller
|
||||
|
||||
$acceptance->decline($sig_filename, $request->input('note'));
|
||||
$acceptance->notify(new AcceptanceAssetDeclinedNotification($data));
|
||||
Log::debug('New event acceptance.');
|
||||
event(new CheckoutDeclined($acceptance));
|
||||
$return_msg = trans('admin/users/message.declined');
|
||||
}
|
||||
@@ -358,16 +356,13 @@ class AcceptanceController extends Controller
|
||||
$recipient = User::find($acceptance->alert_on_response_id);
|
||||
|
||||
if ($recipient) {
|
||||
Log::debug('Attempting to send email acceptance.');
|
||||
Mail::to($recipient)->send(new CheckoutAcceptanceResponseMail(
|
||||
$acceptance,
|
||||
$recipient,
|
||||
$request->input('asset_acceptance') === 'accepted',
|
||||
));
|
||||
Log::debug('Send email notification sucess on checkout acceptance response.');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::error($e->getMessage());
|
||||
Log::warning($e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@ namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Http\Transformers\MaintenancesTransformer;
|
||||
use App\Http\Transformers\AssetMaintenancesTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Maintenance;
|
||||
use App\Models\AssetMaintenance;
|
||||
use App\Models\Company;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
@@ -18,13 +18,13 @@ use Illuminate\Http\JsonResponse;
|
||||
*
|
||||
* @version v2.0
|
||||
*/
|
||||
class MaintenancesController extends Controller
|
||||
class AssetMaintenancesController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Generates the JSON response for asset maintenances listing view.
|
||||
*
|
||||
* @see MaintenancesController::getIndex() method that generates view
|
||||
* @see AssetMaintenancesController::getIndex() method that generates view
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
@@ -33,7 +33,7 @@ class MaintenancesController extends Controller
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
|
||||
$maintenances = Maintenance::select('maintenances.*')
|
||||
$maintenances = AssetMaintenance::select('asset_maintenances.*')
|
||||
->with('asset', 'asset.model', 'asset.location', 'asset.defaultLoc', 'supplier', 'asset.company', 'asset.assetstatus', 'adminuser');
|
||||
|
||||
if ($request->filled('search')) {
|
||||
@@ -45,11 +45,11 @@ class MaintenancesController extends Controller
|
||||
}
|
||||
|
||||
if ($request->filled('supplier_id')) {
|
||||
$maintenances->where('maintenances.supplier_id', '=', $request->input('supplier_id'));
|
||||
$maintenances->where('asset_maintenances.supplier_id', '=', $request->input('supplier_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('created_by')) {
|
||||
$maintenances->where('maintenances.created_by', '=', $request->input('created_by'));
|
||||
$maintenances->where('asset_maintenances.created_by', '=', $request->input('created_by'));
|
||||
}
|
||||
|
||||
if ($request->filled('asset_maintenance_type')) {
|
||||
@@ -63,7 +63,7 @@ class MaintenancesController extends Controller
|
||||
|
||||
$allowed_columns = [
|
||||
'id',
|
||||
'name',
|
||||
'title',
|
||||
'asset_maintenance_time',
|
||||
'asset_maintenance_type',
|
||||
'cost',
|
||||
@@ -112,7 +112,7 @@ class MaintenancesController extends Controller
|
||||
|
||||
$total = $maintenances->count();
|
||||
$maintenances = $maintenances->skip($offset)->take($limit)->get();
|
||||
return (new MaintenancesTransformer())->transformMaintenances($maintenances, $total);
|
||||
return (new AssetMaintenancesTransformer())->transformAssetMaintenances($maintenances, $total);
|
||||
|
||||
|
||||
}
|
||||
@@ -121,23 +121,22 @@ class MaintenancesController extends Controller
|
||||
/**
|
||||
* Validates and stores the new asset maintenance
|
||||
*
|
||||
* @see MaintenancesController::getCreate() method for the form
|
||||
* @see AssetMaintenancesController::getCreate() method for the form
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
*/
|
||||
public function store(ImageUploadRequest $request) : JsonResponse | array
|
||||
public function store(Request $request) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
|
||||
// create a new model instance
|
||||
$maintenance = new Maintenance();
|
||||
$maintenance = new AssetMaintenance();
|
||||
$maintenance->fill($request->all());
|
||||
$maintenance->created_by = auth()->id();
|
||||
$maintenance = $request->handleImages($maintenance);
|
||||
|
||||
// Was the asset maintenance created?
|
||||
if ($maintenance->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $maintenance, trans('admin/maintenances/message.create.success')));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $maintenance, trans('admin/asset_maintenances/message.create.success')));
|
||||
|
||||
}
|
||||
|
||||
@@ -158,11 +157,11 @@ class MaintenancesController extends Controller
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
|
||||
if ($maintenance = Maintenance::with('asset')->find($id)) {
|
||||
if ($maintenance = AssetMaintenance::with('asset')->find($id)) {
|
||||
|
||||
// Can this user manage this asset?
|
||||
if (! Company::isCurrentUserHasAccess($maintenance->asset)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.action_permission_denied', ['item_type' => trans('admin/maintenances/general.maintenance'), 'id' => $id, 'action' => trans('general.edit')])));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.action_permission_denied', ['item_type' => trans('admin/asset_maintenances/general.maintenance'), 'id' => $id, 'action' => trans('general.edit')])));
|
||||
}
|
||||
|
||||
// The asset this miantenance is attached to is not valid or has been deleted
|
||||
@@ -173,13 +172,13 @@ class MaintenancesController extends Controller
|
||||
$maintenance->fill($request->all());
|
||||
|
||||
if ($maintenance->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $maintenance, trans('admin/maintenances/message.edit.success')));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $maintenance, trans('admin/asset_maintenances/message.edit.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $maintenance->getErrors()));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.item_not_found', ['item_type' => trans('admin/maintenances/general.maintenance'), 'id' => $id])));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.item_not_found', ['item_type' => trans('admin/asset_maintenances/general.maintenance'), 'id' => $id])));
|
||||
|
||||
}
|
||||
|
||||
@@ -187,20 +186,20 @@ class MaintenancesController extends Controller
|
||||
* Delete an asset maintenance
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @param int $maintenanceId
|
||||
* @param int $assetMaintenanceId
|
||||
* @version v1.0
|
||||
* @since [v4.0]
|
||||
*/
|
||||
public function destroy($maintenanceId) : JsonResponse | array
|
||||
public function destroy($assetMaintenanceId) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
// Check if the asset maintenance exists
|
||||
|
||||
$maintenance = Maintenance::findOrFail($maintenanceId);
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
|
||||
$maintenance->delete();
|
||||
$assetMaintenance->delete();
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $maintenance, trans('admin/maintenances/message.delete.success')));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $assetMaintenance, trans('admin/asset_maintenances/message.delete.success')));
|
||||
|
||||
|
||||
}
|
||||
@@ -209,19 +208,19 @@ class MaintenancesController extends Controller
|
||||
* View an asset maintenance
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @param int $maintenanceId
|
||||
* @param int $assetMaintenanceId
|
||||
* @version v1.0
|
||||
* @since [v4.0]
|
||||
*/
|
||||
public function show($maintenanceId) : JsonResponse | array
|
||||
public function show($assetMaintenanceId) : JsonResponse | array
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
$maintenance = Maintenance::findOrFail($maintenanceId);
|
||||
if (! Company::isCurrentUserHasAccess($maintenance->asset)) {
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
if (! Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot view a maintenance for that asset'));
|
||||
}
|
||||
|
||||
return (new MaintenancesTransformer())->transformMaintenance($maintenance);
|
||||
return (new AssetMaintenancesTransformer())->transformAssetMaintenance($assetMaintenance);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -117,20 +117,15 @@ class AssetsController extends Controller
|
||||
'jobtitle',
|
||||
];
|
||||
|
||||
$all_custom_fields = CustomField::all(); //used as a 'cache' of custom fields throughout this page load
|
||||
|
||||
foreach ($all_custom_fields as $field) {
|
||||
$allowed_columns[] = $field->db_column_name();
|
||||
}
|
||||
|
||||
$filter = [];
|
||||
|
||||
if ($request->filled('filter')) {
|
||||
$filter = json_decode($request->input('filter'), true);
|
||||
}
|
||||
|
||||
$filter = array_filter($filter, function ($key) use ($allowed_columns) {
|
||||
return in_array($key, $allowed_columns);
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
$all_custom_fields = CustomField::all(); //used as a 'cache' of custom fields throughout this page load
|
||||
foreach ($all_custom_fields as $field) {
|
||||
$allowed_columns[] = $field->db_column_name();
|
||||
}
|
||||
|
||||
$assets = Asset::select('assets.*')
|
||||
@@ -146,7 +141,6 @@ class AssetsController extends Controller
|
||||
'model.category',
|
||||
'model.manufacturer',
|
||||
'model.fieldset',
|
||||
'model.depreciation',
|
||||
'supplier'
|
||||
); // it might be tempting to add 'assetlog' here, but don't. It blows up update-heavy users.
|
||||
|
||||
|
||||
@@ -228,16 +228,11 @@ class ConsumablesController extends Controller
|
||||
foreach ($consumable->consumableAssignments as $consumable_assignment) {
|
||||
$rows[] = [
|
||||
'avatar' => ($consumable_assignment->user) ? e($consumable_assignment->user->present()->gravatar) : '',
|
||||
'user' => ($consumable_assignment->user) ? [
|
||||
'id' => (int) $consumable_assignment->user->id,
|
||||
'name'=> e($consumable_assignment->user->present()->fullName()),
|
||||
] : null,
|
||||
'name' => ($consumable_assignment->user) ? $consumable_assignment->user->present()->nameUrl() : 'Deleted User',
|
||||
'created_at' => Helper::getFormattedDateObject($consumable_assignment->created_at, 'datetime'),
|
||||
'note' => ($consumable_assignment->note) ? e($consumable_assignment->note) : null,
|
||||
'created_by' => ($consumable_assignment->adminuser) ? [
|
||||
'id' => (int) $consumable_assignment->adminuser->id,
|
||||
'name'=> e($consumable_assignment->adminuser->present()->fullName()),
|
||||
] : null,
|
||||
'admin' => ($consumable_assignment->adminuser) ? $consumable_assignment->adminuser->present()->nameUrl() : null, // legacy, so we don't change the shape of the response
|
||||
'created_by' => ($consumable_assignment->adminuser) ? $consumable_assignment->adminuser->present()->nameUrl() : null,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -150,11 +150,8 @@ class SettingsController extends Controller
|
||||
if (!config('app.lock_passwords')) {
|
||||
try {
|
||||
Notification::send(Setting::first(), new MailTest());
|
||||
Log::debug('Attempting to sending to '.config('mail.reply_to.address'));
|
||||
return response()->json(['message' => 'Mail sent to '.config('mail.reply_to.address')], 200);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Mail sent error using '.config('mail.reply_to.address') .': '. $e->getMessage());
|
||||
Log::debug($e);
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
@@ -318,4 +315,4 @@ class SettingsController extends Controller
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -194,7 +194,7 @@ class SuppliersController extends Controller
|
||||
public function destroy($id) : JsonResponse
|
||||
{
|
||||
$this->authorize('delete', Supplier::class);
|
||||
$supplier = Supplier::with('maintenances', 'assets', 'licenses')->withCount('maintenances as maintenances_count', 'assets as assets_count', 'licenses as licenses_count')->findOrFail($id);
|
||||
$supplier = Supplier::with('asset_maintenances', 'assets', 'licenses')->withCount('asset_maintenances as asset_maintenances_count', 'assets as assets_count', 'licenses as licenses_count')->findOrFail($id);
|
||||
$this->authorize('delete', $supplier);
|
||||
|
||||
|
||||
@@ -202,8 +202,8 @@ class SuppliersController extends Controller
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/suppliers/message.delete.assoc_assets', ['asset_count' => (int) $supplier->assets_count])));
|
||||
}
|
||||
|
||||
if ($supplier->maintenances_count > 0) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/suppliers/message.delete.assoc_maintenances', ['maintenances_count' => $supplier->maintenances_count])));
|
||||
if ($supplier->asset_maintenances_count > 0) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/suppliers/message.delete.assoc_maintenances', ['asset_maintenances_count' => $supplier->asset_maintenances_count])));
|
||||
}
|
||||
|
||||
if ($supplier->licenses_count > 0) {
|
||||
|
||||
@@ -7,9 +7,18 @@ use App\Helpers\StorageHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use App\Http\Transformers\UploadedFilesTransformer;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Component;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\License;
|
||||
use App\Models\Location;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
@@ -19,6 +28,45 @@ class UploadedFilesController extends Controller
|
||||
{
|
||||
|
||||
|
||||
static $map_object_type = [
|
||||
'accessories' => Accessory::class,
|
||||
'assets' => Asset::class,
|
||||
'components' => Component::class,
|
||||
'consumables' => Consumable::class,
|
||||
'hardware' => Asset::class,
|
||||
'licenses' => License::class,
|
||||
'locations' => Location::class,
|
||||
'models' => AssetModel::class,
|
||||
'users' => User::class,
|
||||
];
|
||||
|
||||
static $map_storage_path = [
|
||||
'accessories' => 'private_uploads/accessories/',
|
||||
'assets' => 'private_uploads/assets/',
|
||||
'components' => 'private_uploads/components/',
|
||||
'consumables' => 'private_uploads/consumables/',
|
||||
'hardware' => 'private_uploads/assets/',
|
||||
'licenses' => 'private_uploads/licenses/',
|
||||
'locations' => 'private_uploads/locations/',
|
||||
'models' => 'private_uploads/assetmodels/',
|
||||
'users' => 'private_uploads/users/',
|
||||
];
|
||||
|
||||
static $map_file_prefix= [
|
||||
'accessories' => 'accessory',
|
||||
'assets' => 'asset',
|
||||
'components' => 'component',
|
||||
'consumables' => 'consumable',
|
||||
'hardware' => 'asset',
|
||||
'licenses' => 'license',
|
||||
'locations' => 'location',
|
||||
'models' => 'model',
|
||||
'users' => 'user',
|
||||
];
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* List files for an object
|
||||
*
|
||||
|
||||
@@ -20,7 +20,6 @@ use App\Models\Consumable;
|
||||
use App\Models\License;
|
||||
use App\Models\User;
|
||||
use App\Notifications\CurrentInventory;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -70,7 +69,6 @@ class UsersController extends Controller
|
||||
'users.notes',
|
||||
'users.permissions',
|
||||
'users.phone',
|
||||
'users.mobile',
|
||||
'users.state',
|
||||
'users.two_factor_enrolled',
|
||||
'users.two_factor_optin',
|
||||
@@ -122,14 +120,6 @@ class UsersController extends Controller
|
||||
$users = $users->where('users.company_id', '=', $request->input('company_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('phone')) {
|
||||
$users = $users->where('users.phone', '=', $request->input('phone'));
|
||||
}
|
||||
|
||||
if ($request->filled('mobile')) {
|
||||
$users = $users->where('users.mobile', '=', $request->input('mobile'));
|
||||
}
|
||||
|
||||
if ($request->filled('location_id')) {
|
||||
$users = $users->where('users.location_id', '=', $request->input('location_id'));
|
||||
}
|
||||
@@ -302,7 +292,6 @@ class UsersController extends Controller
|
||||
'manages_users_count',
|
||||
'manages_locations_count',
|
||||
'phone',
|
||||
'mobile',
|
||||
'address',
|
||||
'city',
|
||||
'state',
|
||||
@@ -833,37 +822,4 @@ class UsersController extends Controller
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.user_not_found')), 200);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run the LDAP sync command to import users from LDAP via API.
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @since 8.2.2
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function syncLdapUsers(Request $request)
|
||||
{
|
||||
$this->authorize('update', User::class);
|
||||
// Call Artisan LDAP import command.
|
||||
|
||||
Artisan::call('snipeit:ldap-sync', ['--location_id' => $request->input('location_id'), '--json_summary' => true]);
|
||||
|
||||
// Collect and parse JSON summary.
|
||||
$ldap_results_json = Artisan::output();
|
||||
$ldap_results = json_decode($ldap_results_json, true);
|
||||
|
||||
if (!$ldap_results) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null,trans('general.no_results')), 200);
|
||||
}
|
||||
|
||||
// Direct user to appropriate status page.
|
||||
if ($ldap_results['error']) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $ldap_results['error_message']), 200);
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, $ldap_results['summary']), 200);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Maintenance;
|
||||
use App\Models\AssetMaintenance;
|
||||
use App\Models\Company;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Carbon\Carbon;
|
||||
@@ -18,23 +17,29 @@ use \Illuminate\Http\RedirectResponse;
|
||||
*
|
||||
* @version v2.0
|
||||
*/
|
||||
class MaintenancesController extends Controller
|
||||
class AssetMaintenancesController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the asset maintenances listing.
|
||||
* the content for the asset maintenances listing, which is generated in getDatatable.
|
||||
*
|
||||
* @todo This should be replaced with middleware and/or policies
|
||||
* @see AssetMaintenancesController::getDatatable() method that generates the JSON response
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
*/
|
||||
public function index() : View
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
return view('maintenances.index');
|
||||
return view('asset_maintenances/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a form view to create a new asset maintenance.
|
||||
*
|
||||
* @see MaintenancesController::postCreate() method that stores the data
|
||||
* @see AssetMaintenancesController::postCreate() method that stores the data
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
@@ -50,21 +55,21 @@ class MaintenancesController extends Controller
|
||||
$asset->asset_id = $asset->id;
|
||||
}
|
||||
|
||||
return view('maintenances/edit')
|
||||
->with('maintenanceType', Maintenance::getImprovementOptions())
|
||||
return view('asset_maintenances/edit')
|
||||
->with('assetMaintenanceType', AssetMaintenance::getImprovementOptions())
|
||||
->with('asset', $asset)
|
||||
->with('item', new Maintenance);
|
||||
->with('item', new AssetMaintenance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates and stores the new asset maintenance
|
||||
*
|
||||
* @see MaintenancesController::getCreate() method for the form
|
||||
* @see AssetMaintenancesController::getCreate() method for the form
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
*/
|
||||
public function store(ImageUploadRequest $request) : RedirectResponse
|
||||
public function store(Request $request) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
|
||||
@@ -73,73 +78,72 @@ class MaintenancesController extends Controller
|
||||
// Loop through the selected assets
|
||||
foreach ($assets as $asset) {
|
||||
|
||||
$maintenance = new Maintenance();
|
||||
$maintenance->supplier_id = $request->input('supplier_id');
|
||||
$maintenance->is_warranty = $request->input('is_warranty');
|
||||
$maintenance->cost = $request->input('cost');
|
||||
$maintenance->notes = $request->input('notes');
|
||||
$assetMaintenance = new AssetMaintenance();
|
||||
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
||||
$assetMaintenance->is_warranty = $request->input('is_warranty');
|
||||
$assetMaintenance->cost = $request->input('cost');
|
||||
$assetMaintenance->notes = $request->input('notes');
|
||||
|
||||
// Save the asset maintenance data
|
||||
$maintenance->asset_id = $asset->id;
|
||||
$maintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
|
||||
$maintenance->name = $request->input('name');
|
||||
$maintenance->start_date = $request->input('start_date');
|
||||
$maintenance->completion_date = $request->input('completion_date');
|
||||
$maintenance->created_by = auth()->id();
|
||||
$assetMaintenance->asset_id = $asset->id;
|
||||
$assetMaintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
|
||||
$assetMaintenance->title = $request->input('title');
|
||||
$assetMaintenance->start_date = $request->input('start_date');
|
||||
$assetMaintenance->completion_date = $request->input('completion_date');
|
||||
$assetMaintenance->created_by = auth()->id();
|
||||
|
||||
if (($maintenance->completion_date !== null)
|
||||
&& ($maintenance->start_date !== '')
|
||||
&& ($maintenance->start_date !== '0000-00-00')
|
||||
if (($assetMaintenance->completion_date !== null)
|
||||
&& ($assetMaintenance->start_date !== '')
|
||||
&& ($assetMaintenance->start_date !== '0000-00-00')
|
||||
) {
|
||||
$startDate = Carbon::parse($maintenance->start_date);
|
||||
$completionDate = Carbon::parse($maintenance->completion_date);
|
||||
$maintenance->asset_maintenance_time = (int) $completionDate->diffInDays($startDate, true);
|
||||
$startDate = Carbon::parse($assetMaintenance->start_date);
|
||||
$completionDate = Carbon::parse($assetMaintenance->completion_date);
|
||||
$assetMaintenance->asset_maintenance_time = (int) $completionDate->diffInDays($startDate, true);
|
||||
}
|
||||
|
||||
$maintenance = $request->handleImages($maintenance);
|
||||
|
||||
// Was the asset maintenance created?
|
||||
if (!$maintenance->save()) {
|
||||
return redirect()->back()->withInput()->withErrors($maintenance->getErrors());
|
||||
if (!$assetMaintenance->save()) {
|
||||
return redirect()->back()->withInput()->withErrors($assetMaintenance->getErrors());
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->route('maintenances.index')
|
||||
->with('success', trans('admin/maintenances/message.create.success'));
|
||||
->with('success', trans('admin/asset_maintenances/message.create.success'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a form view to edit a selected asset maintenance.
|
||||
*
|
||||
* @see MaintenancesController::postEdit() method that stores the data
|
||||
* @see AssetMaintenancesController::postEdit() method that stores the data
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
*/
|
||||
public function edit(Maintenance $maintenance) : View | RedirectResponse
|
||||
public function edit(AssetMaintenance $maintenance) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
$this->authorize('update', $maintenance->asset);
|
||||
|
||||
return view('maintenances/edit')
|
||||
return view('asset_maintenances/edit')
|
||||
->with('selected_assets', $maintenance->asset->pluck('id')->toArray())
|
||||
->with('asset_ids', request()->input('asset_ids', []))
|
||||
->with('maintenanceType', Maintenance::getImprovementOptions())
|
||||
->with('assetMaintenanceType', AssetMaintenance::getImprovementOptions())
|
||||
->with('item', $maintenance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates and stores an update to an asset maintenance
|
||||
*
|
||||
* @see MaintenancesController::postEdit() method that stores the data
|
||||
* @see AssetMaintenancesController::postEdit() method that stores the data
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @param Request $request
|
||||
* @param int $maintenanceId
|
||||
* @param int $assetMaintenanceId
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
*/
|
||||
public function update(ImageUploadRequest $request, Maintenance $maintenance) : View | RedirectResponse
|
||||
public function update(Request $request, AssetMaintenance $maintenance) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
$this->authorize('update', $maintenance->asset);
|
||||
@@ -149,7 +153,7 @@ class MaintenancesController extends Controller
|
||||
$maintenance->cost = $request->input('cost');
|
||||
$maintenance->notes = $request->input('notes');
|
||||
$maintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
|
||||
$maintenance->name = $request->input('name');
|
||||
$maintenance->title = $request->input('title');
|
||||
$maintenance->start_date = $request->input('start_date');
|
||||
$maintenance->completion_date = $request->input('completion_date');
|
||||
|
||||
@@ -172,11 +176,10 @@ class MaintenancesController extends Controller
|
||||
$completionDate = Carbon::parse($maintenance->completion_date);
|
||||
$maintenance->asset_maintenance_time = (int) $completionDate->diffInDays($startDate, true);
|
||||
}
|
||||
$maintenance = $request->handleImages($maintenance);
|
||||
|
||||
if ($maintenance->save()) {
|
||||
return redirect()->route('maintenances.index')
|
||||
->with('success', trans('admin/maintenances/message.edit.success'));
|
||||
->with('success', trans('admin/asset_maintenances/message.edit.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($maintenance->getErrors());
|
||||
@@ -186,11 +189,11 @@ class MaintenancesController extends Controller
|
||||
* Delete an asset maintenance
|
||||
*
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @param int $maintenanceId
|
||||
* @param int $assetMaintenanceId
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
*/
|
||||
public function destroy(Maintenance $maintenance) : RedirectResponse
|
||||
public function destroy(AssetMaintenance $maintenance) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
$this->authorize('update', $maintenance->asset);
|
||||
@@ -198,19 +201,19 @@ class MaintenancesController extends Controller
|
||||
$maintenance->delete();
|
||||
// Redirect to the asset_maintenance management page
|
||||
return redirect()->route('maintenances.index')
|
||||
->with('success', trans('admin/maintenances/message.delete.success'));
|
||||
->with('success', trans('admin/asset_maintenances/message.delete.success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View an asset maintenance
|
||||
*
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @param int $maintenanceId
|
||||
* @param int $assetMaintenanceId
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
*/
|
||||
public function show(Maintenance $maintenance) : View | RedirectResponse
|
||||
public function show(AssetMaintenance $maintenance) : View | RedirectResponse
|
||||
{
|
||||
return view('maintenances.view')->with('maintenance', $maintenance);
|
||||
return view('asset_maintenances/view')->with('assetMaintenance', $maintenance);
|
||||
}
|
||||
}
|
||||
115
app/Http/Controllers/AssetModelsFilesController.php
Normal file
115
app/Http/Controllers/AssetModelsFilesController.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\StorageHelper;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\AssetModel;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use \Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
|
||||
class AssetModelsFilesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Upload a file to the server.
|
||||
*
|
||||
* @param UploadFileRequest $request
|
||||
* @param int $modelId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*@since [v1.0]
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
*/
|
||||
public function store(UploadFileRequest $request, $modelId = null) : RedirectResponse
|
||||
{
|
||||
if (! $model = AssetModel::find($modelId)) {
|
||||
return redirect()->route('models.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize('update', $model);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
if (! Storage::exists('private_uploads/assetmodels')) {
|
||||
Storage::makeDirectory('private_uploads/assetmodels', 775);
|
||||
}
|
||||
|
||||
foreach ($request->file('file') as $file) {
|
||||
|
||||
$file_name = $request->handleFile('private_uploads/assetmodels/','model-'.$model->id,$file);
|
||||
|
||||
$model->logUpload($file_name, $request->get('notes'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withFragment('files')->with('success', trans('general.file_upload_success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withFragment('files')->with('error', trans('admin/hardware/message.upload.nofiles'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for permissions and display the file.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $modelId
|
||||
* @param int $fileId
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function show(AssetModel $model, $fileId = null) : StreamedResponse | Response | RedirectResponse | BinaryFileResponse
|
||||
{
|
||||
|
||||
$this->authorize('view', $model);
|
||||
|
||||
if (! $log = Actionlog::find($fileId)) {
|
||||
return response('No matching record for that model/file', 500)
|
||||
->header('Content-Type', 'text/plain');
|
||||
}
|
||||
|
||||
$file = 'private_uploads/assetmodels/'.$log->filename;
|
||||
|
||||
if (! Storage::exists($file)) {
|
||||
return response('File '.$file.' not found on server', 404)
|
||||
->header('Content-Type', 'text/plain');
|
||||
}
|
||||
|
||||
if (request('inline') == 'true') {
|
||||
|
||||
$headers = [
|
||||
'Content-Disposition' => 'inline',
|
||||
];
|
||||
|
||||
return Storage::download($file, $log->filename, $headers);
|
||||
}
|
||||
|
||||
return StorageHelper::downloader($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the associated file
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $modelId
|
||||
* @param int $fileId
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function destroy(AssetModel $model, $fileId = null) : RedirectResponse
|
||||
{
|
||||
$rel_path = 'private_uploads/assetmodels';
|
||||
$this->authorize('update', $model);
|
||||
$log = Actionlog::find($fileId);
|
||||
if ($log) {
|
||||
if (Storage::exists($rel_path.'/'.$log->filename)) {
|
||||
Storage::delete($rel_path.'/'.$log->filename);
|
||||
}
|
||||
$log->delete();
|
||||
|
||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
|
||||
|
||||
}
|
||||
}
|
||||
108
app/Http/Controllers/Assets/AssetFilesController.php
Normal file
108
app/Http/Controllers/Assets/AssetFilesController.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Assets;
|
||||
|
||||
use App\Helpers\StorageHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use \Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
use \Illuminate\Http\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
|
||||
class AssetFilesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Upload a file to the server.
|
||||
*
|
||||
* @param UploadFileRequest $request
|
||||
* @param int $assetId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*@since [v1.0]
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
*/
|
||||
public function store(UploadFileRequest $request, Asset $asset) : RedirectResponse
|
||||
{
|
||||
|
||||
$this->authorize('update', $asset);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
if (! Storage::exists('private_uploads/assets')) {
|
||||
Storage::makeDirectory('private_uploads/assets', 775);
|
||||
}
|
||||
|
||||
foreach ($request->file('file') as $file) {
|
||||
$file_name = $request->handleFile('private_uploads/assets/','hardware-'.$asset->id, $file);
|
||||
|
||||
$asset->logUpload($file_name, $request->get('notes'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.upload.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', trans('admin/hardware/message.upload.nofiles'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for permissions and display the file.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @param int $fileId
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function show(Asset $asset, $fileId = null) : View | RedirectResponse | Response | StreamedResponse | BinaryFileResponse
|
||||
{
|
||||
|
||||
$this->authorize('view', $asset);
|
||||
|
||||
if ($log = Actionlog::whereNotNull('filename')->where('item_id', $asset->id)->find($fileId)) {
|
||||
$file = 'private_uploads/assets/'.$log->filename;
|
||||
|
||||
if ($log->action_type == 'audit') {
|
||||
$file = 'private_uploads/audits/'.$log->filename;
|
||||
}
|
||||
|
||||
try {
|
||||
return StorageHelper::showOrDownloadFile($file, $log->filename);
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->route('hardware.show', $asset)->with('error', trans('general.file_not_found'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return redirect()->route('hardware.show', $asset)->with('error', trans('general.log_record_not_found'));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the associated file
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $assetId
|
||||
* @param int $fileId
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function destroy(Asset $asset, $fileId = null) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', $asset);
|
||||
$rel_path = 'private_uploads/assets';
|
||||
|
||||
if ($log = Actionlog::find($fileId)) {
|
||||
if (Storage::exists($rel_path.'/'.$log->filename)) {
|
||||
Storage::delete($rel_path.'/'.$log->filename);
|
||||
}
|
||||
$log->delete();
|
||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
|
||||
}
|
||||
|
||||
return redirect()->route('hardware.show', $asset)->with('error', trans('general.log_record_not_found'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -234,13 +234,9 @@ class AssetsController extends Controller
|
||||
$failures[] = join(",", $asset->getErrors()->all());
|
||||
}
|
||||
}
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
}
|
||||
|
||||
session()->put(['checkout_to_type' => $request->get('checkout_to_type'),
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'),
|
||||
'checkout_to_type' => $request->get('checkout_to_type'),
|
||||
'other_redirect' => 'model' ]);
|
||||
|
||||
|
||||
@@ -424,9 +420,6 @@ class AssetsController extends Controller
|
||||
$model = AssetModel::find($request->get('model_id'));
|
||||
if (($model) && ($model->fieldset)) {
|
||||
foreach ($model->fieldset->fields as $field) {
|
||||
if ($field->element == 'checkbox' && !$request->has($field->db_column)) {
|
||||
$asset->{$field->db_column} = null;
|
||||
}
|
||||
if ($request->has($field->db_column)) {
|
||||
if ($field->field_encrypted == '1') {
|
||||
if (Gate::allows('assets.view.encrypted_custom_fields')) {
|
||||
|
||||
@@ -544,7 +544,7 @@ class BulkAssetsController extends Controller
|
||||
session()->put('bulk_asset_errors',$error_array);
|
||||
|
||||
return redirect()
|
||||
->route('hardware.index')
|
||||
->route('hardware.bulkedit')
|
||||
->with('bulk_asset_errors', $error_array)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
@@ -88,12 +88,7 @@ class ComponentsController extends Controller
|
||||
|
||||
$component = $request->handleImages($component);
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
}
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
if ($component->save()) {
|
||||
return Helper::getRedirectOption($request, $component->id, 'Components')
|
||||
|
||||
138
app/Http/Controllers/Components/ComponentsFilesController.php
Normal file
138
app/Http/Controllers/Components/ComponentsFilesController.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Components;
|
||||
|
||||
use App\Helpers\StorageHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Component;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ComponentsFilesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Validates and stores files associated with a component.
|
||||
*
|
||||
* @param UploadFileRequest $request
|
||||
* @param int $componentId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*@author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @todo Switch to using the AssetFileRequest form request validator.
|
||||
*/
|
||||
public function store(UploadFileRequest $request, $componentId = null)
|
||||
{
|
||||
|
||||
if (config('app.lock_passwords')) {
|
||||
return redirect()->route('components.show', ['component'=>$componentId])->with('error', trans('general.feature_disabled'));
|
||||
}
|
||||
|
||||
$component = Component::find($componentId);
|
||||
|
||||
if (isset($component->id)) {
|
||||
$this->authorize('update', $component);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
if (! Storage::exists('private_uploads/components')) {
|
||||
Storage::makeDirectory('private_uploads/components', 775);
|
||||
}
|
||||
|
||||
foreach ($request->file('file') as $file) {
|
||||
$file_name = $request->handleFile('private_uploads/components/','component-'.$component->id, $file);
|
||||
|
||||
//Log the upload to the log
|
||||
$component->logUpload($file_name, e($request->input('notes')));
|
||||
}
|
||||
|
||||
|
||||
return redirect()->route('components.show', $component->id)->withFragment('files')->with('success', trans('general.file_upload_success'));
|
||||
|
||||
}
|
||||
|
||||
return redirect()->route('components.show', $component->id)->with('error', trans('general.no_files_uploaded'));
|
||||
}
|
||||
// Prepare the error message
|
||||
return redirect()->route('components.index')
|
||||
->with('error', trans('general.file_does_not_exist'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the selected component file.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $componentId
|
||||
* @param int $fileId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($componentId = null, $fileId = null)
|
||||
{
|
||||
$component = Component::find($componentId);
|
||||
|
||||
// the asset is valid
|
||||
if (isset($component->id)) {
|
||||
$this->authorize('update', $component);
|
||||
$log = Actionlog::find($fileId);
|
||||
|
||||
// Remove the file if one exists
|
||||
if (Storage::exists('components/'.$log->filename)) {
|
||||
try {
|
||||
Storage::delete('components/'.$log->filename);
|
||||
} catch (\Exception $e) {
|
||||
Log::debug($e);
|
||||
}
|
||||
}
|
||||
|
||||
$log->delete();
|
||||
|
||||
return redirect()->back()->withFragment('files')
|
||||
->with('success', trans('admin/hardware/message.deletefile.success'));
|
||||
}
|
||||
|
||||
// Redirect to the licence management page
|
||||
return redirect()->route('components.index')->with('error', trans('general.file_does_not_exist'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the selected file to be viewed.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.4]
|
||||
* @param int $componentId
|
||||
* @param int $fileId
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($componentId = null, $fileId = null)
|
||||
{
|
||||
Log::debug('Private filesystem is: '.config('filesystems.default'));
|
||||
|
||||
|
||||
// the component is valid
|
||||
if ($component = Component::find($componentId)) {
|
||||
$this->authorize('view', $component);
|
||||
$this->authorize('components.files', $component);
|
||||
|
||||
if ($log = Actionlog::whereNotNull('filename')->where('item_id', $component->id)->find($fileId)) {
|
||||
|
||||
$file = 'private_uploads/components/'.$log->filename;
|
||||
|
||||
try {
|
||||
return StorageHelper::showOrDownloadFile($file, $log->filename);
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->route('components.show', ['component' => $component])->with('error', trans('general.file_not_found'));
|
||||
}
|
||||
}
|
||||
return redirect()->route('components.show', ['component' => $component])->with('error', trans('general.log_record_not_found'));
|
||||
|
||||
}
|
||||
|
||||
return redirect()->route('components.index')->with('error', trans('general.file_does_not_exist', ['id' => $fileId]));
|
||||
}
|
||||
}
|
||||
@@ -98,12 +98,7 @@ class ConsumablesController extends Controller
|
||||
$consumable = $request->handleImages($consumable);
|
||||
}
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
}
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
if ($consumable->save()) {
|
||||
return Helper::getRedirectOption($request, $consumable->id, 'Consumables')
|
||||
|
||||
134
app/Http/Controllers/Consumables/ConsumablesFilesController.php
Normal file
134
app/Http/Controllers/Consumables/ConsumablesFilesController.php
Normal file
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Consumables;
|
||||
|
||||
use App\Helpers\StorageHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Consumable;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Symfony\Consumable\HttpFoundation\JsonResponse;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
class ConsumablesFilesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Validates and stores files associated with a consumable.
|
||||
*
|
||||
* @param UploadFileRequest $request
|
||||
* @param int $consumableId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*@author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @todo Switch to using the AssetFileRequest form request validator.
|
||||
*/
|
||||
public function store(UploadFileRequest $request, $consumableId = null)
|
||||
{
|
||||
if (config('app.lock_passwords')) {
|
||||
return redirect()->route('consumables.show', ['consumable'=>$consumableId])->with('error', trans('general.feature_disabled'));
|
||||
}
|
||||
|
||||
$consumable = Consumable::find($consumableId);
|
||||
|
||||
if (isset($consumable->id)) {
|
||||
$this->authorize('update', $consumable);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
if (! Storage::exists('private_uploads/consumables')) {
|
||||
Storage::makeDirectory('private_uploads/consumables', 775);
|
||||
}
|
||||
|
||||
foreach ($request->file('file') as $file) {
|
||||
$file_name = $request->handleFile('private_uploads/consumables/','consumable-'.$consumable->id, $file);
|
||||
|
||||
//Log the upload to the log
|
||||
$consumable->logUpload($file_name, e($request->input('notes')));
|
||||
}
|
||||
|
||||
|
||||
return redirect()->route('consumables.show', $consumable->id)->withFragment('files')->with('success', trans('general.file_upload_success'));
|
||||
|
||||
}
|
||||
|
||||
return redirect()->route('consumables.show', $consumable->id)->with('error', trans('general.no_files_uploaded'));
|
||||
}
|
||||
// Prepare the error message
|
||||
return redirect()->route('consumables.index')
|
||||
->with('error', trans('general.file_does_not_exist'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the selected consumable file.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $consumableId
|
||||
* @param int $fileId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($consumableId = null, $fileId = null)
|
||||
{
|
||||
$consumable = Consumable::find($consumableId);
|
||||
|
||||
// the asset is valid
|
||||
if (isset($consumable->id)) {
|
||||
$this->authorize('update', $consumable);
|
||||
$log = Actionlog::find($fileId);
|
||||
|
||||
// Remove the file if one exists
|
||||
if (Storage::exists('consumables/'.$log->filename)) {
|
||||
try {
|
||||
Storage::delete('consumables/'.$log->filename);
|
||||
} catch (\Exception $e) {
|
||||
Log::debug($e);
|
||||
}
|
||||
}
|
||||
|
||||
$log->delete();
|
||||
|
||||
return redirect()->back()->withFragment('files')
|
||||
->with('success', trans('admin/hardware/message.deletefile.success'));
|
||||
}
|
||||
|
||||
// Redirect to the licence management page
|
||||
return redirect()->route('consumables.index')->with('error', trans('general.file_does_not_exist'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the selected file to be viewed.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.4]
|
||||
* @param int $consumableId
|
||||
* @param int $fileId
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($consumableId = null, $fileId = null)
|
||||
{
|
||||
$consumable = Consumable::find($consumableId);
|
||||
|
||||
// the consumable is valid
|
||||
if (isset($consumable->id)) {
|
||||
$this->authorize('view', $consumable);
|
||||
$this->authorize('consumables.files', $consumable);
|
||||
|
||||
if ($log = Actionlog::whereNotNull('filename')->where('item_id', $consumable->id)->find($fileId)) {
|
||||
$file = 'private_uploads/consumables/'.$log->filename;
|
||||
|
||||
try {
|
||||
return StorageHelper::showOrDownloadFile($file, $log->filename);
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->route('consumables.show', ['consumable' => $consumable])->with('error', trans('general.file_not_found'));
|
||||
}
|
||||
}
|
||||
// The log record doesn't exist somehow
|
||||
return redirect()->route('consumables.show', ['consumable' => $consumable])->with('error', trans('general.log_record_not_found'));
|
||||
|
||||
}
|
||||
|
||||
return redirect()->route('consumables.index')->with('error', trans('general.file_does_not_exist', ['id' => $fileId]));
|
||||
}
|
||||
}
|
||||
@@ -22,15 +22,6 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Component;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\License;
|
||||
use App\Models\Location;
|
||||
use App\Models\Maintenance;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
@@ -41,45 +32,6 @@ abstract class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
static $map_object_type = [
|
||||
'accessories' => Accessory::class,
|
||||
'maintenances' => Maintenance::class,
|
||||
'assets' => Asset::class,
|
||||
'components' => Component::class,
|
||||
'consumables' => Consumable::class,
|
||||
'hardware' => Asset::class,
|
||||
'licenses' => License::class,
|
||||
'locations' => Location::class,
|
||||
'models' => AssetModel::class,
|
||||
'users' => User::class,
|
||||
];
|
||||
|
||||
static $map_storage_path = [
|
||||
'accessories' => 'private_uploads/accessories/',
|
||||
'maintenances' => 'private_uploads/maintenances/',
|
||||
'assets' => 'private_uploads/assets/',
|
||||
'components' => 'private_uploads/components/',
|
||||
'consumables' => 'private_uploads/consumables/',
|
||||
'hardware' => 'private_uploads/assets/',
|
||||
'licenses' => 'private_uploads/licenses/',
|
||||
'locations' => 'private_uploads/locations/',
|
||||
'models' => 'private_uploads/models/',
|
||||
'users' => 'private_uploads/users/',
|
||||
];
|
||||
|
||||
static $map_file_prefix= [
|
||||
'accessories' => 'accessory',
|
||||
'maintenances' => 'maintenance',
|
||||
'assets' => 'asset',
|
||||
'components' => 'component',
|
||||
'consumables' => 'consumable',
|
||||
'hardware' => 'asset',
|
||||
'licenses' => 'license',
|
||||
'locations' => 'location',
|
||||
'models' => 'model',
|
||||
'users' => 'user',
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
view()->share('signedIn', Auth::check());
|
||||
|
||||
@@ -144,9 +144,10 @@ class CustomFieldsController extends Controller
|
||||
*/
|
||||
public function deleteFieldFromFieldset($field_id, $fieldset_id) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', CustomField::class);
|
||||
$field = CustomField::find($field_id);
|
||||
|
||||
$this->authorize('update', $field);
|
||||
|
||||
// Check that the field exists - this is mostly related to the demo, where we
|
||||
// rewrite the data every x minutes, so it's possible someone might be disassociating
|
||||
// a field from a fieldset just as we're wiping the database
|
||||
@@ -156,12 +157,11 @@ class CustomFieldsController extends Controller
|
||||
return redirect()->route('fieldsets.show', ['fieldset' => $fieldset_id])
|
||||
->with('success', trans('admin/custom_fields/message.field.delete.success'));
|
||||
} else {
|
||||
return redirect()->back()->with('error', trans('admin/custom_fields/message.field.delete.error'))
|
||||
->withInput();
|
||||
return redirect()->back()->withErrors(['message' => "Field is in use and cannot be deleted."]);
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', trans('admin/custom_fields/message.field.delete.error'));
|
||||
return redirect()->back()->withErrors(['message' => "Error deleting field from fieldset"]);
|
||||
|
||||
|
||||
}
|
||||
@@ -172,16 +172,20 @@ class CustomFieldsController extends Controller
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @since [v1.8]
|
||||
*/
|
||||
public function destroy(CustomField $field) : RedirectResponse
|
||||
public function destroy($field_id) : RedirectResponse
|
||||
{
|
||||
$this->authorize('delete', CustomField::class);
|
||||
if ($field = CustomField::find($field_id)) {
|
||||
$this->authorize('delete', $field);
|
||||
|
||||
if (($field->fieldset) && ($field->fieldset->count() > 0)) {
|
||||
return redirect()->back()->with('error', trans('admin/custom_fields/message.field.delete.in_use'));
|
||||
if (($field->fieldset) && ($field->fieldset->count() > 0)) {
|
||||
return redirect()->back()->withErrors(['message' => 'Field is in-use']);
|
||||
}
|
||||
$field->delete();
|
||||
return redirect()->route("fields.index")
|
||||
->with("success", trans('admin/custom_fields/message.field.delete.success'));
|
||||
}
|
||||
$field->delete();
|
||||
return redirect()->route("fields.index")
|
||||
->with("success", trans('admin/custom_fields/message.field.delete.success'));
|
||||
|
||||
return redirect()->back()->withErrors(['message' => 'Field does not exist']);
|
||||
}
|
||||
|
||||
|
||||
@@ -194,7 +198,7 @@ class CustomFieldsController extends Controller
|
||||
*/
|
||||
public function edit(Request $request, CustomField $field) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('update', CustomField::class);
|
||||
$this->authorize('update', $field);
|
||||
$fieldsets = CustomFieldset::get();
|
||||
$customFormat = '';
|
||||
if ((stripos($field->format, 'regex') === 0) && ($field->format !== CustomField::PREDEFINED_FORMATS['MAC'])) {
|
||||
@@ -224,7 +228,7 @@ class CustomFieldsController extends Controller
|
||||
*/
|
||||
public function update(CustomFieldRequest $request, CustomField $field) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', CustomField::class);
|
||||
$this->authorize('update', $field);
|
||||
$show_in_email = $request->get("show_in_email", 0);
|
||||
$display_in_user_view = $request->get("display_in_user_view", 0);
|
||||
|
||||
@@ -261,6 +265,7 @@ class CustomFieldsController extends Controller
|
||||
|
||||
if ($field->save()) {
|
||||
|
||||
|
||||
// Sync fields with fieldsets
|
||||
$fieldset_array = $request->input('associate_fieldsets');
|
||||
if ($request->has('associate_fieldsets') && (is_array($fieldset_array))) {
|
||||
|
||||
@@ -87,9 +87,7 @@ class LicenseCheckinController extends Controller
|
||||
|
||||
if($licenseSeat->assigned_to != null){
|
||||
$return_to = User::withTrashed()->find($licenseSeat->assigned_to);
|
||||
if ($return_to) {
|
||||
session()->put('checkedInFrom', $return_to->id);
|
||||
}
|
||||
session()->put('checkedInFrom', $return_to->id);
|
||||
} else {
|
||||
$return_to = Asset::find($licenseSeat->asset_id);
|
||||
}
|
||||
|
||||
132
app/Http/Controllers/Licenses/LicenseFilesController.php
Normal file
132
app/Http/Controllers/Licenses/LicenseFilesController.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Licenses;
|
||||
|
||||
use App\Helpers\StorageHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\License;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class LicenseFilesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Validates and stores files associated with a license.
|
||||
*
|
||||
* @param UploadFileRequest $request
|
||||
* @param int $licenseId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @todo Switch to using the AssetFileRequest form request validator.
|
||||
*/
|
||||
public function store(UploadFileRequest $request, $licenseId = null)
|
||||
{
|
||||
$license = License::find($licenseId);
|
||||
|
||||
if (isset($license->id)) {
|
||||
$this->authorize('update', $license);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
if (! Storage::exists('private_uploads/licenses')) {
|
||||
Storage::makeDirectory('private_uploads/licenses', 775);
|
||||
}
|
||||
|
||||
foreach ($request->file('file') as $file) {
|
||||
$file_name = $request->handleFile('private_uploads/licenses/','license-'.$license->id, $file);
|
||||
|
||||
//Log the upload to the log
|
||||
$license->logUpload($file_name, e($request->input('notes')));
|
||||
}
|
||||
|
||||
|
||||
return redirect()->route('licenses.show', $license->id)->with('success', trans('admin/licenses/message.upload.success'));
|
||||
|
||||
}
|
||||
|
||||
return redirect()->route('licenses.show', $license->id)->with('error', trans('admin/licenses/message.upload.nofiles'));
|
||||
}
|
||||
// Prepare the error message
|
||||
return redirect()->route('licenses.index')
|
||||
->with('error', trans('admin/licenses/message.does_not_exist'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the selected license file.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $licenseId
|
||||
* @param int $fileId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($licenseId = null, $fileId = null)
|
||||
{
|
||||
if ($license = License::find($licenseId)) {
|
||||
|
||||
$this->authorize('update', $license);
|
||||
|
||||
if ($log = Actionlog::find($fileId)) {
|
||||
|
||||
// Remove the file if one exists
|
||||
if (Storage::exists('licenses/'.$log->filename)) {
|
||||
try {
|
||||
Storage::delete('licenses/'.$log->filename);
|
||||
} catch (\Exception $e) {
|
||||
Log::debug($e);
|
||||
}
|
||||
}
|
||||
|
||||
$log->delete();
|
||||
|
||||
return redirect()->back()
|
||||
->with('success', trans('admin/hardware/message.deletefile.success'));
|
||||
}
|
||||
|
||||
return redirect()->route('licenses.index')->with('error', trans('general.log_does_not_exist'));
|
||||
}
|
||||
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the selected file to be viewed.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.4]
|
||||
* @param int $licenseId
|
||||
* @param int $fileId
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show($licenseId = null, $fileId = null, $download = true)
|
||||
{
|
||||
$license = License::find($licenseId);
|
||||
|
||||
// the license is valid
|
||||
if (isset($license->id)) {
|
||||
$this->authorize('view', $license);
|
||||
$this->authorize('licenses.files', $license);
|
||||
|
||||
if ($log = Actionlog::whereNotNull('filename')->where('item_id', $license->id)->find($fileId)) {
|
||||
$file = 'private_uploads/licenses/'.$log->filename;
|
||||
|
||||
try {
|
||||
return StorageHelper::showOrDownloadFile($file, $log->filename);
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->route('licenses.show', ['licenses' => $license])->with('error', trans('general.file_not_found'));
|
||||
}
|
||||
}
|
||||
|
||||
// The log record doesn't exist somehow
|
||||
return redirect()->route('licenses.show', ['licenses' => $license])->with('error', trans('general.log_record_not_found'));
|
||||
|
||||
}
|
||||
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist', ['id' => $fileId]));
|
||||
}
|
||||
}
|
||||
@@ -102,11 +102,7 @@ class LicensesController extends Controller
|
||||
$license->created_by = auth()->id();
|
||||
$license->min_amt = $request->input('min_amt');
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
}
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
if ($license->save()) {
|
||||
return Helper::getRedirectOption($request, $license->id, 'Licenses')
|
||||
|
||||
111
app/Http/Controllers/LocationsFilesController.php
Normal file
111
app/Http/Controllers/LocationsFilesController.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\StorageHelper;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Location;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use \Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
|
||||
class LocationsFilesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Upload a file to the server.
|
||||
*
|
||||
* @param UploadFileRequest $request
|
||||
* @param int $modelId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*@since [v1.0]
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
*/
|
||||
public function store(UploadFileRequest $request, Location $location) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', $location);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
|
||||
if (! Storage::exists('private_uploads/locations')) {
|
||||
Storage::makeDirectory('private_uploads/locations', 775);
|
||||
}
|
||||
|
||||
foreach ($request->file('file') as $file) {
|
||||
$file_name = $request->handleFile('private_uploads/locations/','location-'.$location->id, $file);
|
||||
$location->logUpload($file_name, $request->get('notes'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withFragment('files')->with('success', trans('general.file_upload_success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withFragment('files')->with('error', trans('admin/hardware/message.upload.nofiles'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for permissions and display the file.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $modelId
|
||||
* @param int $fileId
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function show(Location $location, $fileId = null) : StreamedResponse | Response | RedirectResponse | BinaryFileResponse
|
||||
{
|
||||
|
||||
$this->authorize('view', $location);
|
||||
|
||||
if (! $log = Actionlog::find($fileId)) {
|
||||
return redirect()->back()->withFragment('files')->with('error', 'No matching file record');
|
||||
}
|
||||
|
||||
$file = 'private_uploads/locations/'.$log->filename;
|
||||
|
||||
if (! Storage::exists($file)) {
|
||||
return redirect()->back()->withFragment('files')->with('error', 'No matching file on server');
|
||||
}
|
||||
|
||||
if (request('inline') == 'true') {
|
||||
|
||||
$headers = [
|
||||
'Content-Disposition' => 'inline',
|
||||
];
|
||||
|
||||
return Storage::download($file, $log->filename, $headers);
|
||||
}
|
||||
|
||||
return StorageHelper::downloader($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the associated file
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $modelId
|
||||
* @param int $fileId
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function destroy(Location $location, $fileId = null) : RedirectResponse
|
||||
{
|
||||
$rel_path = 'private_uploads/locations';
|
||||
$this->authorize('update', $location);
|
||||
$log = Actionlog::find($fileId);
|
||||
|
||||
if ($log) {
|
||||
|
||||
// This should be moved to purge
|
||||
// if (Storage::exists($rel_path.'/'.$log->filename)) {
|
||||
// Storage::delete($rel_path.'/'.$log->filename);
|
||||
// }
|
||||
$log->delete();
|
||||
|
||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/hardware/message.deletefile.success'));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Category;
|
||||
use App\Models\Maintenance;
|
||||
use App\Models\AssetMaintenance;
|
||||
use App\Models\CheckoutAcceptance;
|
||||
use App\Models\Company;
|
||||
use App\Models\CustomField;
|
||||
@@ -17,11 +17,13 @@ use App\Models\Depreciation;
|
||||
use App\Models\License;
|
||||
use App\Models\ReportTemplate;
|
||||
use App\Models\Setting;
|
||||
use App\Notifications\CheckoutAssetNotification;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
use League\Csv\Reader;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
@@ -1036,11 +1038,11 @@ class ReportsController extends Controller
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
*/
|
||||
public function getMaintenancesReport() : View
|
||||
public function getAssetMaintenancesReport() : View
|
||||
{
|
||||
$this->authorize('reports.view');
|
||||
|
||||
return view('reports.maintenances');
|
||||
return view('reports.asset_maintenances');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1049,11 +1051,11 @@ class ReportsController extends Controller
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
*/
|
||||
public function exportMaintenancesReport() : Response
|
||||
public function exportAssetMaintenancesReport() : Response
|
||||
{
|
||||
$this->authorize('reports.view');
|
||||
// Grab all the improvements
|
||||
$Maintenances = Maintenance::with('asset', 'supplier')
|
||||
$assetMaintenances = AssetMaintenance::with('asset', 'supplier')
|
||||
->orderBy('created_at', 'DESC')
|
||||
->get();
|
||||
|
||||
@@ -1061,36 +1063,36 @@ class ReportsController extends Controller
|
||||
|
||||
$header = [
|
||||
trans('admin/hardware/table.asset_tag'),
|
||||
trans('admin/maintenances/table.asset_name'),
|
||||
trans('admin/asset_maintenances/table.asset_name'),
|
||||
trans('general.supplier'),
|
||||
trans('admin/maintenances/form.asset_maintenance_type'),
|
||||
trans('admin/maintenances/form.title'),
|
||||
trans('admin/maintenances/form.start_date'),
|
||||
trans('admin/maintenances/form.completion_date'),
|
||||
trans('admin/maintenances/form.asset_maintenance_time'),
|
||||
trans('admin/maintenances/form.cost'),
|
||||
trans('admin/asset_maintenances/form.asset_maintenance_type'),
|
||||
trans('admin/asset_maintenances/form.title'),
|
||||
trans('admin/asset_maintenances/form.start_date'),
|
||||
trans('admin/asset_maintenances/form.completion_date'),
|
||||
trans('admin/asset_maintenances/form.asset_maintenance_time'),
|
||||
trans('admin/asset_maintenances/form.cost'),
|
||||
];
|
||||
|
||||
$header = array_map('trim', $header);
|
||||
$rows[] = implode(',', $header);
|
||||
|
||||
foreach ($Maintenances as $maintenance) {
|
||||
foreach ($assetMaintenances as $assetMaintenance) {
|
||||
$row = [];
|
||||
$row[] = str_replace(',', '', e($maintenance->asset->asset_tag));
|
||||
$row[] = str_replace(',', '', e($maintenance->asset->name));
|
||||
$row[] = str_replace(',', '', e($maintenance->supplier->name));
|
||||
$row[] = e($maintenance->improvement_type);
|
||||
$row[] = e($maintenance->name);
|
||||
$row[] = e($maintenance->start_date);
|
||||
$row[] = e($maintenance->completion_date);
|
||||
if (is_null($maintenance->asset_maintenance_time)) {
|
||||
$row[] = str_replace(',', '', e($assetMaintenance->asset->asset_tag));
|
||||
$row[] = str_replace(',', '', e($assetMaintenance->asset->name));
|
||||
$row[] = str_replace(',', '', e($assetMaintenance->supplier->name));
|
||||
$row[] = e($assetMaintenance->improvement_type);
|
||||
$row[] = e($assetMaintenance->title);
|
||||
$row[] = e($assetMaintenance->start_date);
|
||||
$row[] = e($assetMaintenance->completion_date);
|
||||
if (is_null($assetMaintenance->asset_maintenance_time)) {
|
||||
$improvementTime = (int) Carbon::now()
|
||||
->diffInDays(Carbon::parse($maintenance->start_date), true);
|
||||
->diffInDays(Carbon::parse($assetMaintenance->start_date), true);
|
||||
} else {
|
||||
$improvementTime = (int) $maintenance->asset_maintenance_time;
|
||||
$improvementTime = (int) $assetMaintenance->asset_maintenance_time;
|
||||
}
|
||||
$row[] = $improvementTime;
|
||||
$row[] = trans('general.currency') . Helper::formatCurrencyOutput($maintenance->cost);
|
||||
$row[] = trans('general.currency') . Helper::formatCurrencyOutput($assetMaintenance->cost);
|
||||
$rows[] = implode(',', $row);
|
||||
}
|
||||
|
||||
|
||||
@@ -1084,7 +1084,6 @@ class SettingsController extends Controller
|
||||
|
||||
if (! config('app.lock_passwords')) {
|
||||
if (Storage::exists($path.'/'.$filename)) {
|
||||
Log::warning('User '.auth()->user()->username.' is attempting to download backup file: '.$filename);
|
||||
return StorageHelper::downloader($path.'/'.$filename);
|
||||
} else {
|
||||
// Redirect to the backup page
|
||||
@@ -1112,7 +1111,6 @@ class SettingsController extends Controller
|
||||
if (Storage::exists($path . '/' . $filename)) {
|
||||
|
||||
try {
|
||||
Log::warning('User '.auth()->user()->username.' is attempting to delete backup file: '.$filename);
|
||||
Storage::delete($path . '/' . $filename);
|
||||
return redirect()->route('settings.backups.index')->with('success', trans('admin/settings/message.backup.file_deleted'));
|
||||
} catch (\Exception $e) {
|
||||
@@ -1192,7 +1190,7 @@ class SettingsController extends Controller
|
||||
'--force' => true,
|
||||
]);
|
||||
|
||||
Log::warning('User '.auth()->user()->username.' is attempting to restore from: '. storage_path($path).'/'.$filename);
|
||||
Log::debug('Attempting to restore from: '. storage_path($path).'/'.$filename);
|
||||
|
||||
$restore_params = [
|
||||
'--force' => true,
|
||||
@@ -1341,11 +1339,9 @@ class SettingsController extends Controller
|
||||
'name' => config('mail.from.name'),
|
||||
'email' => config('mail.from.address'),
|
||||
])->notify(new MailTest());
|
||||
Log::debug('Attempting to send mail to '.config('mail.from.address'));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('mail_sent.mail_sent')));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Mail sent from '.config('mail.from.address') .' with errors '. $e->getMessage());
|
||||
Log::debug($e);
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, $e->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Supplier;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use \Illuminate\Contracts\View\View;
|
||||
|
||||
@@ -121,7 +122,7 @@ class SuppliersController extends Controller
|
||||
public function destroy($supplierId) : RedirectResponse
|
||||
{
|
||||
$this->authorize('delete', Supplier::class);
|
||||
if (is_null($supplier = Supplier::with('maintenances', 'assets', 'licenses')->withCount('maintenances as maintenances_count', 'assets as assets_count', 'licenses as licenses_count')->find($supplierId))) {
|
||||
if (is_null($supplier = Supplier::with('asset_maintenances', 'assets', 'licenses')->withCount('asset_maintenances as asset_maintenances_count', 'assets as assets_count', 'licenses as licenses_count')->find($supplierId))) {
|
||||
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.not_found'));
|
||||
}
|
||||
|
||||
@@ -129,8 +130,8 @@ class SuppliersController extends Controller
|
||||
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.delete.assoc_assets', ['asset_count' => (int) $supplier->assets_count]));
|
||||
}
|
||||
|
||||
if ($supplier->maintenances_count > 0) {
|
||||
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.delete.assoc_maintenances', ['maintenances_count' => $supplier->maintenances_count]));
|
||||
if ($supplier->asset_maintenances_count > 0) {
|
||||
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.delete.assoc_maintenances', ['asset_maintenances_count' => $supplier->asset_maintenances_count]));
|
||||
}
|
||||
|
||||
if ($supplier->licenses_count > 0) {
|
||||
|
||||
@@ -1,162 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\StorageHelper;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use App\Models\Actionlog;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
/**
|
||||
* This controller provide the health route for
|
||||
* the Snipe-IT Asset Management application.
|
||||
*
|
||||
* @version v1.0
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
|
||||
*/
|
||||
class UploadedFilesController extends Controller
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Accepts a POST to upload a file to the server.
|
||||
*
|
||||
* @param \App\Http\Requests\UploadFileRequest $request
|
||||
* @param string $object_type the type of object to upload the file to
|
||||
* @param int $id the ID of the object to store so we can check permisisons
|
||||
* @since [v8.2.2]
|
||||
* @author [A. Gianotto <snipe@snipe.net>]
|
||||
*/
|
||||
public function store(UploadFileRequest $request, $object_type, $id) : RedirectResponse
|
||||
{
|
||||
|
||||
// Check the permissions to make sure the user can view the object
|
||||
$object = self::$map_object_type[$object_type]::find($id);
|
||||
$this->authorize('update', $object);
|
||||
|
||||
if (!$object) {
|
||||
return redirect()->back()->withFragment('files')->with('error',trans('general.file_upload_status.invalid_object'));
|
||||
}
|
||||
|
||||
// If the file storage directory doesn't exist, create it
|
||||
if (! Storage::exists(self::$map_storage_path[$object_type])) {
|
||||
Storage::makeDirectory(self::$map_storage_path[$object_type], 775);
|
||||
}
|
||||
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
// Loop over the attached files and add them to the object
|
||||
foreach ($request->file('file') as $file) {
|
||||
$file_name = $request->handleFile(self::$map_storage_path[$object_type], self::$map_file_prefix[$object_type].'-'.$object->id, $file);
|
||||
$files[] = $file_name;
|
||||
$object->logUpload($file_name, $request->get('notes'));
|
||||
}
|
||||
|
||||
$files = Actionlog::select('action_logs.*')->where('action_type', '=', 'uploaded')
|
||||
->where('item_type', '=', self::$map_object_type[$object_type])
|
||||
->where('item_id', '=', $id)->whereIn('filename', $files)
|
||||
->get();
|
||||
|
||||
return redirect()->back()->withFragment('files')->with('success', trans_choice('general.file_upload_status.upload.success', count($files)));
|
||||
}
|
||||
|
||||
// No files were submitted
|
||||
return redirect()->back()->withFragment('files')->with('error', trans('general.file_upload_status.nofiles'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check for permissions and display the file.
|
||||
* This isn't currently used, but is here for future use.
|
||||
*
|
||||
* @param \App\Http\Requests\UploadFileRequest $request
|
||||
* @param string $object_type the type of object to upload the file to
|
||||
* @param int $id the ID of the object to delete from so we can check permisisons
|
||||
* @param $file_id the ID of the file to show from the action_logs table
|
||||
* @since [v8.2.2]
|
||||
* @author [A. Gianotto <snipe@snipe.net>]
|
||||
*/
|
||||
public function show($object_type, $id, $file_id) : RedirectResponse | StreamedResponse | Storage | StorageHelper | BinaryFileResponse
|
||||
{
|
||||
// Check the permissions to make sure the user can view the object
|
||||
$object = self::$map_object_type[$object_type]::find($id);
|
||||
$this->authorize('view', $object);
|
||||
|
||||
if (!$object) {
|
||||
return redirect()->back()->withFragment('files')->with('error',trans('general.file_upload_status.invalid_object'));
|
||||
}
|
||||
|
||||
|
||||
// Check that the file being requested exists for the object
|
||||
if (! $log = Actionlog::whereNotNull('filename')->where('item_type', self::$map_object_type[$object_type])->where('item_id', $object->id)->find($file_id))
|
||||
{
|
||||
return redirect()->back()->withFragment('files')->with('error', trans('general.file_upload_status.invalid_id'));
|
||||
}
|
||||
|
||||
|
||||
if (! Storage::exists(self::$map_storage_path[$object_type].'/'.$log->filename))
|
||||
{
|
||||
return redirect()->back()->withFragment('files')->with('error', trans('general.file_upload_status.file_not_found'));
|
||||
}
|
||||
|
||||
if (request('inline') == 'true') {
|
||||
$headers = [
|
||||
'Content-Disposition' => 'inline',
|
||||
];
|
||||
return Storage::download(self::$map_storage_path[$object_type].'/'.$log->filename, $log->filename, $headers);
|
||||
}
|
||||
|
||||
return StorageHelper::downloader(self::$map_storage_path[$object_type].'/'.$log->filename);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the associated file
|
||||
*
|
||||
* @param \App\Http\Requests\UploadFileRequest $request
|
||||
* @param string $object_type the type of object to upload the file to
|
||||
* @param int $id the ID of the object to delete from so we can check permisisons
|
||||
* @param $file_id the ID of the file to delete from the action_logs table
|
||||
* @since [v8.2.2]
|
||||
* @author [A. Gianotto <snipe@snipe.net>]
|
||||
*/
|
||||
public function destroy($object_type, $id, $file_id) : RedirectResponse
|
||||
{
|
||||
|
||||
// Check the permissions to make sure the user can view the object
|
||||
$object = self::$map_object_type[$object_type]::find($id);
|
||||
$this->authorize('update', self::$map_object_type[$object_type]);
|
||||
|
||||
if (!$object) {
|
||||
return redirect()->back()->withFragment('files')->with('error',trans('general.file_upload_status.invalid_object'));
|
||||
}
|
||||
|
||||
|
||||
// Check for the file
|
||||
$log = Actionlog::find($file_id)->where('item_type', self::$map_object_type[$object_type])
|
||||
->where('item_id', $object->id)->first();
|
||||
|
||||
if ($log) {
|
||||
// Check the file actually exists, and delete it
|
||||
if (Storage::exists(self::$map_storage_path[$object_type].'/'.$log->filename)) {
|
||||
Storage::delete(self::$map_storage_path[$object_type].'/'.$log->filename);
|
||||
}
|
||||
// Delete the record of the file
|
||||
if ($log->delete()) {
|
||||
return redirect()->back()->withFragment('files')->with('success', trans_choice('general.file_upload_status.delete.success', 1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// The file doesn't seem to really exist, so report an error
|
||||
return redirect()->back()->withFragment('files')->with('success', trans_choice('general.file_upload_status.delete.error', 1));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
119
app/Http/Controllers/Users/UserFilesController.php
Normal file
119
app/Http/Controllers/Users/UserFilesController.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Users;
|
||||
|
||||
use App\Helpers\StorageHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\UploadFileRequest;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\User;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class UserFilesController extends Controller
|
||||
{
|
||||
/**
|
||||
* Return JSON response with a list of user details for the getIndex() view.
|
||||
*
|
||||
* @param UploadFileRequest $request
|
||||
* @param int $userId
|
||||
* @return string JSON
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*@author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.6]
|
||||
*/
|
||||
public function store(UploadFileRequest $request, User $user)
|
||||
{
|
||||
$this->authorize('update', $user);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
if (! Storage::exists('private_uploads/users')) {
|
||||
Storage::makeDirectory('private_uploads/users', 775);
|
||||
}
|
||||
|
||||
foreach ($request->file('file') as $file) {
|
||||
$file_name = $request->handleFile('private_uploads/users/','user-'.$user->id, $file);
|
||||
$user->logUpload($file_name, $request->get('notes'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/users/message.upload.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->with('error', trans('admin/users/message.upload.nofiles'));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete file
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.6]
|
||||
* @param int $userId
|
||||
* @param int $fileId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function destroy($userId = null, $fileId = null)
|
||||
{
|
||||
if ($user = User::find($userId)) {
|
||||
|
||||
$this->authorize('delete', $user);
|
||||
$rel_path = 'private_uploads/users';
|
||||
|
||||
|
||||
if ($log = Actionlog::find($fileId)) {
|
||||
$filename = $log->filename;
|
||||
$log->delete();
|
||||
|
||||
if (Storage::exists($rel_path.'/'.$filename)) {
|
||||
Storage::delete($rel_path.'/'.$filename);
|
||||
return redirect()->back()->withFragment('files')->with('success', trans('admin/users/message.deletefile.success'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// The log record doesn't exist somehow
|
||||
return redirect()->back()->with('success', trans('admin/users/message.deletefile.success'));
|
||||
}
|
||||
|
||||
return redirect()->route('users.index')->with('error', trans('admin/users/message.user_not_found', ['id' => $userId]));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display/download the uploaded file
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.6]
|
||||
* @param int $userId
|
||||
* @param int $fileId
|
||||
* @return mixed
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||
*/
|
||||
public function show(User $user, $fileId = null)
|
||||
{
|
||||
|
||||
|
||||
if (empty($fileId)) {
|
||||
return redirect()->route('users.show')->with('error', 'Invalid file request');
|
||||
}
|
||||
|
||||
$this->authorize('view', $user);
|
||||
|
||||
if ($log = Actionlog::whereNotNull('filename')->where('item_id', $user->id)->find($fileId)) {
|
||||
$file = 'private_uploads/users/'.$log->filename;
|
||||
|
||||
try {
|
||||
return StorageHelper::showOrDownloadFile($file, $log->filename);
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->route('users.show', ['user' => $user])->with('error', trans('general.file_not_found'));
|
||||
}
|
||||
}
|
||||
|
||||
// The log record doesn't exist somehow
|
||||
return redirect()->route('users.show', ['user' => $user])->with('error', trans('general.log_record_not_found'));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -98,7 +98,6 @@ class UsersController extends Controller
|
||||
$user->activated = $request->input('activated', 0);
|
||||
$user->jobtitle = $request->input('jobtitle');
|
||||
$user->phone = $request->input('phone');
|
||||
$user->mobile = $request->input('mobile');
|
||||
$user->location_id = $request->input('location_id', null);
|
||||
$user->department_id = $request->input('department_id', null);
|
||||
$user->company_id = Company::getIdForUser($request->input('company_id', null));
|
||||
@@ -127,12 +126,7 @@ class UsersController extends Controller
|
||||
// we have to invoke the form request here to handle image uploads
|
||||
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
}
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
|
||||
if ($user->save()) {
|
||||
if ($request->filled('groups')) {
|
||||
@@ -245,7 +239,6 @@ class UsersController extends Controller
|
||||
$user->employee_num = $request->input('employee_num');
|
||||
$user->jobtitle = $request->input('jobtitle', null);
|
||||
$user->phone = $request->input('phone');
|
||||
$user->mobile = $request->input('mobile');
|
||||
$user->location_id = $request->input('location_id', null);
|
||||
$user->company_id = Company::getIdForUser($request->input('company_id', null));
|
||||
$user->manager_id = $request->input('manager_id', null);
|
||||
|
||||
@@ -26,6 +26,7 @@ class SecurityHeaders
|
||||
$response = $next($request);
|
||||
|
||||
$response->headers->set('X-Content-Type-Options', 'nosniff');
|
||||
$response->headers->set('X-XSS-Protection', '1; mode=block');
|
||||
|
||||
// Ugh. Feature-Policy is dumb and clumsy and mostly irrelevant for Snipe-IT,
|
||||
// since we don't provide any way to IFRAME anything in in the first place.
|
||||
|
||||
@@ -11,7 +11,6 @@ use Illuminate\Support\Facades\Storage;
|
||||
use Intervention\Image\Exception\NotReadableException;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ImageUploadRequest extends Request
|
||||
{
|
||||
@@ -71,25 +70,19 @@ class ImageUploadRequest extends Request
|
||||
public function handleImages($item, $w = 600, $form_fieldname = 'image', $path = null, $db_fieldname = 'image')
|
||||
{
|
||||
|
||||
$type = class_basename(get_class($item));
|
||||
$type = strtolower(class_basename(get_class($item)));
|
||||
|
||||
if (is_null($path)) {
|
||||
|
||||
$path = strtolower(str_plural($type));
|
||||
$path = str_plural($type);
|
||||
|
||||
if ($type == 'AssetModel') {
|
||||
if ($type == 'assetmodel') {
|
||||
$path = 'models';
|
||||
}
|
||||
|
||||
if ($type == 'user') {
|
||||
$path = 'avatars';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!Storage::disk('public')->exists($path)) {
|
||||
Storage::disk('public')->makeDirectory($path);
|
||||
}
|
||||
|
||||
if ($this->offsetGet($form_fieldname) instanceof UploadedFile) {
|
||||
@@ -100,9 +93,10 @@ class ImageUploadRequest extends Request
|
||||
|
||||
if (isset($image)) {
|
||||
|
||||
if (!config('app.lock_passwords')) {
|
||||
|
||||
$ext = $image->guessExtension();
|
||||
$file_name = $type.'-'.$form_fieldname.($item->id ?? '-'.$item->id).'-'.str_random(10).'.'.$ext;
|
||||
$file_name = $type.'-'.$form_fieldname.'-'.$item->id.'-'.str_random(10).'.'.$ext;
|
||||
|
||||
if (($image->getMimeType() == 'image/vnd.microsoft.icon') || ($image->getMimeType() == 'image/x-icon') || ($image->getMimeType() == 'image/avif') || ($image->getMimeType() == 'image/webp')) {
|
||||
// If the file is an icon, webp or avif, we need to just move it since gd doesn't support resizing
|
||||
@@ -144,7 +138,7 @@ class ImageUploadRequest extends Request
|
||||
// Remove Current image if exists
|
||||
$item = $this->deleteExistingImage($item, $path, $db_fieldname);
|
||||
$item->{$db_fieldname} = $file_name;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// If the user isn't uploading anything new but wants to delete their old image, do so
|
||||
|
||||
@@ -4,24 +4,23 @@ namespace App\Http\Transformers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Maintenance;
|
||||
use App\Models\AssetMaintenance;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class MaintenancesTransformer
|
||||
class AssetMaintenancesTransformer
|
||||
{
|
||||
public function transformMaintenances(Collection $maintenances, $total)
|
||||
public function transformAssetMaintenances(Collection $assetmaintenances, $total)
|
||||
{
|
||||
$array = [];
|
||||
foreach ($maintenances as $assetmaintenance) {
|
||||
$array[] = self::transformMaintenance($assetmaintenance);
|
||||
foreach ($assetmaintenances as $assetmaintenance) {
|
||||
$array[] = self::transformAssetMaintenance($assetmaintenance);
|
||||
}
|
||||
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformMaintenance(Maintenance $assetmaintenance)
|
||||
public function transformAssetMaintenance(AssetMaintenance $assetmaintenance)
|
||||
{
|
||||
$array = [
|
||||
'id' => (int) $assetmaintenance->id,
|
||||
@@ -34,7 +33,6 @@ class MaintenancesTransformer
|
||||
'created_at' => Helper::getFormattedDateObject($assetmaintenance->asset->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($assetmaintenance->asset->updated_at, 'datetime'),
|
||||
] : null,
|
||||
'image' => ($assetmaintenance->image != '') ? Storage::disk('public')->url('maintenances/'.e($assetmaintenance->image)) : null,
|
||||
'model' => (($assetmaintenance->asset) && ($assetmaintenance->asset->model)) ? [
|
||||
'id' => (int) $assetmaintenance->asset->model->id,
|
||||
'name'=> ($assetmaintenance->asset->model->name) ? e($assetmaintenance->asset->model->name).' '.e($assetmaintenance->asset->model->model_number) : null,
|
||||
@@ -50,8 +48,7 @@ class MaintenancesTransformer
|
||||
'name'=> ($assetmaintenance->asset->company->name) ? e($assetmaintenance->asset->company->name) : null,
|
||||
|
||||
] : null,
|
||||
'name' => ($assetmaintenance->name) ? e($assetmaintenance->name) : null,
|
||||
'title' => ($assetmaintenance->name) ? e($assetmaintenance->name) : null, // legacy to not change the shape of the API
|
||||
'title' => ($assetmaintenance->title) ? e($assetmaintenance->title) : null,
|
||||
'location' => (($assetmaintenance->asset) && ($assetmaintenance->asset->location)) ? [
|
||||
'id' => (int) $assetmaintenance->asset->location->id,
|
||||
'name'=> e($assetmaintenance->asset->location->name),
|
||||
@@ -58,13 +58,6 @@ class AssetsTransformer
|
||||
'id' => (int) $asset->model->manufacturer->id,
|
||||
'name'=> e($asset->model->manufacturer->name),
|
||||
] : null,
|
||||
'depreciation' => (($asset->model) && ($asset->model->depreciation)) ? [
|
||||
'id' => (int) $asset->model->depreciation->id,
|
||||
'name'=> e($asset->model->depreciation->name),
|
||||
'months'=> (int) $asset->model->depreciation->months,
|
||||
'type'=> e($asset->model->depreciation->depreciation_type),
|
||||
'minimum'=> ($asset->model->depreciation->depreciation_min) ? (int) $asset->model->depreciation->depreciation_min : null,
|
||||
] : null,
|
||||
'supplier' => ($asset->supplier) ? [
|
||||
'id' => (int) $asset->supplier->id,
|
||||
'name'=> e($asset->supplier->name),
|
||||
|
||||
@@ -25,7 +25,7 @@ class ConsumablesTransformer
|
||||
$array = [
|
||||
'id' => (int) $consumable->id,
|
||||
'name' => e($consumable->name),
|
||||
'image' => ($consumable->getImageUrl()) ? ($consumable->getImageUrl()) : null,
|
||||
'image' => ($consumable->image) ? Storage::disk('public')->url('consumables/'.e($consumable->image)) : null,
|
||||
'category' => ($consumable->category) ? ['id' => $consumable->category->id, 'name' => e($consumable->category->name)] : null,
|
||||
'company' => ($consumable->company) ? ['id' => (int) $consumable->company->id, 'name' => e($consumable->company->name)] : null,
|
||||
'item_no' => e($consumable->item_no),
|
||||
|
||||
@@ -45,7 +45,7 @@ class UploadedFilesTransformer
|
||||
] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($file->created_at, 'datetime'),
|
||||
'deleted_at' => Helper::getFormattedDateObject($file->deleted_at, 'datetime'),
|
||||
'inlineable' => StorageHelper::allowSafeInline($file->uploads_file_path()) ?? false,
|
||||
'inlineable' => StorageHelper::allowSafeInline($file->uploads_file_path()),
|
||||
'exists_on_disk' => (Storage::exists($file->uploads_file_path()) ? true : false),
|
||||
];
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@ class UsersTransformer
|
||||
'jobtitle' => ($user->jobtitle) ? e($user->jobtitle) : null,
|
||||
'vip' => ($user->vip == '1') ? true : false,
|
||||
'phone' => ($user->phone) ? e($user->phone) : null,
|
||||
'mobile' => ($user->mobile) ? e($user->mobile) : null,
|
||||
'website' => ($user->website) ? e($user->website) : null,
|
||||
'address' => ($user->address) ? e($user->address) : null,
|
||||
'city' => ($user->city) ? e($user->city) : null,
|
||||
|
||||
@@ -52,7 +52,6 @@ class UserImporter extends ItemImporter
|
||||
$this->item['email'] = trim($this->findCsvMatch($row, 'email'));
|
||||
$this->item['gravatar'] = trim($this->findCsvMatch($row, 'gravatar'));
|
||||
$this->item['phone'] = trim($this->findCsvMatch($row, 'phone_number'));
|
||||
$this->item['mobile'] = trim($this->findCsvMatch($row, 'mobile_number'));
|
||||
$this->item['website'] = trim($this->findCsvMatch($row, 'website'));
|
||||
$this->item['jobtitle'] = trim($this->findCsvMatch($row, 'jobtitle'));
|
||||
$this->item['address'] = trim($this->findCsvMatch($row, 'address'));
|
||||
|
||||
@@ -334,7 +334,6 @@ class Importer extends Component
|
||||
'manager_username' => trans('general.importer.manager_username'),
|
||||
'notes' => trans('general.notes'),
|
||||
'phone_number' => trans('admin/users/table.phone'),
|
||||
'mobile_number' => trans('admin/users/table.mobile'),
|
||||
'remote' => trans('admin/users/general.remote'),
|
||||
'start_date' => trans('general.start_date'),
|
||||
'state' => trans('general.state'),
|
||||
@@ -511,13 +510,6 @@ class Importer extends Component
|
||||
'telephone',
|
||||
'tel.',
|
||||
],
|
||||
'mobile_number' =>
|
||||
[
|
||||
'mobile',
|
||||
'mobile number',
|
||||
'cell',
|
||||
'cellphone',
|
||||
],
|
||||
|
||||
'serial' =>
|
||||
[
|
||||
|
||||
@@ -47,7 +47,7 @@ class CheckinAssetMail extends Mailable
|
||||
|
||||
return new Envelope(
|
||||
from: $from,
|
||||
subject: trans('mail.Asset_Checkin_Notification', ['tag' => $this->item->asset_tag]),
|
||||
subject: trans('mail.Asset_Checkin_Notification'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,25 +24,16 @@ class CheckoutAssetMail extends Mailable
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct(Asset $asset, $checkedOutTo, User $checkedOutBy, $acceptance, $note, bool $firstTimeSending = true)
|
||||
{
|
||||
$this->item = $asset;
|
||||
$this->admin = $checkedOutBy;
|
||||
$this->note = $note;
|
||||
$this->target = $checkedOutTo;
|
||||
$this->acceptance = $acceptance;
|
||||
|
||||
$this->settings = Setting::getSettings();
|
||||
$this->target = $checkedOutTo;
|
||||
|
||||
// Location is a target option, but there are no emails currently associated with locations.
|
||||
if($this->target instanceof User){
|
||||
$this->target = $this->target->present()?->fullName();
|
||||
}
|
||||
else if($this->target instanceof Asset){
|
||||
$this->target = $this->target->assignedto?->present()?->fullName();
|
||||
}
|
||||
|
||||
$this->last_checkout = '';
|
||||
$this->expected_checkin = '';
|
||||
@@ -125,7 +116,7 @@ class CheckoutAssetMail extends Mailable
|
||||
private function getSubject(): string
|
||||
{
|
||||
if ($this->firstTimeSending) {
|
||||
return trans('mail.Asset_Checkout_Notification', ['tag' => $this->item->asset_tag]);
|
||||
return trans('mail.Asset_Checkout_Notification');
|
||||
}
|
||||
|
||||
return trans('mail.unaccepted_asset_reminder');
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\LicenseSeat;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
@@ -26,16 +25,9 @@ class CheckoutLicenseMail extends Mailable
|
||||
$this->item = $licenseSeat;
|
||||
$this->admin = $checkedOutBy;
|
||||
$this->note = $note;
|
||||
$this->target = $checkedOutTo;
|
||||
$this->acceptance = $acceptance;
|
||||
$this->settings = Setting::getSettings();
|
||||
$this->target = $checkedOutTo;
|
||||
|
||||
if($this->target instanceof User){
|
||||
$this->target = $this->target->present()?->fullName();
|
||||
}
|
||||
elseif($this->target instanceof Asset){
|
||||
$this->target = $this->target->assignedto?->present()?->fullName();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,6 @@ use App\Presenters\Presentable;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Model for the Actionlog (the table that keeps a historical log of
|
||||
@@ -459,23 +458,30 @@ class Actionlog extends SnipeModel
|
||||
{
|
||||
|
||||
|
||||
|
||||
if (($this->action_type == 'accepted') || ($this->action_type == 'declined')) {
|
||||
return route('log.storedeula.download', ['filename' => $this->filename]);
|
||||
}
|
||||
|
||||
$object = Str::snake(str_plural(str_replace("App\Models\\", '', $this->item_type)));
|
||||
|
||||
if ($object == 'asset_models') {
|
||||
$object = 'models';
|
||||
switch ($this->item_type) {
|
||||
case Accessory::class:
|
||||
return route('show.accessoryfile', [$this->item_id, $this->id]);
|
||||
case Asset::class:
|
||||
return route('show/assetfile', [$this->item_id, $this->id]);
|
||||
case AssetModel::class:
|
||||
return route('show/modelfile', [$this->item_id, $this->id]);
|
||||
case Consumable::class:
|
||||
return route('show.consumablefile', [$this->item_id, $this->id]);
|
||||
case Component::class:
|
||||
return route('show.componentfile', [$this->item_id, $this->id]);
|
||||
case License::class:
|
||||
return route('show.licensefile', [$this->item_id, $this->id]);
|
||||
case Location::class:
|
||||
return route('show/locationsfile', [$this->item_id, $this->id]);
|
||||
case User::class:
|
||||
return route('show/userfile', [$this->item_id, $this->id]);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
return route('ui.files.show', [
|
||||
'object_type' => $object,
|
||||
'id' => $this->item_id,
|
||||
'file_id' => $this->id,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function uploads_file_path()
|
||||
@@ -491,7 +497,7 @@ class Actionlog extends SnipeModel
|
||||
case Asset::class:
|
||||
return 'private_uploads/assets/'.$this->filename;
|
||||
case AssetModel::class:
|
||||
return 'private_uploads/models/'.$this->filename;
|
||||
return 'private_uploads/assetmodels/'.$this->filename;
|
||||
case Consumable::class:
|
||||
return 'private_uploads/consumables/'.$this->filename;
|
||||
case Component::class:
|
||||
@@ -500,8 +506,6 @@ class Actionlog extends SnipeModel
|
||||
return 'private_uploads/licenses/'.$this->filename;
|
||||
case Location::class:
|
||||
return 'private_uploads/locations/'.$this->filename;
|
||||
case Maintenance::class:
|
||||
return 'private_uploads/maintenances/'.$this->filename;
|
||||
case User::class:
|
||||
return 'private_uploads/users/'.$this->filename;
|
||||
default:
|
||||
@@ -510,6 +514,11 @@ class Actionlog extends SnipeModel
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Manually sets $this->source for determineActionSource()
|
||||
public function setActionSource($source = null): void
|
||||
{
|
||||
|
||||
@@ -112,7 +112,7 @@ class Asset extends Depreciable
|
||||
'location_id' => ['nullable', 'exists:locations,id', 'fmcs_location'],
|
||||
'rtd_location_id' => ['nullable', 'exists:locations,id', 'fmcs_location'],
|
||||
'purchase_date' => ['nullable', 'date', 'date_format:Y-m-d'],
|
||||
'serial' => ['nullable', 'string', 'unique_undeleted:assets,serial'],
|
||||
'serial' => ['nullable', 'unique_undeleted:assets,serial'],
|
||||
'purchase_cost' => ['nullable', 'numeric', 'gte:0', 'max:9999999999999'],
|
||||
'supplier_id' => ['nullable', 'exists:suppliers,id'],
|
||||
'asset_eol_date' => ['nullable', 'date'],
|
||||
@@ -206,17 +206,6 @@ class Asset extends Depreciable
|
||||
'model.manufacturer' => ['name'],
|
||||
];
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::forceDeleted(function (Asset $asset) {
|
||||
$asset->requests()->forceDelete();
|
||||
});
|
||||
|
||||
static::softDeleted(function (Asset $asset) {
|
||||
$asset->requests()->delete();
|
||||
});
|
||||
}
|
||||
|
||||
// To properly set the expected checkin as Y-m-d
|
||||
public function setExpectedCheckinAttribute($value)
|
||||
{
|
||||
@@ -771,9 +760,9 @@ class Asset extends Depreciable
|
||||
* @since 1.0
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||
*/
|
||||
public function maintenances()
|
||||
public function assetmaintenances()
|
||||
{
|
||||
return $this->hasMany(\App\Models\Maintenance::class, 'asset_id')
|
||||
return $this->hasMany(\App\Models\AssetMaintenance::class, 'asset_id')
|
||||
->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
|
||||
@@ -4,34 +4,31 @@ namespace App\Models;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Traits\Searchable;
|
||||
use App\Presenters\Presentable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
use App\Models\Traits\HasUploads;
|
||||
|
||||
/**
|
||||
* Model for Asset Maintenances.
|
||||
*
|
||||
* @version v1.0
|
||||
*/
|
||||
class Maintenance extends SnipeModel implements ICompanyableChild
|
||||
class AssetMaintenance extends Model implements ICompanyableChild
|
||||
{
|
||||
use HasFactory;
|
||||
use HasUploads;
|
||||
use SoftDeletes;
|
||||
use CompanyableChildTrait;
|
||||
use ValidatingTrait;
|
||||
use Loggable, Presentable;
|
||||
|
||||
|
||||
|
||||
protected $table = 'maintenances';
|
||||
protected $table = 'asset_maintenances';
|
||||
protected $rules = [
|
||||
'asset_id' => 'required|integer',
|
||||
'supplier_id' => 'nullable|integer',
|
||||
'asset_maintenance_type' => 'required',
|
||||
'name' => 'required|max:100',
|
||||
'title' => 'required|max:100',
|
||||
'is_warranty' => 'boolean',
|
||||
'start_date' => 'required|date_format:Y-m-d',
|
||||
'completion_date' => 'date_format:Y-m-d|nullable|after_or_equal:start_date',
|
||||
@@ -46,7 +43,7 @@ class Maintenance extends SnipeModel implements ICompanyableChild
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'title',
|
||||
'asset_id',
|
||||
'supplier_id',
|
||||
'asset_maintenance_type',
|
||||
@@ -67,7 +64,7 @@ class Maintenance extends SnipeModel implements ICompanyableChild
|
||||
*/
|
||||
protected $searchableAttributes =
|
||||
[
|
||||
'name',
|
||||
'title',
|
||||
'notes',
|
||||
'asset_maintenance_type',
|
||||
'cost',
|
||||
@@ -103,14 +100,14 @@ class Maintenance extends SnipeModel implements ICompanyableChild
|
||||
public static function getImprovementOptions()
|
||||
{
|
||||
return [
|
||||
trans('admin/maintenances/general.maintenance') => trans('admin/maintenances/general.maintenance'),
|
||||
trans('admin/maintenances/general.repair') => trans('admin/maintenances/general.repair'),
|
||||
trans('admin/maintenances/general.upgrade') => trans('admin/maintenances/general.upgrade'),
|
||||
trans('admin/maintenances/general.pat_test') => trans('admin/maintenances/general.pat_test'),
|
||||
trans('admin/maintenances/general.calibration') => trans('admin/maintenances/general.calibration'),
|
||||
trans('admin/maintenances/general.software_support') => trans('admin/maintenances/general.software_support'),
|
||||
trans('admin/maintenances/general.hardware_support') => trans('admin/maintenances/general.hardware_support'),
|
||||
trans('admin/maintenances/general.configuration_change') => trans('admin/maintenances/general.configuration_change'),
|
||||
trans('admin/asset_maintenances/general.maintenance') => trans('admin/asset_maintenances/general.maintenance'),
|
||||
trans('admin/asset_maintenances/general.repair') => trans('admin/asset_maintenances/general.repair'),
|
||||
trans('admin/asset_maintenances/general.upgrade') => trans('admin/asset_maintenances/general.upgrade'),
|
||||
trans('admin/asset_maintenances/general.pat_test') => trans('admin/asset_maintenances/general.pat_test'),
|
||||
trans('admin/asset_maintenances/general.calibration') => trans('admin/asset_maintenances/general.calibration'),
|
||||
trans('admin/asset_maintenances/general.software_support') => trans('admin/asset_maintenances/general.software_support'),
|
||||
trans('admin/asset_maintenances/general.hardware_support') => trans('admin/asset_maintenances/general.hardware_support'),
|
||||
trans('admin/asset_maintenances/general.configuration_change') => trans('admin/asset_maintenances/general.configuration_change'),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -169,21 +166,6 @@ class Maintenance extends SnipeModel implements ICompanyableChild
|
||||
return $this->belongsTo(\App\Models\Asset::class, 'asset_id')
|
||||
->withTrashed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maintenance logs
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v8.2.2]
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||
*/
|
||||
public function assetlog()
|
||||
{
|
||||
return $this->hasMany(\App\Models\Actionlog::class, 'item_id')
|
||||
->where('item_type', '=', self::class)
|
||||
->orderBy('created_at', 'desc')
|
||||
->withTrashed();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -205,11 +187,6 @@ class Maintenance extends SnipeModel implements ICompanyableChild
|
||||
->withTrashed();
|
||||
}
|
||||
|
||||
public function getDisplayNameAttribute()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* -----------------------------------------------
|
||||
* BEGIN QUERY SCOPES
|
||||
@@ -226,7 +203,7 @@ class Maintenance extends SnipeModel implements ICompanyableChild
|
||||
*/
|
||||
public function scopeOrderBySupplier($query, $order)
|
||||
{
|
||||
return $query->leftJoin('suppliers as suppliers_maintenances', 'maintenances.supplier_id', '=', 'suppliers_maintenances.id')
|
||||
return $query->leftJoin('suppliers as suppliers_maintenances', 'asset_maintenances.supplier_id', '=', 'suppliers_maintenances.id')
|
||||
->orderBy('suppliers_maintenances.name', $order);
|
||||
}
|
||||
|
||||
@@ -242,7 +219,7 @@ class Maintenance extends SnipeModel implements ICompanyableChild
|
||||
*/
|
||||
public function scopeOrderByTag($query, $order)
|
||||
{
|
||||
return $query->leftJoin('assets', 'maintenances.asset_id', '=', 'assets.id')
|
||||
return $query->leftJoin('assets', 'asset_maintenances.asset_id', '=', 'assets.id')
|
||||
->orderBy('assets.asset_tag', $order);
|
||||
}
|
||||
|
||||
@@ -256,7 +233,7 @@ class Maintenance extends SnipeModel implements ICompanyableChild
|
||||
*/
|
||||
public function scopeOrderByAssetName($query, $order)
|
||||
{
|
||||
return $query->leftJoin('assets', 'maintenances.asset_id', '=', 'assets.id')
|
||||
return $query->leftJoin('assets', 'asset_maintenances.asset_id', '=', 'assets.id')
|
||||
->orderBy('assets.name', $order);
|
||||
}
|
||||
|
||||
@@ -270,7 +247,7 @@ class Maintenance extends SnipeModel implements ICompanyableChild
|
||||
*/
|
||||
public function scopeOrderByAssetSerial($query, $order)
|
||||
{
|
||||
return $query->leftJoin('assets', 'maintenances.asset_id', '=', 'assets.id')
|
||||
return $query->leftJoin('assets', 'asset_maintenances.asset_id', '=', 'assets.id')
|
||||
->orderBy('assets.serial', $order);
|
||||
}
|
||||
|
||||
@@ -284,7 +261,7 @@ class Maintenance extends SnipeModel implements ICompanyableChild
|
||||
*/
|
||||
public function scopeOrderStatusName($query, $order)
|
||||
{
|
||||
return $query->join('assets as maintained_asset', 'maintenances.asset_id', '=', 'maintained_asset.id')
|
||||
return $query->join('assets as maintained_asset', 'asset_maintenances.asset_id', '=', 'maintained_asset.id')
|
||||
->leftjoin('status_labels as maintained_asset_status', 'maintained_asset_status.id', '=', 'maintained_asset.status_id')
|
||||
->orderBy('maintained_asset_status.name', $order);
|
||||
}
|
||||
@@ -299,7 +276,7 @@ class Maintenance extends SnipeModel implements ICompanyableChild
|
||||
*/
|
||||
public function scopeOrderLocationName($query, $order)
|
||||
{
|
||||
return $query->join('assets as maintained_asset', 'maintenances.asset_id', '=', 'maintained_asset.id')
|
||||
return $query->join('assets as maintained_asset', 'asset_maintenances.asset_id', '=', 'maintained_asset.id')
|
||||
->leftjoin('locations as maintained_asset_location', 'maintained_asset_location.id', '=', 'maintained_asset.location_id')
|
||||
->orderBy('maintained_asset_location.name', $order);
|
||||
}
|
||||
@@ -309,6 +286,6 @@ class Maintenance extends SnipeModel implements ICompanyableChild
|
||||
*/
|
||||
public function scopeOrderByCreatedBy($query, $order)
|
||||
{
|
||||
return $query->leftJoin('users as admin_sort', 'maintenances.created_by', '=', 'admin_sort.id')->select('maintenances.*')->orderBy('admin_sort.first_name', $order)->orderBy('admin_sort.last_name', $order);
|
||||
return $query->leftJoin('users as admin_sort', 'asset_maintenances.created_by', '=', 'admin_sort.id')->select('asset_maintenances.*')->orderBy('admin_sort.first_name', $order)->orderBy('admin_sort.last_name', $order);
|
||||
}
|
||||
}
|
||||
@@ -98,16 +98,8 @@ class AssetModel extends SnipeModel
|
||||
'manufacturer' => ['name'],
|
||||
];
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::forceDeleted(function (AssetModel $assetModel) {
|
||||
$assetModel->requests()->forceDelete();
|
||||
});
|
||||
|
||||
static::softDeleted(function (AssetModel $assetModel) {
|
||||
$assetModel->requests()->delete();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Establishes the model -> assets relationship
|
||||
|
||||
@@ -2,13 +2,11 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class CheckoutRequest extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use SoftDeletes;
|
||||
protected $fillable = ['user_id'];
|
||||
protected $table = 'checkout_requests';
|
||||
|
||||
@@ -230,16 +230,11 @@ class Consumable extends SnipeModel
|
||||
*/
|
||||
public function getImageUrl()
|
||||
{
|
||||
// If there is a consumable image, use that
|
||||
if ($this->image) {
|
||||
return Storage::disk('public')->url(app('consumables_upload_path').$this->image);
|
||||
|
||||
// Otherwise check for a category image
|
||||
} elseif (($this->category) && ($this->category->image)) {
|
||||
return Storage::disk('public')->url(app('categories_upload_path').e($this->category->image));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Labels\Tapes\Dymo;
|
||||
|
||||
|
||||
class LabelWriter_11354 extends LabelWriter
|
||||
{
|
||||
private const BARCODE1D_HEIGHT = 3.00;
|
||||
private const BARCODE_MARGIN = 1.80;
|
||||
private const TAG_SIZE = 2.80;
|
||||
private const TITLE_SIZE = 2.80;
|
||||
private const TITLE_MARGIN = 0.50;
|
||||
private const FIELD_SIZE = 2.80;
|
||||
private const FIELD_MARGIN = 0.15;
|
||||
|
||||
public function getUnit()
|
||||
{
|
||||
return 'mm';
|
||||
}
|
||||
public function getWidth()
|
||||
{
|
||||
return 57;
|
||||
}
|
||||
public function getHeight()
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
public function getSupportAssetTag()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public function getSupport1DBarcode()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public function getSupport2DBarcode()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public function getSupportFields()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
public function getSupportLogo()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public function getSupportTitle()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public function preparePDF($pdf)
|
||||
{
|
||||
}
|
||||
|
||||
public function write($pdf, $record)
|
||||
{
|
||||
$pa = $this->getPrintableArea();
|
||||
|
||||
$currentX = $pa->x1;
|
||||
$currentY = $pa->y1;
|
||||
$usableWidth = $pa->w;
|
||||
$usableHeight = $pa->h;
|
||||
|
||||
// Wide 1D barcode on top
|
||||
if ($record->has('barcode1d')) {
|
||||
static::write1DBarcode(
|
||||
$pdf, $record->get('barcode1d')->content, $record->get('barcode1d')->type,
|
||||
$currentX, $currentY, $usableWidth, self::BARCODE1D_HEIGHT
|
||||
);
|
||||
$currentY += self::BARCODE1D_HEIGHT + self::BARCODE_MARGIN;
|
||||
$usableHeight -= self::BARCODE1D_HEIGHT + self::BARCODE_MARGIN;
|
||||
}
|
||||
|
||||
// 2D Barcode in left column
|
||||
if ($record->has('barcode2d')) {
|
||||
$barcodeSize = $usableHeight - self::TAG_SIZE;
|
||||
|
||||
static::writeText(
|
||||
$pdf, $record->get('tag'),
|
||||
$currentX, $pa->y2 - self::TAG_SIZE,
|
||||
'freesans', 'b', self::TAG_SIZE, 'C',
|
||||
$barcodeSize, self::TAG_SIZE, true, 0
|
||||
);
|
||||
static::write2DBarcode(
|
||||
$pdf, $record->get('barcode2d')->content, $record->get('barcode2d')->type,
|
||||
$currentX, $currentY,
|
||||
$barcodeSize, $barcodeSize
|
||||
);
|
||||
$currentX += $barcodeSize + self::BARCODE_MARGIN;
|
||||
$usableWidth -= $barcodeSize + self::BARCODE_MARGIN;
|
||||
}
|
||||
|
||||
// Right column
|
||||
if ($record->has('title')) {
|
||||
static::writeText(
|
||||
$pdf, $record->get('title'),
|
||||
$currentX, $currentY,
|
||||
'freesans', 'b', self::TITLE_SIZE, 'L',
|
||||
$usableWidth, self::TITLE_SIZE, true, 0
|
||||
);
|
||||
$currentY += self::TITLE_SIZE + self::TITLE_MARGIN;
|
||||
}
|
||||
|
||||
foreach ($record->get('fields') as $field) {
|
||||
static::writeText(
|
||||
$pdf, (($field['label']) ? $field['label'].' ' : '') . $field['value'],
|
||||
$currentX, $currentY,
|
||||
'freesans', '', self::FIELD_SIZE, 'L',
|
||||
$usableWidth, self::FIELD_SIZE, true, 0, 0.3
|
||||
);
|
||||
$currentY += self::FIELD_SIZE + self::FIELD_MARGIN;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,7 +21,7 @@ class SnipeModel extends Model
|
||||
*/
|
||||
public function setPurchaseCostAttribute($value)
|
||||
{
|
||||
if (is_numeric($value)) {
|
||||
if (is_float($value)) {
|
||||
//value is *already* a floating-point number. Just assign it directly
|
||||
$this->attributes['purchase_cost'] = $value;
|
||||
return;
|
||||
|
||||
@@ -153,21 +153,12 @@ class SnipeSCIMConfig extends \ArieTimmerman\Laravel\SCIMServer\SCIMConfig
|
||||
"primary" => AttributeMapping::constant(true)->ignoreWrite()
|
||||
]],
|
||||
|
||||
// Mobile and work phone numbers
|
||||
'phoneNumbers' => [
|
||||
[
|
||||
"value" => AttributeMapping::eloquent("phone"),
|
||||
"display" => null,
|
||||
"type" => AttributeMapping::constant("work")->ignoreWrite(),
|
||||
"primary" => AttributeMapping::constant(true)->ignoreWrite(),
|
||||
],
|
||||
[
|
||||
"value" => AttributeMapping::eloquent("mobile"),
|
||||
"display" => null,
|
||||
"type" => AttributeMapping::constant("mobile")->ignoreWrite(),
|
||||
"primary" => AttributeMapping::constant(false)->ignoreWrite()
|
||||
]
|
||||
],
|
||||
'phoneNumbers' => [[
|
||||
"value" => AttributeMapping::eloquent("phone"),
|
||||
"display" => null,
|
||||
"type" => AttributeMapping::constant("work")->ignoreWrite(),
|
||||
"primary" => AttributeMapping::constant(true)->ignoreWrite()
|
||||
]],
|
||||
|
||||
'ims' => [[
|
||||
"value" => null,
|
||||
|
||||
@@ -7,7 +7,7 @@ use App\Models\Traits\Searchable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
use \Illuminate\Database\Eloquent\Relations\Relation;
|
||||
|
||||
class Supplier extends SnipeModel
|
||||
{
|
||||
use HasFactory;
|
||||
@@ -133,7 +133,7 @@ class Supplier extends SnipeModel
|
||||
* Establishes the supplier -> admin user relationship
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @return Relation
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||
*/
|
||||
public function adminuser()
|
||||
{
|
||||
@@ -147,9 +147,9 @@ class Supplier extends SnipeModel
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||
*/
|
||||
public function maintenances(): Relation
|
||||
public function asset_maintenances()
|
||||
{
|
||||
return $this->hasMany(\App\Models\Maintenance::class, 'supplier_id');
|
||||
return $this->hasMany(\App\Models\AssetMaintenance::class, 'supplier_id');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -70,7 +70,6 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
'manager_id',
|
||||
'password',
|
||||
'phone',
|
||||
'mobile',
|
||||
'notes',
|
||||
'state',
|
||||
'username',
|
||||
@@ -140,7 +139,6 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
'locale',
|
||||
'notes',
|
||||
'phone',
|
||||
'mobile',
|
||||
'state',
|
||||
'username',
|
||||
'website',
|
||||
@@ -185,17 +183,6 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
);
|
||||
}
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::forceDeleted(function (User $user) {
|
||||
CheckoutRequest::where(['user_id' => $user->id])->forceDelete();
|
||||
});
|
||||
|
||||
static::softDeleted(function (User $user) {
|
||||
CheckoutRequest::where(['user_id' => $user->id])->delete();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public function isAvatarExternal()
|
||||
{
|
||||
@@ -411,9 +398,9 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Database\Eloquent\Relations\Relation
|
||||
*/
|
||||
public function maintenances()
|
||||
public function assetmaintenances()
|
||||
{
|
||||
return $this->hasMany(\App\Models\Maintenance::class, 'user_id')->withTrashed();
|
||||
return $this->hasMany(\App\Models\AssetMaintenance::class, 'user_id')->withTrashed();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,7 +29,6 @@ class AcceptanceAssetAcceptedNotification extends Notification
|
||||
$this->assigned_to = $params['assigned_to'];
|
||||
$this->note = $params['note'];
|
||||
$this->company_name = $params['company_name'];
|
||||
$this->admin = $params['admin'] ?? null;
|
||||
$this->settings = Setting::getSettings();
|
||||
|
||||
}
|
||||
@@ -73,7 +72,6 @@ class AcceptanceAssetAcceptedNotification extends Notification
|
||||
'assigned_to' => $this->assigned_to,
|
||||
'company_name' => $this->company_name,
|
||||
'intro_text' => trans('mail.acceptance_asset_accepted'),
|
||||
'admin' => $this->admin,
|
||||
])
|
||||
->subject(trans('mail.acceptance_asset_accepted'));
|
||||
|
||||
|
||||
@@ -20,11 +20,7 @@ class ComponentObserver
|
||||
$logAction->item_type = Component::class;
|
||||
$logAction->item_id = $component->id;
|
||||
$logAction->created_at = date('Y-m-d H:i:s');
|
||||
$logAction->action_date = date('Y-m-d H:i:s');
|
||||
$logAction->created_by = auth()->id();
|
||||
if($component->imported) {
|
||||
$logAction->setActionSource('importer');
|
||||
}
|
||||
$logAction->logaction('update');
|
||||
}
|
||||
|
||||
@@ -41,7 +37,6 @@ class ComponentObserver
|
||||
$logAction->item_type = Component::class;
|
||||
$logAction->item_id = $component->id;
|
||||
$logAction->created_at = date('Y-m-d H:i:s');
|
||||
$logAction->action_date = date('Y-m-d H:i:s');
|
||||
$logAction->created_by = auth()->id();
|
||||
if($component->imported) {
|
||||
$logAction->setActionSource('importer');
|
||||
@@ -61,7 +56,6 @@ class ComponentObserver
|
||||
$logAction->item_type = Component::class;
|
||||
$logAction->item_id = $component->id;
|
||||
$logAction->created_at = date('Y-m-d H:i:s');
|
||||
$logAction->action_date = date('Y-m-d H:i:s');
|
||||
$logAction->created_by = auth()->id();
|
||||
$logAction->logaction('delete');
|
||||
}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Maintenance;
|
||||
use App\Models\Asset;
|
||||
|
||||
class MaintenanceObserver
|
||||
{
|
||||
/**
|
||||
* Listen to the User created event.
|
||||
*
|
||||
* @param Maintenance $maintenance
|
||||
* @return void
|
||||
*/
|
||||
public function updated(Maintenance $maintenance)
|
||||
{
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = Maintenance::class;
|
||||
$logAction->item_id = $maintenance->id;
|
||||
$logAction->target_type = Asset::class;
|
||||
$logAction->target_id = $maintenance->asset_id;
|
||||
$logAction->created_at = date('Y-m-d H:i:s');
|
||||
$logAction->action_date = date('Y-m-d H:i:s');
|
||||
$logAction->created_by = auth()->id();
|
||||
if($maintenance->imported) {
|
||||
$logAction->setActionSource('importer');
|
||||
}
|
||||
$logAction->logaction('update');
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen to the Component created event when
|
||||
* a new component is created.
|
||||
*
|
||||
* @param Maintenance $maintenance
|
||||
* @return void
|
||||
*/
|
||||
public function created(Maintenance $maintenance)
|
||||
{
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = Maintenance::class;
|
||||
$logAction->item_id = $maintenance->id;
|
||||
$logAction->target_type = Asset::class;
|
||||
$logAction->target_id = $maintenance->asset_id;
|
||||
$logAction->created_at = date('Y-m-d H:i:s');
|
||||
$logAction->action_date = date('Y-m-d H:i:s');
|
||||
$logAction->created_by = auth()->id();
|
||||
if($maintenance->imported) {
|
||||
$logAction->setActionSource('importer');
|
||||
}
|
||||
$logAction->logaction('create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen to the Component deleting event.
|
||||
*
|
||||
* @param Maintenance $maintenance
|
||||
* @return void
|
||||
*/
|
||||
public function deleting(Maintenance $maintenance)
|
||||
{
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = Maintenance::class;
|
||||
$logAction->item_id = $maintenance->id;
|
||||
$logAction->target_type = Asset::class;
|
||||
$logAction->target_id = $maintenance->asset_id;
|
||||
$logAction->created_at = date('Y-m-d H:i:s');
|
||||
$logAction->action_date = date('Y-m-d H:i:s');
|
||||
$logAction->created_by = auth()->id();
|
||||
$logAction->logaction('delete');
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Asset;
|
||||
|
||||
class AssetPolicy extends CheckoutablePermissionsPolicy
|
||||
{
|
||||
|
||||
@@ -85,7 +85,7 @@ abstract class SnipePermissionsPolicy
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
* Determine whether the user can view the accessory.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return mixed
|
||||
@@ -101,7 +101,7 @@ abstract class SnipePermissionsPolicy
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create model.
|
||||
* Determine whether the user can create accessories.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return mixed
|
||||
@@ -112,7 +112,7 @@ abstract class SnipePermissionsPolicy
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
* Determine whether the user can update the accessory.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return mixed
|
||||
@@ -124,7 +124,7 @@ abstract class SnipePermissionsPolicy
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
* Determine whether the user can update the accessory.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return mixed
|
||||
@@ -135,7 +135,7 @@ abstract class SnipePermissionsPolicy
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
* Determine whether the user can delete the accessory.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return mixed
|
||||
@@ -151,7 +151,7 @@ abstract class SnipePermissionsPolicy
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can manage the model.
|
||||
* Determine whether the user can manage the accessory.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return mixed
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace App\Presenters;
|
||||
/**
|
||||
* Class AssetModelPresenter
|
||||
*/
|
||||
class MaintenancesPresenter extends Presenter
|
||||
class AssetMaintenancesPresenter extends Presenter
|
||||
{
|
||||
/**
|
||||
* Json Column Layout for bootstrap table
|
||||
@@ -22,7 +22,7 @@ class MaintenancesPresenter extends Presenter
|
||||
'title' => trans('general.id'),
|
||||
'visible' => false,
|
||||
], [
|
||||
'field' => 'name',
|
||||
'field' => 'title',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
@@ -30,15 +30,6 @@ class MaintenancesPresenter extends Presenter
|
||||
'visible' => true,
|
||||
'formatter' => 'maintenancesLinkFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'image',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('general.image'),
|
||||
'visible' => true,
|
||||
'formatter' => 'imageFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'company',
|
||||
'searchable' => true,
|
||||
@@ -51,7 +42,7 @@ class MaintenancesPresenter extends Presenter
|
||||
'field' => 'asset_name',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'title' => trans('admin/maintenances/table.asset_name'),
|
||||
'title' => trans('admin/asset_maintenances/table.asset_name'),
|
||||
'formatter' => 'assetNameLinkFormatter',
|
||||
], [
|
||||
'field' => 'asset_tag',
|
||||
@@ -98,35 +89,35 @@ class MaintenancesPresenter extends Presenter
|
||||
'field' => 'asset_maintenance_type',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'title' => trans('admin/maintenances/form.asset_maintenance_type'),
|
||||
'title' => trans('admin/asset_maintenances/form.asset_maintenance_type'),
|
||||
], [
|
||||
'field' => 'start_date',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'title' => trans('admin/maintenances/form.start_date'),
|
||||
'title' => trans('admin/asset_maintenances/form.start_date'),
|
||||
'formatter' => 'dateDisplayFormatter',
|
||||
], [
|
||||
'field' => 'completion_date',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'title' => trans('admin/maintenances/form.completion_date'),
|
||||
'title' => trans('admin/asset_maintenances/form.completion_date'),
|
||||
'formatter' => 'dateDisplayFormatter',
|
||||
], [
|
||||
'field' => 'notes',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'title' => trans('admin/maintenances/form.notes'),
|
||||
'title' => trans('admin/asset_maintenances/form.notes'),
|
||||
], [
|
||||
'field' => 'is_warranty',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'title' => trans('admin/maintenances/table.is_warranty'),
|
||||
'title' => trans('admin/asset_maintenances/table.is_warranty'),
|
||||
'formatter' => 'trueFalseFormatter'
|
||||
], [
|
||||
'field' => 'cost',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'title' => trans('admin/maintenances/form.cost'),
|
||||
'title' => trans('admin/asset_maintenances/form.cost'),
|
||||
'class' => 'text-right',
|
||||
], [
|
||||
'field' => 'created_by',
|
||||
@@ -328,7 +328,7 @@ class AssetPresenter extends Presenter
|
||||
// name can break the listings page. - snipe
|
||||
foreach ($fields as $field) {
|
||||
$layout[] = [
|
||||
'field' => $field->db_column,
|
||||
'field' => 'custom_fields.'.$field->db_column,
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
|
||||
@@ -53,7 +53,6 @@ class LicensePresenter extends Presenter
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'title' => trans('admin/licenses/form.to_email'),
|
||||
'formatter' => 'emailFormatter',
|
||||
], [
|
||||
'field' => 'license_name',
|
||||
'searchable' => true,
|
||||
|
||||
@@ -67,9 +67,7 @@ class LocationPresenter extends Presenter
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('admin/locations/message.current_location'),
|
||||
'titleTooltip' => trans('admin/locations/message.current_location'),
|
||||
'visible' => true,
|
||||
'class' => 'css-house-laptop',
|
||||
], [
|
||||
'field' => 'rtd_assets_count',
|
||||
'searchable' => false,
|
||||
|
||||
@@ -124,15 +124,6 @@ class UserPresenter extends Presenter
|
||||
'visible' => true,
|
||||
'formatter' => 'phoneFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'mobile',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'switchable' => true,
|
||||
'title' => trans('admin/users/table.mobile'),
|
||||
'visible' => false,
|
||||
'formatter' => 'mobileFormatter',
|
||||
],
|
||||
[
|
||||
'field' => 'website',
|
||||
'searchable' => true,
|
||||
|
||||
@@ -7,7 +7,6 @@ use App\Models\Asset;
|
||||
use App\Models\Component;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\License;
|
||||
use App\Models\Maintenance;
|
||||
use App\Models\User;
|
||||
use App\Models\Setting;
|
||||
use App\Models\SnipeSCIMConfig;
|
||||
@@ -18,7 +17,6 @@ use App\Observers\ComponentObserver;
|
||||
use App\Observers\ConsumableObserver;
|
||||
use App\Observers\LicenseObserver;
|
||||
use App\Observers\SettingObserver;
|
||||
use App\Observers\MaintenanceObserver;
|
||||
use Illuminate\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
@@ -69,7 +67,6 @@ class AppServiceProvider extends ServiceProvider
|
||||
|
||||
Schema::defaultStringLength(191);
|
||||
Asset::observe(AssetObserver::class);
|
||||
Maintenance::observe(MaintenanceObserver::class);
|
||||
User::observe(UserObserver::class);
|
||||
Accessory::observe(AccessoryObserver::class);
|
||||
Component::observe(ComponentObserver::class);
|
||||
@@ -85,12 +82,6 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
|
||||
if ($this->app->environment('local')) {
|
||||
$this->app->register(\Laravel\Telescope\TelescopeServiceProvider::class);
|
||||
$this->app->register(TelescopeServiceProvider::class);
|
||||
}
|
||||
|
||||
// Only load rollbar if there is a rollbar key and the app is in production
|
||||
if (($this->app->environment('production')) && (config('logging.channels.rollbar.access_token'))) {
|
||||
$this->app->register(\Rollbar\Laravel\RollbarServiceProvider::class);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Maintenance;
|
||||
use App\Models\AssetMaintenance;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Category;
|
||||
use App\Models\Company;
|
||||
@@ -413,14 +413,14 @@ class BreadcrumbsServiceProvider extends ServiceProvider
|
||||
->push(trans('general.create'), route('maintenances.create'))
|
||||
);
|
||||
|
||||
Breadcrumbs::for('maintenances.show', fn (Trail $trail, Maintenance $maintenance) =>
|
||||
Breadcrumbs::for('maintenances.show', fn (Trail $trail, AssetMaintenance $maintenance) =>
|
||||
$trail->parent('maintenances.index', route('maintenances.index'))
|
||||
->push($maintenance->name, route('maintenances.show', $maintenance))
|
||||
->push($maintenance->title, route('maintenances.show', $maintenance))
|
||||
);
|
||||
|
||||
Breadcrumbs::for('maintenances.edit', fn (Trail $trail, Maintenance $maintenance) =>
|
||||
Breadcrumbs::for('maintenances.edit', fn (Trail $trail, AssetMaintenance $maintenance) =>
|
||||
$trail->parent('maintenances.index', route('maintenances.index'))
|
||||
->push(trans('general.breadcrumb_button_actions.edit_item', ['name' => $maintenance->name]), route('maintenances.edit', $maintenance))
|
||||
->push(trans('general.breadcrumb_button_actions.edit_item', ['name' => $maintenance->title]), route('maintenances.edit', $maintenance))
|
||||
);
|
||||
|
||||
|
||||
@@ -549,16 +549,6 @@ class BreadcrumbsServiceProvider extends ServiceProvider
|
||||
->push(trans('general.users'), route('users.index'))
|
||||
->push(trans('general.show_superadmins'), route('users.index'))
|
||||
);
|
||||
} elseif ((request()->is('users*')) && (request()->activated=='0')) {
|
||||
Breadcrumbs::for('users.index', fn(Trail $trail) => $trail->parent('home', route('home'))
|
||||
->push(trans('general.users'), route('users.index'))
|
||||
->push(trans('general.login_disabled'), route('users.index'))
|
||||
);
|
||||
} elseif ((request()->is('users*')) && (request()->activated=='1')) {
|
||||
Breadcrumbs::for('users.index', fn(Trail $trail) => $trail->parent('home', route('home'))
|
||||
->push(trans('general.users'), route('users.index'))
|
||||
->push(trans('general.login_enabled'), route('users.index'))
|
||||
);
|
||||
} else {
|
||||
Breadcrumbs::for('users.index', fn(Trail $trail) => $trail->parent('home', route('home'))
|
||||
->push(trans('general.users'), route('users.index'))
|
||||
|
||||
@@ -31,7 +31,7 @@ class SettingsServiceProvider extends ServiceProvider
|
||||
|
||||
|
||||
// Make sure the limit is actually set, is an integer and does not exceed system limits
|
||||
app()->singleton('api_limit_value', function () {
|
||||
\App::singleton('api_limit_value', function () {
|
||||
$limit = config('app.max_results');
|
||||
$int_limit = intval(request('limit'));
|
||||
|
||||
@@ -43,7 +43,7 @@ class SettingsServiceProvider extends ServiceProvider
|
||||
});
|
||||
|
||||
// Make sure the offset is actually set and is an integer
|
||||
app()->singleton('api_offset_value', function () {
|
||||
\App::singleton('api_offset_value', function () {
|
||||
$offset = intval(request('offset'));
|
||||
return $offset;
|
||||
});
|
||||
@@ -57,121 +57,117 @@ class SettingsServiceProvider extends ServiceProvider
|
||||
// Model paths and URLs
|
||||
|
||||
|
||||
app()->singleton('eula_pdf_path', function () {
|
||||
\App::singleton('eula_pdf_path', function () {
|
||||
return 'eula_pdf_path/';
|
||||
});
|
||||
|
||||
app()->singleton('assets_upload_path', function () {
|
||||
\App::singleton('assets_upload_path', function () {
|
||||
return 'assets/';
|
||||
});
|
||||
|
||||
app()->singleton('maintenances_path', function () {
|
||||
return 'maintenances/';
|
||||
});
|
||||
|
||||
app()->singleton('audits_upload_path', function () {
|
||||
\App::singleton('audits_upload_path', function () {
|
||||
return 'audits/';
|
||||
});
|
||||
|
||||
app()->singleton('accessories_upload_path', function () {
|
||||
\App::singleton('accessories_upload_path', function () {
|
||||
return 'public/uploads/accessories/';
|
||||
});
|
||||
|
||||
app()->singleton('models_upload_path', function () {
|
||||
\App::singleton('models_upload_path', function () {
|
||||
return 'models/';
|
||||
});
|
||||
|
||||
app()->singleton('models_upload_url', function () {
|
||||
\App::singleton('models_upload_url', function () {
|
||||
return 'models/';
|
||||
});
|
||||
|
||||
// Categories
|
||||
app()->singleton('categories_upload_path', function () {
|
||||
\App::singleton('categories_upload_path', function () {
|
||||
return 'categories/';
|
||||
});
|
||||
|
||||
app()->singleton('categories_upload_url', function () {
|
||||
\App::singleton('categories_upload_url', function () {
|
||||
return 'categories/';
|
||||
});
|
||||
|
||||
// Locations
|
||||
app()->singleton('locations_upload_path', function () {
|
||||
\App::singleton('locations_upload_path', function () {
|
||||
return 'locations/';
|
||||
});
|
||||
|
||||
app()->singleton('locations_upload_url', function () {
|
||||
\App::singleton('locations_upload_url', function () {
|
||||
return 'locations/';
|
||||
});
|
||||
|
||||
// Users
|
||||
app()->singleton('users_upload_path', function () {
|
||||
\App::singleton('users_upload_path', function () {
|
||||
return 'avatars/';
|
||||
});
|
||||
|
||||
app()->singleton('users_upload_url', function () {
|
||||
\App::singleton('users_upload_url', function () {
|
||||
return 'users/';
|
||||
});
|
||||
|
||||
// Manufacturers
|
||||
app()->singleton('manufacturers_upload_path', function () {
|
||||
\App::singleton('manufacturers_upload_path', function () {
|
||||
return 'manufacturers/';
|
||||
});
|
||||
|
||||
app()->singleton('manufacturers_upload_url', function () {
|
||||
\App::singleton('manufacturers_upload_url', function () {
|
||||
return 'manufacturers/';
|
||||
});
|
||||
|
||||
// Suppliers
|
||||
app()->singleton('suppliers_upload_path', function () {
|
||||
\App::singleton('suppliers_upload_path', function () {
|
||||
return 'suppliers/';
|
||||
});
|
||||
|
||||
app()->singleton('suppliers_upload_url', function () {
|
||||
\App::singleton('suppliers_upload_url', function () {
|
||||
return 'suppliers/';
|
||||
});
|
||||
|
||||
// Departments
|
||||
app()->singleton('departments_upload_path', function () {
|
||||
\App::singleton('departments_upload_path', function () {
|
||||
return 'departments/';
|
||||
});
|
||||
|
||||
app()->singleton('departments_upload_url', function () {
|
||||
\App::singleton('departments_upload_url', function () {
|
||||
return 'departments/';
|
||||
});
|
||||
|
||||
// Company paths and URLs
|
||||
app()->singleton('companies_upload_path', function () {
|
||||
\App::singleton('companies_upload_path', function () {
|
||||
return 'companies/';
|
||||
});
|
||||
|
||||
app()->singleton('companies_upload_url', function () {
|
||||
\App::singleton('companies_upload_url', function () {
|
||||
return 'companies/';
|
||||
});
|
||||
|
||||
// Accessories paths and URLs
|
||||
app()->singleton('accessories_upload_path', function () {
|
||||
\App::singleton('accessories_upload_path', function () {
|
||||
return 'accessories/';
|
||||
});
|
||||
|
||||
app()->singleton('accessories_upload_url', function () {
|
||||
\App::singleton('accessories_upload_url', function () {
|
||||
return 'accessories/';
|
||||
});
|
||||
|
||||
// Consumables paths and URLs
|
||||
app()->singleton('consumables_upload_path', function () {
|
||||
\App::singleton('consumables_upload_path', function () {
|
||||
return 'consumables/';
|
||||
});
|
||||
|
||||
app()->singleton('consumables_upload_url', function () {
|
||||
\App::singleton('consumables_upload_url', function () {
|
||||
return 'consumables/';
|
||||
});
|
||||
|
||||
// Components paths and URLs
|
||||
app()->singleton('components_upload_path', function () {
|
||||
\App::singleton('components_upload_path', function () {
|
||||
return 'components/';
|
||||
});
|
||||
|
||||
app()->singleton('components_upload_url', function () {
|
||||
\App::singleton('components_upload_url', function () {
|
||||
return 'components/';
|
||||
});
|
||||
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Laravel\Telescope\IncomingEntry;
|
||||
use Laravel\Telescope\Telescope;
|
||||
use Laravel\Telescope\TelescopeApplicationServiceProvider;
|
||||
|
||||
class TelescopeServiceProvider extends TelescopeApplicationServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
// Telescope::night();
|
||||
|
||||
$this->hideSensitiveRequestDetails();
|
||||
|
||||
$isLocal = $this->app->environment('local');
|
||||
|
||||
Telescope::filter(function (IncomingEntry $entry) use ($isLocal) {
|
||||
return $isLocal ||
|
||||
$entry->isReportableException() ||
|
||||
$entry->isFailedRequest() ||
|
||||
$entry->isFailedJob() ||
|
||||
$entry->isScheduledTask() ||
|
||||
$entry->hasMonitoredTag();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent sensitive request details from being logged by Telescope.
|
||||
*/
|
||||
protected function hideSensitiveRequestDetails(): void
|
||||
{
|
||||
if ($this->app->environment('local')) {
|
||||
return;
|
||||
}
|
||||
|
||||
Telescope::hideRequestParameters(['_token']);
|
||||
|
||||
Telescope::hideRequestHeaders([
|
||||
'cookie',
|
||||
'x-csrf-token',
|
||||
'x-xsrf-token',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the Telescope gate.
|
||||
*
|
||||
* This gate determines who can access Telescope in NON-LOCAL environments.
|
||||
*/
|
||||
protected function gate(): void
|
||||
{
|
||||
Gate::define('viewTelescope', function ($user) {
|
||||
if ($user->isSuperUser()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@
|
||||
"doctrine/dbal": "^3.1",
|
||||
"doctrine/instantiator": "^1.3",
|
||||
"eduardokum/laravel-mail-auto-embed": "^2.0",
|
||||
"enshrined/svg-sanitize": "^0.22.0",
|
||||
"enshrined/svg-sanitize": "^0.16.0",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"fakerphp/faker": "^1.24",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
@@ -84,7 +84,6 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"larastan/larastan": "^2.9",
|
||||
"laravel/telescope": "^5.11",
|
||||
"mockery/mockery": "^1.4",
|
||||
"nunomaduro/phpinsights": "^2.11",
|
||||
"php-mock/php-mock-phpunit": "^2.10",
|
||||
@@ -96,8 +95,7 @@
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"dont-discover": [
|
||||
"rollbar/rollbar-laravel",
|
||||
"laravel/telescope"
|
||||
"rollbar/rollbar-laravel"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
149
composer.lock
generated
149
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "41f2c8e1296de21aaf82d4b1bfbc1800",
|
||||
"content-hash": "75fb4f46ea0a488c2dd45d73eb2a9b9d",
|
||||
"packages": [
|
||||
{
|
||||
"name": "alek13/slack",
|
||||
@@ -1678,25 +1678,26 @@
|
||||
},
|
||||
{
|
||||
"name": "enshrined/svg-sanitize",
|
||||
"version": "0.22.0",
|
||||
"version": "0.16.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/darylldoyle/svg-sanitizer.git",
|
||||
"reference": "0afa95ea74be155a7bcd6c6fb60c276c39984500"
|
||||
"reference": "239e257605e2141265b429e40987b2ee51bba4b4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/darylldoyle/svg-sanitizer/zipball/0afa95ea74be155a7bcd6c6fb60c276c39984500",
|
||||
"reference": "0afa95ea74be155a7bcd6c6fb60c276c39984500",
|
||||
"url": "https://api.github.com/repos/darylldoyle/svg-sanitizer/zipball/239e257605e2141265b429e40987b2ee51bba4b4",
|
||||
"reference": "239e257605e2141265b429e40987b2ee51bba4b4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-libxml": "*",
|
||||
"php": "^7.1 || ^8.0"
|
||||
"ezyang/htmlpurifier": "^4.16",
|
||||
"php": "^5.6 || ^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.5 || ^8.5"
|
||||
"phpunit/phpunit": "^5.7 || ^6.5 || ^8.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -1717,9 +1718,9 @@
|
||||
"description": "An SVG sanitizer for PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/darylldoyle/svg-sanitizer/issues",
|
||||
"source": "https://github.com/darylldoyle/svg-sanitizer/tree/0.22.0"
|
||||
"source": "https://github.com/darylldoyle/svg-sanitizer/tree/0.16.0"
|
||||
},
|
||||
"time": "2025-08-12T10:13:48+00:00"
|
||||
"time": "2023-03-20T10:51:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "erusev/parsedown",
|
||||
@@ -1771,6 +1772,67 @@
|
||||
},
|
||||
"time": "2019-12-30T22:54:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ezyang/htmlpurifier",
|
||||
"version": "v4.18.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ezyang/htmlpurifier.git",
|
||||
"reference": "cb56001e54359df7ae76dc522d08845dc741621b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/cb56001e54359df7ae76dc522d08845dc741621b",
|
||||
"reference": "cb56001e54359df7ae76dc522d08845dc741621b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cerdic/css-tidy": "^1.7 || ^2.0",
|
||||
"simpletest/simpletest": "dev-master"
|
||||
},
|
||||
"suggest": {
|
||||
"cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.",
|
||||
"ext-bcmath": "Used for unit conversion and imagecrash protection",
|
||||
"ext-iconv": "Converts text to and from non-UTF-8 encodings",
|
||||
"ext-tidy": "Used for pretty-printing HTML"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"library/HTMLPurifier.composer.php"
|
||||
],
|
||||
"psr-0": {
|
||||
"HTMLPurifier": "library/"
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/library/HTMLPurifier/Language/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Edward Z. Yang",
|
||||
"email": "admin@htmlpurifier.org",
|
||||
"homepage": "http://ezyang.com"
|
||||
}
|
||||
],
|
||||
"description": "Standards compliant HTML filter written in PHP",
|
||||
"homepage": "http://htmlpurifier.org/",
|
||||
"keywords": [
|
||||
"html"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/ezyang/htmlpurifier/issues",
|
||||
"source": "https://github.com/ezyang/htmlpurifier/tree/v4.18.0"
|
||||
},
|
||||
"time": "2024-11-01T03:51:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fakerphp/faker",
|
||||
"version": "v1.24.1",
|
||||
@@ -12883,75 +12945,6 @@
|
||||
],
|
||||
"time": "2025-06-10T22:06:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/telescope",
|
||||
"version": "v5.11.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/telescope.git",
|
||||
"reference": "62e1a21db3db3e7440e9ca02ffa3efce14d6b85e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/telescope/zipball/62e1a21db3db3e7440e9ca02ffa3efce14d6b85e",
|
||||
"reference": "62e1a21db3db3e7440e9ca02ffa3efce14d6b85e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"laravel/framework": "^8.37|^9.0|^10.0|^11.0|^12.0",
|
||||
"php": "^8.0",
|
||||
"symfony/console": "^5.3|^6.0|^7.0",
|
||||
"symfony/var-dumper": "^5.0|^6.0|^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-gd": "*",
|
||||
"guzzlehttp/guzzle": "^6.0|^7.0",
|
||||
"laravel/octane": "^1.4|^2.0|dev-develop",
|
||||
"orchestra/testbench": "^6.40|^7.37|^8.17|^9.0|^10.0",
|
||||
"phpstan/phpstan": "^1.10",
|
||||
"phpunit/phpunit": "^9.0|^10.5|^11.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Laravel\\Telescope\\TelescopeServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Laravel\\Telescope\\": "src/",
|
||||
"Laravel\\Telescope\\Database\\Factories\\": "database/factories/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
},
|
||||
{
|
||||
"name": "Mohamed Said",
|
||||
"email": "mohamed@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "An elegant debug assistant for the Laravel framework.",
|
||||
"keywords": [
|
||||
"debugging",
|
||||
"laravel",
|
||||
"monitoring"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/telescope/issues",
|
||||
"source": "https://github.com/laravel/telescope/tree/v5.11.2"
|
||||
},
|
||||
"time": "2025-08-16T00:52:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/container",
|
||||
"version": "5.1.0",
|
||||
|
||||
@@ -123,9 +123,6 @@ $config['allowed_upload_extensions_array'] = [
|
||||
'mov',
|
||||
'mp3',
|
||||
'mp4',
|
||||
'odp',
|
||||
'ods',
|
||||
'odt',
|
||||
'ogg',
|
||||
'pdf',
|
||||
'png',
|
||||
@@ -143,15 +140,12 @@ $config['allowed_upload_extensions_array'] = [
|
||||
];
|
||||
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/MIME_types/Common_types
|
||||
|
||||
$config['allowed_upload_mimetypes_array'] = [
|
||||
'application/json',
|
||||
'application/msword',
|
||||
'application/pdf',
|
||||
'application/vnd.ms-excel',
|
||||
'application/vnd.oasis.opendocument.presentation',
|
||||
'application/vnd.oasis.opendocument.spreadsheet',
|
||||
'application/vnd.oasis.opendocument.text',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'application/x-rar-compressed',
|
||||
|
||||
192
config/mail.php
192
config/mail.php
@@ -4,50 +4,31 @@
|
||||
|--------------------------------------------------------------------------
|
||||
| DO NOT EDIT THIS FILE DIRECTLY.
|
||||
|--------------------------------------------------------------------------
|
||||
| This file reads from your .env configuration file and should not
|
||||
| This file reads from your .env configuration file and should NOT
|
||||
| be modified directly.
|
||||
| See https://snipe-it.readme.io/docs/configuration for more info.
|
||||
*/
|
||||
|
||||
|
||||
return [
|
||||
|
||||
|
||||
/*
|
||||
| ***************************************************************************
|
||||
| DO NOT MAKE CHANGES DIRECTLY TO THIS FILE.
|
||||
|
|
||||
| Instead use your .env file to set your application configuration settings.
|
||||
| See https://snipe-it.readme.io/docs/configuration for more info.
|
||||
|
|
||||
|--------------------------------------------------------------------------
|
||||
| Mail Driver
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
|
||||
| sending of e-mail. You may specify which one you're using throughout
|
||||
| your application here. By default, Laravel is setup for SMTP mail.
|
||||
|
|
||||
|
|
||||
| Supported: "smtp", "mail", "sendmail", "mailgun", "mandrill", "ses", "log"
|
||||
|
|
||||
*/
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Mailer
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option controls the default mailer that is used to send any email
|
||||
| messages sent by your application. Alternative mailers may be setup
|
||||
| and used as needed; however, this mailer will be used by default.
|
||||
| This option controls the default mailer that is used to send all email
|
||||
| messages unless another mailer is explicitly specified when sending
|
||||
| the message. All additional mailers can be configured within the
|
||||
| "mailers" array. Examples of each type of mailer are provided.
|
||||
|
|
||||
| Previous versions of Snipe-IT and Laravel used SwiftMailer, which used
|
||||
| MAIL_DRIVER instead of MAIL_MAILER. In order to not break existing
|
||||
| installations, we'll accept both
|
||||
| installations, we'll accept both.
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('MAIL_DRIVER') != null ? env('MAIL_DRIVER') : env('MAIL_MAILER', 'smtp'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Mailer Configurations
|
||||
@@ -57,112 +38,29 @@ return [
|
||||
| their respective settings. Several examples have been configured for
|
||||
| you and you are free to add your own as your application requires.
|
||||
|
|
||||
| Laravel supports a variety of mail "transport" drivers to be used while
|
||||
| sending an e-mail. You will specify which one you are using for your
|
||||
| mailers below. You are free to add additional mailers as required.
|
||||
| Laravel supports a variety of mail "transport" drivers that can be used
|
||||
| when delivering an email. You may specify which one you're using for
|
||||
| your mailers below. You may also add additional mailers if needed.
|
||||
|
|
||||
| Supported: "smtp", "sendmail", "mailgun", "ses", "ses-v2",
|
||||
| "postmark", "log", "array", "failover", "roundrobin"
|
||||
| "postmark", "resend", "log", "array",
|
||||
| "failover", "roundrobin"
|
||||
|
|
||||
*/
|
||||
|
||||
'mailers' => [
|
||||
|
||||
'smtp' => [
|
||||
// Don't touch this. For the smtp mailer, the transport needs to be smtp
|
||||
'transport' => 'smtp',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| SMTP Host Address
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may provide the host address of the SMTP server used by your
|
||||
| applications. A default option is provided that is compatible with
|
||||
| the Mailgun mail service which will provide reliable deliveries.
|
||||
|
|
||||
*/
|
||||
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
|
||||
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| SMTP Host Port
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is the SMTP port used by your application to deliver e-mails to
|
||||
| users of the application. Like the host we have set this value to
|
||||
| stay compatible with the Mailgun e-mail application by default.
|
||||
|
|
||||
*/
|
||||
|
||||
'port' => env('MAIL_PORT', 587),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| SMTP Server Username
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If your SMTP server requires a username for authentication, you should
|
||||
| set it here. This will get used to authenticate with your server on
|
||||
| connection. You may also set the "password" value below this one.
|
||||
|
|
||||
*/
|
||||
|
||||
'scheme' => env('MAIL_SCHEME'),
|
||||
'url' => env('MAIL_URL'),
|
||||
'host' => env('MAIL_HOST', '127.0.0.1'),
|
||||
'port' => env('MAIL_PORT', 2525),
|
||||
'username' => env('MAIL_USERNAME'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| SMTP Server Password
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may set the password required by your SMTP server to send out
|
||||
| messages from your application. This will be given to the server on
|
||||
| connection so that the application will be able to send messages.
|
||||
|
|
||||
*/
|
||||
|
||||
'password' => env('MAIL_PASSWORD'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| SMTP Server connection timeout
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Give up trying to connect to the mail server after this many seconds
|
||||
|
|
||||
*/
|
||||
|
||||
'timeout' => 30,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| mostly pointless encryption option
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This used to let you specify whether or not to use TLS, but now it really
|
||||
| just helps inform the code about which SMTP port to use. SymfonMailer will
|
||||
| still use TLS if the server offers it, regardless of how this is set.
|
||||
| We're only including it here for reference, and the extreme edge-case where
|
||||
| Symfony can't figure out what to do on its own.
|
||||
|
|
||||
*/
|
||||
|
||||
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Verify SMTP TLS certificate
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| As noted above, Swiftmailer WILL use TLS if the server offers it, so if
|
||||
| you're using a self-signed certificate or want to refer to your mailserver
|
||||
| by a name that isn't in the certificate (like the IP address), set this
|
||||
| to 0 or false.
|
||||
|
|
||||
*/
|
||||
|
||||
'timeout' => null,
|
||||
'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url(env('APP_URL', 'http://localhost'), PHP_URL_HOST)),
|
||||
'verify_peer' => env('MAIL_TLS_VERIFY_PEER', 1),
|
||||
|
||||
],
|
||||
|
||||
'ses' => [
|
||||
@@ -171,29 +69,16 @@ return [
|
||||
|
||||
'postmark' => [
|
||||
'transport' => 'postmark',
|
||||
// 'message_stream_id' => null,
|
||||
// 'message_stream_id' => env('POSTMARK_MESSAGE_STREAM_ID'),
|
||||
// 'client' => [
|
||||
// 'timeout' => 5,
|
||||
// ],
|
||||
],
|
||||
|
||||
'mailgun' => [
|
||||
'transport' => 'mailgun',
|
||||
// 'client' => [
|
||||
// 'timeout' => 5,
|
||||
// ],
|
||||
'resend' => [
|
||||
'transport' => 'resend',
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Sendmail System Path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When using the "sendmail" driver to send e-mails, we will need to know
|
||||
| the path to where Sendmail lives on this server. A default path has
|
||||
| been provided here, which will work well on most of your systems.
|
||||
|
|
||||
*/
|
||||
'sendmail' => [
|
||||
'transport' => 'sendmail',
|
||||
'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'),
|
||||
@@ -223,6 +108,7 @@ return [
|
||||
'postmark',
|
||||
],
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
@@ -230,15 +116,15 @@ return [
|
||||
| Global "From" Address
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| You may wish for all e-mails sent by your application to be sent from
|
||||
| the same address. Here, you may specify a name and address that is
|
||||
| used globally for all e-mails that are sent by your application.
|
||||
| You may wish for all emails sent by your application to be sent from
|
||||
| the same address. Here you may specify a name and address that is
|
||||
| used globally for all emails that are sent by your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'from' => [
|
||||
'address' => env('MAIL_FROM_ADDR', null),
|
||||
'name' => env('MAIL_FROM_NAME', null),
|
||||
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
|
||||
'name' => env('MAIL_FROM_NAME', 'Example'),
|
||||
],
|
||||
|
||||
/*
|
||||
@@ -257,23 +143,5 @@ return [
|
||||
'name' => env('MAIL_REPLYTO_NAME', null),
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Markdown Mail Settings
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If you are using Markdown based email rendering, you may configure your
|
||||
| theme and component paths here, allowing you to customize the design
|
||||
| of the emails. Or, you may simply stick with the Laravel defaults!
|
||||
|
|
||||
*/
|
||||
|
||||
'markdown' => [
|
||||
'theme' => 'default',
|
||||
|
||||
'paths' => [
|
||||
resource_path('views/vendor/mail'),
|
||||
],
|
||||
],
|
||||
|
||||
];
|
||||
];
|
||||
@@ -1,205 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Laravel\Telescope\Http\Middleware\Authorize;
|
||||
use Laravel\Telescope\Watchers;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Telescope Master Switch
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option may be used to disable all Telescope watchers regardless
|
||||
| of their individual configuration, which simply provides a single
|
||||
| and convenient way to enable or disable Telescope data storage.
|
||||
|
|
||||
*/
|
||||
|
||||
'enabled' => env('TELESCOPE_ENABLED', false),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Telescope Domain
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is the subdomain where Telescope will be accessible from. If the
|
||||
| setting is null, Telescope will reside under the same domain as the
|
||||
| application. Otherwise, this value will be used as the subdomain.
|
||||
|
|
||||
*/
|
||||
|
||||
'domain' => env('TELESCOPE_DOMAIN'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Telescope Path
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This is the URI path where Telescope will be accessible from. Feel free
|
||||
| to change this path to anything you like. Note that the URI will not
|
||||
| affect the paths of its internal API that aren't exposed to users.
|
||||
|
|
||||
*/
|
||||
|
||||
'path' => env('TELESCOPE_PATH', 'telescope'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Telescope Storage Driver
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This configuration options determines the storage driver that will
|
||||
| be used to store Telescope's data. In addition, you may set any
|
||||
| custom options as needed by the particular driver you choose.
|
||||
|
|
||||
*/
|
||||
|
||||
'driver' => env('TELESCOPE_DRIVER', 'database'),
|
||||
|
||||
'storage' => [
|
||||
'database' => [
|
||||
'connection' => env('DB_CONNECTION', 'mysql'),
|
||||
'chunk' => 1000,
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Telescope Queue
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This configuration options determines the queue connection and queue
|
||||
| which will be used to process ProcessPendingUpdate jobs. This can
|
||||
| be changed if you would prefer to use a non-default connection.
|
||||
|
|
||||
*/
|
||||
|
||||
'queue' => [
|
||||
'connection' => env('TELESCOPE_QUEUE_CONNECTION'),
|
||||
'queue' => env('TELESCOPE_QUEUE'),
|
||||
'delay' => env('TELESCOPE_QUEUE_DELAY', 10),
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Telescope Route Middleware
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| These middleware will be assigned to every Telescope route, giving you
|
||||
| the chance to add your own middleware to this list or change any of
|
||||
| the existing middleware. Or, you can simply stick with this list.
|
||||
|
|
||||
*/
|
||||
|
||||
'middleware' => [
|
||||
'web',
|
||||
Authorize::class,
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Allowed / Ignored Paths & Commands
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following array lists the URI paths and Artisan commands that will
|
||||
| not be watched by Telescope. In addition to this list, some Laravel
|
||||
| commands, like migrations and queue commands, are always ignored.
|
||||
|
|
||||
*/
|
||||
|
||||
'only_paths' => [
|
||||
// 'api/*'
|
||||
],
|
||||
|
||||
'ignore_paths' => [
|
||||
'livewire*',
|
||||
],
|
||||
|
||||
'ignore_commands' => [
|
||||
//
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Telescope Watchers
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following array lists the "watchers" that will be registered with
|
||||
| Telescope. The watchers gather the application's profile data when
|
||||
| a request or task is executed. Feel free to customize this list.
|
||||
|
|
||||
*/
|
||||
|
||||
'watchers' => [
|
||||
Watchers\BatchWatcher::class => env('TELESCOPE_BATCH_WATCHER', true),
|
||||
|
||||
Watchers\CacheWatcher::class => [
|
||||
'enabled' => env('TELESCOPE_CACHE_WATCHER', true),
|
||||
'hidden' => [],
|
||||
'ignore' => [],
|
||||
],
|
||||
|
||||
Watchers\ClientRequestWatcher::class => env('TELESCOPE_CLIENT_REQUEST_WATCHER', true),
|
||||
|
||||
Watchers\CommandWatcher::class => [
|
||||
'enabled' => env('TELESCOPE_COMMAND_WATCHER', true),
|
||||
'ignore' => [],
|
||||
],
|
||||
|
||||
Watchers\DumpWatcher::class => [
|
||||
'enabled' => env('TELESCOPE_DUMP_WATCHER', true),
|
||||
'always' => env('TELESCOPE_DUMP_WATCHER_ALWAYS', false),
|
||||
],
|
||||
|
||||
Watchers\EventWatcher::class => [
|
||||
'enabled' => env('TELESCOPE_EVENT_WATCHER', true),
|
||||
'ignore' => [],
|
||||
],
|
||||
|
||||
Watchers\ExceptionWatcher::class => env('TELESCOPE_EXCEPTION_WATCHER', true),
|
||||
|
||||
Watchers\GateWatcher::class => [
|
||||
'enabled' => env('TELESCOPE_GATE_WATCHER', true),
|
||||
'ignore_abilities' => [],
|
||||
'ignore_packages' => true,
|
||||
'ignore_paths' => [],
|
||||
],
|
||||
|
||||
Watchers\JobWatcher::class => env('TELESCOPE_JOB_WATCHER', true),
|
||||
|
||||
Watchers\LogWatcher::class => [
|
||||
'enabled' => env('TELESCOPE_LOG_WATCHER', true),
|
||||
'level' => 'error',
|
||||
],
|
||||
|
||||
Watchers\MailWatcher::class => env('TELESCOPE_MAIL_WATCHER', true),
|
||||
|
||||
Watchers\ModelWatcher::class => [
|
||||
'enabled' => env('TELESCOPE_MODEL_WATCHER', true),
|
||||
'events' => ['eloquent.*'],
|
||||
'hydrations' => true,
|
||||
],
|
||||
|
||||
Watchers\NotificationWatcher::class => env('TELESCOPE_NOTIFICATION_WATCHER', true),
|
||||
|
||||
Watchers\QueryWatcher::class => [
|
||||
'enabled' => env('TELESCOPE_QUERY_WATCHER', true),
|
||||
'ignore_packages' => true,
|
||||
'ignore_paths' => [],
|
||||
'slow' => 100,
|
||||
],
|
||||
|
||||
Watchers\RedisWatcher::class => env('TELESCOPE_REDIS_WATCHER', true),
|
||||
|
||||
Watchers\RequestWatcher::class => [
|
||||
'enabled' => env('TELESCOPE_REQUEST_WATCHER', true),
|
||||
'size_limit' => env('TELESCOPE_RESPONSE_SIZE_LIMIT', 64),
|
||||
'ignore_http_methods' => [],
|
||||
'ignore_status_codes' => [],
|
||||
],
|
||||
|
||||
Watchers\ScheduleWatcher::class => env('TELESCOPE_SCHEDULE_WATCHER', true),
|
||||
Watchers\ViewWatcher::class => env('TELESCOPE_VIEW_WATCHER', true),
|
||||
],
|
||||
];
|
||||
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
return array (
|
||||
'app_version' => 'v8.2.2-pre',
|
||||
'full_app_version' => 'v8.2.2-pre - build 19319-ga36afbcb2',
|
||||
'build_version' => '19319',
|
||||
'app_version' => 'v8.2.1',
|
||||
'full_app_version' => 'v8.2.1 - build 19068-g6ca49a20c',
|
||||
'build_version' => '19068',
|
||||
'prerelease_version' => '',
|
||||
'hash_version' => 'ga36afbcb2',
|
||||
'full_hash' => 'v8.2.2-pre-249-ga36afbcb2',
|
||||
'hash_version' => 'g6ca49a20c',
|
||||
'full_hash' => 'v8.2.1-10-g6ca49a20c',
|
||||
'branch' => 'develop',
|
||||
);
|
||||
@@ -3,18 +3,18 @@
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\Maintenance;
|
||||
use App\Models\AssetMaintenance;
|
||||
use App\Models\Supplier;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class MaintenanceFactory extends Factory
|
||||
class AssetMaintenanceFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = Maintenance::class;
|
||||
protected $model = AssetMaintenance::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
@@ -27,7 +27,7 @@ class MaintenanceFactory extends Factory
|
||||
'asset_id' => Asset::factory(),
|
||||
'supplier_id' => Supplier::factory(),
|
||||
'asset_maintenance_type' => $this->faker->randomElement(['maintenance', 'repair', 'upgrade']),
|
||||
'name' => $this->faker->sentence(),
|
||||
'title' => $this->faker->sentence(),
|
||||
'start_date' => $this->faker->date(),
|
||||
'is_warranty' => $this->faker->boolean(),
|
||||
'notes' => $this->faker->paragraph(),
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\CheckoutRequest;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class CheckoutRequestFactory extends Factory
|
||||
{
|
||||
protected $model = CheckoutRequest::class;
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'requestable_id' => Asset::factory(),
|
||||
'requestable_type' => Asset::class,
|
||||
'quantity' => 1,
|
||||
'user_id' => User::factory(),
|
||||
];
|
||||
}
|
||||
|
||||
public function forAsset()
|
||||
{
|
||||
return $this->state(function (array $attributes) {
|
||||
return [
|
||||
'requestable_id' => Asset::factory(),
|
||||
'requestable_type' => Asset::class,
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
public function forAssetModel()
|
||||
{
|
||||
return $this->state(function (array $attributes) {
|
||||
return [
|
||||
'requestable_id' => AssetModel::factory(),
|
||||
'requestable_type' => AssetModel::class,
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,6 @@ class UserFactory extends Factory
|
||||
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
|
||||
'permissions' => '{}',
|
||||
'phone' => $this->faker->phoneNumber(),
|
||||
'mobile' => $this->faker->phoneNumber(),
|
||||
'state' => $this->faker->stateAbbr(),
|
||||
'username' => $this->faker->unique()->username(),
|
||||
'zip' => $this->faker->postcode(),
|
||||
@@ -351,17 +350,6 @@ class UserFactory extends Factory
|
||||
return $this->appendPermission(['import' => '1']);
|
||||
}
|
||||
|
||||
public function createCustomFields()
|
||||
{
|
||||
return $this->appendPermission(['customfields.create' => '1']);
|
||||
}
|
||||
|
||||
public function viewCustomFields()
|
||||
{
|
||||
return $this->appendPermission(['customfields.view' => '1']);
|
||||
}
|
||||
|
||||
|
||||
public function deleteCustomFields()
|
||||
{
|
||||
return $this->appendPermission(['customfields.delete' => '1']);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
|
||||
class CreateAssetMaintenancesTable extends Migration
|
||||
{
|
||||
@@ -40,9 +40,9 @@
|
||||
protected function getEnumFields()
|
||||
{
|
||||
return [
|
||||
trans('admin/maintenances/general.maintenance'),
|
||||
trans('admin/maintenances/general.repair'),
|
||||
trans('admin/maintenances/general.upgrade'),
|
||||
trans('admin/asset_maintenances/general.maintenance'),
|
||||
trans('admin/asset_maintenances/general.repair'),
|
||||
trans('admin/asset_maintenances/general.upgrade'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Get the migration connection name.
|
||||
*/
|
||||
public function getConnection(): ?string
|
||||
{
|
||||
return config('telescope.storage.database.connection');
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
$schema = Schema::connection($this->getConnection());
|
||||
|
||||
$schema->create('telescope_entries', function (Blueprint $table) {
|
||||
$table->bigIncrements('sequence');
|
||||
$table->uuid('uuid');
|
||||
$table->uuid('batch_id');
|
||||
$table->string('family_hash')->nullable();
|
||||
$table->boolean('should_display_on_index')->default(true);
|
||||
$table->string('type', 20);
|
||||
$table->longText('content');
|
||||
$table->dateTime('created_at')->nullable();
|
||||
|
||||
$table->unique('uuid');
|
||||
$table->index('batch_id');
|
||||
$table->index('family_hash');
|
||||
$table->index('created_at');
|
||||
$table->index(['type', 'should_display_on_index']);
|
||||
});
|
||||
|
||||
$schema->create('telescope_entries_tags', function (Blueprint $table) {
|
||||
$table->uuid('entry_uuid');
|
||||
$table->string('tag');
|
||||
|
||||
$table->primary(['entry_uuid', 'tag']);
|
||||
$table->index('tag');
|
||||
|
||||
$table->foreign('entry_uuid')
|
||||
->references('uuid')
|
||||
->on('telescope_entries')
|
||||
->onDelete('cascade');
|
||||
});
|
||||
|
||||
$schema->create('telescope_monitoring', function (Blueprint $table) {
|
||||
$table->string('tag')->primary();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
$schema = Schema::connection($this->getConnection());
|
||||
|
||||
$schema->dropIfExists('telescope_entries_tags');
|
||||
$schema->dropIfExists('telescope_entries');
|
||||
$schema->dropIfExists('telescope_monitoring');
|
||||
}
|
||||
};
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('asset_maintenances', function (Blueprint $table) {
|
||||
if (!Schema::hasColumn('asset_maintenances', 'image')) {
|
||||
$table->text('image')->after('notes')->nullable()->default(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('asset_maintenances', function (Blueprint $table) {
|
||||
$table->dropColumn('image');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('asset_maintenances', function (Blueprint $table) {
|
||||
$table->renameColumn('title', 'name');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('asset_maintenances', function (Blueprint $table) {
|
||||
$table->renameColumn('name', 'title');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::rename('asset_maintenances', 'maintenances');
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::rename('maintenances', 'asset_maintenances');
|
||||
}
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use App\Models\Actionlog;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Actionlog::where('item_type', 'App\\Models\\AssetMaintenance')->update(['item_type' => 'App\\Models\\Maintenance']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
if (!Schema::hasColumn('users', 'mobile')) {
|
||||
$table->text('mobile')->after('phone')->nullable()->default(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('mobile');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('categories', function (Blueprint $table) {
|
||||
$table->index(['deleted_at']);
|
||||
});
|
||||
Schema::table('accessories', function (Blueprint $table) {
|
||||
$table->index(['deleted_at','category_id']);
|
||||
});
|
||||
Schema::table('consumables', function (Blueprint $table) {
|
||||
$table->index(['deleted_at','category_id']);
|
||||
});
|
||||
Schema::table('components', function (Blueprint $table) {
|
||||
$table->index(['deleted_at','category_id']);
|
||||
});
|
||||
Schema::table('licenses', function (Blueprint $table) {
|
||||
$table->index(['deleted_at','category_id']);
|
||||
});
|
||||
Schema::table('models', function (Blueprint $table) {
|
||||
$table->index(['deleted_at','category_id']);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('categories', function (Blueprint $table) {
|
||||
$table->dropIndex(['deleted_at']);
|
||||
});
|
||||
Schema::table('accessories', function (Blueprint $table) {
|
||||
$table->dropIndex(['deleted_at','category_id']);
|
||||
});
|
||||
Schema::table('consumables', function (Blueprint $table) {
|
||||
$table->dropIndex(['deleted_at','category_id']);
|
||||
});
|
||||
Schema::table('components', function (Blueprint $table) {
|
||||
$table->dropIndex(['deleted_at','category_id']);
|
||||
});
|
||||
Schema::table('licenses', function (Blueprint $table) {
|
||||
$table->dropIndex(['deleted_at','category_id']);
|
||||
});
|
||||
Schema::table('models', function (Blueprint $table) {
|
||||
$table->dropIndex(['deleted_at','category_id']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -53,7 +53,7 @@ class DatabaseSeeder extends Seeder
|
||||
Model::reguard();
|
||||
|
||||
DB::table('imports')->truncate();
|
||||
DB::table('maintenances')->truncate();
|
||||
DB::table('asset_maintenances')->truncate();
|
||||
DB::table('requested_assets')->truncate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ for dir in \
|
||||
'data/private_uploads/consumables' \
|
||||
'data/private_uploads/eula-pdfs' \
|
||||
'data/private_uploads/imports' \
|
||||
'data/private_uploads/models' \
|
||||
'data/private_uploads/assetmodels' \
|
||||
'data/private_uploads/users' \
|
||||
'data/private_uploads/licenses' \
|
||||
'data/private_uploads/signatures' \
|
||||
|
||||
@@ -1072,6 +1072,7 @@ th.css-house-laptop > .th-inner::before,
|
||||
th.css-house-user > .th-inner::before,
|
||||
th.css-license > .th-inner::before,
|
||||
th.css-location > .th-inner::before,
|
||||
th.css-padlock > .th-inner::before,
|
||||
th.css-users > .th-inner::before,
|
||||
th.css-currency > .th-inner::before,
|
||||
th.css-history > .th-inner::before {
|
||||
@@ -1128,8 +1129,7 @@ th.css-component > .th-inner::before {
|
||||
th.css-padlock > .th-inner::before {
|
||||
content: "\f023";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 800;
|
||||
padding-right: 3px;
|
||||
font-weight: 900;
|
||||
}
|
||||
th.css-house-user > .th-inner::before {
|
||||
content: "\e1b0";
|
||||
@@ -1468,25 +1468,6 @@ caption.tableCaption {
|
||||
font-size: 18px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
.sidebar-toggle.btn {
|
||||
border-radius: 3px;
|
||||
box-shadow: none;
|
||||
border-top: 0px solid transparent;
|
||||
border-bottom: 0px solid transparent;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
margin-left: -47px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.popover.help-popover,
|
||||
.popover.help-popover .popover-content,
|
||||
.popover.help-popover .popover-body,
|
||||
.popover.help-popover .popover-title,
|
||||
.popover.help-popover .popover-header {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
|
||||
/*# sourceMappingURL=app.css.map*/
|
||||
File diff suppressed because one or more lines are too long
@@ -693,6 +693,7 @@ th.css-house-laptop > .th-inner::before,
|
||||
th.css-house-user > .th-inner::before,
|
||||
th.css-license > .th-inner::before,
|
||||
th.css-location > .th-inner::before,
|
||||
th.css-padlock > .th-inner::before,
|
||||
th.css-users > .th-inner::before,
|
||||
th.css-currency > .th-inner::before,
|
||||
th.css-history > .th-inner::before {
|
||||
@@ -749,8 +750,7 @@ th.css-component > .th-inner::before {
|
||||
th.css-padlock > .th-inner::before {
|
||||
content: "\f023";
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 800;
|
||||
padding-right: 3px;
|
||||
font-weight: 900;
|
||||
}
|
||||
th.css-house-user > .th-inner::before {
|
||||
content: "\e1b0";
|
||||
@@ -1089,25 +1089,6 @@ caption.tableCaption {
|
||||
font-size: 18px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
.sidebar-toggle.btn {
|
||||
border-radius: 3px;
|
||||
box-shadow: none;
|
||||
border-top: 0px solid transparent;
|
||||
border-bottom: 0px solid transparent;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
margin-left: -47px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.popover.help-popover,
|
||||
.popover.help-popover .popover-content,
|
||||
.popover.help-popover .popover-body,
|
||||
.popover.help-popover .popover-title,
|
||||
.popover.help-popover .popover-header {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
|
||||
/*# sourceMappingURL=overrides.css.map*/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user