] * @see LicensesController::getDatatable() method that generates the JSON response * @since [v1.0] * @return \Illuminate\Contracts\View\View */ public function index() { $this->authorize('view', License::class); return view('licenses/index'); } /** * Returns a form view that allows an admin to create a new licence. * * @author [A. Gianotto] [] * @see AccessoriesController::getDatatable() method that generates the JSON response * @since [v1.0] * @return \Illuminate\Contracts\View\View */ public function create() { $this->authorize('create', License::class); $maintained_list = [ '' => 'Maintained', '1' => 'Yes', '0' => 'No' ]; return view('licenses/edit') //->with('license_options',$license_options) ->with('depreciation_list', Helper::depreciationList()) ->with('maintained_list', $maintained_list) ->with('item', new License); } /** * Validates and stores the license form data submitted from the new * license form. * * @author [A. Gianotto] [] * @see LicensesController::getCreate() method that provides the form view * @since [v1.0] * @param Request $request * @return \Illuminate\Http\RedirectResponse */ public function store(Request $request) { $this->authorize('create', License::class); // create a new model instance $license = new License(); // Save the license data $license->company_id = Company::getIdForCurrentUser($request->input('company_id')); $license->depreciation_id = $request->input('depreciation_id'); $license->expiration_date = $request->input('expiration_date'); $license->license_email = $request->input('license_email'); $license->license_name = $request->input('license_name'); $license->maintained = $request->input('maintained', 0); $license->manufacturer_id = $request->input('manufacturer_id'); $license->name = $request->input('name'); $license->notes = $request->input('notes'); $license->order_number = $request->input('order_number'); $license->purchase_cost = $request->input('purchase_cost'); $license->purchase_date = $request->input('purchase_date'); $license->purchase_order = $request->input('purchase_order'); $license->purchase_order = $request->input('purchase_order'); $license->reassignable = $request->input('reassignable', 0); $license->seats = $request->input('seats'); $license->serial = $request->input('serial'); $license->supplier_id = $request->input('supplier_id'); $license->category_id = $request->input('category_id'); $license->termination_date = $request->input('termination_date'); $license->user_id = Auth::id(); if ($license->save()) { return redirect()->route("licenses.index")->with('success', trans('admin/licenses/message.create.success')); } return redirect()->back()->withInput()->withErrors($license->getErrors()); } /** * Returns a form with existing license data to allow an admin to * update license information. * * @author [A. Gianotto] [] * @since [v1.0] * @param int $licenseId * @return \Illuminate\Contracts\View\View */ public function edit($licenseId = null) { if (is_null($item = License::find($licenseId))) { return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist')); } $this->authorize('update', $item); $maintained_list = [ '' => 'Maintained', '1' => 'Yes', '0' => 'No' ]; return view('licenses/edit', compact('item')) ->with('depreciation_list', Helper::depreciationList()) ->with('maintained_list', $maintained_list); } /** * Validates and stores the license form data submitted from the edit * license form. * * @author [A. Gianotto] [] * @see LicensesController::getEdit() method that provides the form view * @since [v1.0] * @param Request $request * @param int $licenseId * @return \Illuminate\Http\RedirectResponse */ public function update(Request $request, $licenseId = null) { if (is_null($license = License::find($licenseId))) { return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist')); } $this->authorize('update', $license); $license->company_id = Company::getIdForCurrentUser($request->input('company_id')); $license->depreciation_id = $request->input('depreciation_id'); $license->expiration_date = $request->input('expiration_date'); $license->license_email = $request->input('license_email'); $license->license_name = $request->input('license_name'); $license->maintained = $request->input('maintained',0); $license->name = $request->input('name'); $license->notes = $request->input('notes'); $license->order_number = $request->input('order_number'); $license->purchase_cost = $request->input('purchase_cost'); $license->purchase_date = $request->input('purchase_date'); $license->purchase_order = $request->input('purchase_order'); $license->reassignable = $request->input('reassignable', 0); $license->serial = $request->input('serial'); $license->termination_date = $request->input('termination_date'); $license->seats = e($request->input('seats')); $license->manufacturer_id = $request->input('manufacturer_id'); $license->supplier_id = $request->input('supplier_id'); $license->category_id = $request->input('category_id'); if ($license->save()) { return redirect()->route('licenses.show', ['license' => $licenseId])->with('success', trans('admin/licenses/message.update.success')); } // If we can't adjust the number of seats, the error is flashed to the session by the event handler in License.php return redirect()->back()->withInput()->withErrors($license->getErrors()); } /** * Checks to see whether the selected license can be deleted, and * if it can, marks it as deleted. * * @author [A. Gianotto] [] * @since [v1.0] * @param int $licenseId * @return \Illuminate\Http\RedirectResponse */ public function destroy($licenseId) { // Check if the license exists if (is_null($license = License::find($licenseId))) { // Redirect to the license management page return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found')); } $this->authorize('delete', $license); if ($license->assigned_seats_count == 0) { // Delete the license and the associated license seats DB::table('license_seats') ->where('id', $license->id) ->update(array('assigned_to' => null,'asset_id' => null)); $licenseSeats = $license->licenseseats(); $licenseSeats->delete(); $license->delete(); // Redirect to the licenses management page return redirect()->route('licenses.index')->with('success', trans('admin/licenses/message.delete.success')); // Redirect to the license management page } // There are still licenses in use. return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.assoc_users')); } /** * Provides the form view for checking out a license to a user. * Here we pass the license seat ID instead of the license ID, * because licenses themselves are never checked out to anyone, * only the seats associated with them. * * @author [A. Gianotto] [] * @since [v1.0] * @param int $seatId * @return \Illuminate\Contracts\View\View */ public function getCheckout($licenceId) { // Check that the license is valid if ($license = License::where('id',$licenceId)->first()) { // If the license is valid, check that there is an available seat if ($license->getAvailSeatsCountAttribute() < 1) { return redirect()->route('licenses.index')->with('error', 'There are no available seats for this license'); } } $this->authorize('checkout', $license); return view('licenses/checkout', compact('license')); } /** * Validates and stores the license checkout action. * * @todo Switch to using a FormRequest for validation here. * @author [A. Gianotto] [] * @since [v1.0] * @param Request $request * @param int $licenseId * @param int $seatId * @return \Illuminate\Http\RedirectResponse */ public function postCheckout(Request $request, $licenseId, $seatId = null) { // Check that the license is valid if ($license = License::where('id', $licenseId)->first()) { // If the license is valid, check that there is an available seat if ($license->getAvailSeatsCountAttribute() < 1) { return redirect()->route('licenses.index')->with('error', 'There are no available seats for this license'); } if (!$seatId) { // Get the next available seat for this license $next = $license->freeSeat(); if (!$next) { return redirect()->route('licenses.index')->with('error', 'There are no available seats for this license'); } if (!$licenseSeat = LicenseSeat::where('id', '=', $next->id)->first()) { return redirect()->route('licenses.index')->with('error', 'There are no available seats for this license'); } } else { $licenseSeat = LicenseSeat::where('id', '=', $seatId)->first(); if (!$licenseSeat) { return redirect()->route('licenses.index')->with('error', 'License seat is not available for checkout'); } } $this->authorize('checkout', $license); // Declare the rules for the form validation $rules = [ 'note' => 'string|nullable', 'asset_id' => 'required_without:assigned_to', ]; // Create a new validator instance from our validation rules $validator = Validator::make(Input::all(), $rules); // If validation fails, we'll exit the operation now. if ($validator->fails()) { // Ooops.. something went wrong return redirect()->back()->withInput()->withErrors($validator); } $target = null; // This item is checked out to a an asset if (request('checkout_to_type')=='asset') { if (is_null($target = Asset::find(request('asset_id')))) { return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.asset_does_not_exist')); } $licenseSeat->asset_id = $request->input('asset_id'); // Override asset's assigned user if available if ($target->checkedOutToUser()) { $licenseSeat->assigned_to = $target->assigned_to; } } else { // Fetch the target and set the license user if (is_null($target = User::find(request('assigned_to')))) { return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.user_does_not_exist')); } $licenseSeat->assigned_to = request('assigned_to'); } $licenseSeat->user_id = Auth::user()->id; if ($licenseSeat->save()) { $licenseSeat->logCheckout($request->input('note'), $target); return redirect()->route("licenses.index")->with('success', trans('admin/licenses/message.checkout.success')); } } return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found')); return redirect()->route("licenses.index")->with('error', trans('admin/licenses/message.checkout.error')); } /** * Makes the form view to check a license seat back into inventory. * * @author [A. Gianotto] [] * @since [v1.0] * @param int $seatId * @param string $backTo * @return \Illuminate\Contracts\View\View */ public function getCheckin($seatId = null, $backTo = null) { // Check if the asset exists if (is_null($licenseSeat = LicenseSeat::find($seatId))) { // Redirect to the asset management page with error return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found')); } if (is_null($license = License::find($licenseSeat->license_id))) { // Redirect to the asset management page with error return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found')); } $this->authorize('checkout', $license); return view('licenses/checkin', compact('licenseSeat'))->with('backto', $backTo); } /** * Validates and stores the license checkin action. * * @author [A. Gianotto] [] * @see LicensesController::getCheckin() method that provides the form view * @since [v1.0] * @param int $seatId * @param string $backTo * @return \Illuminate\Http\RedirectResponse */ public function postCheckin($seatId = null, $backTo = null) { // Check if the asset exists if (is_null($licenseSeat = LicenseSeat::find($seatId))) { // Redirect to the asset management page with error return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found')); } $license = License::find($licenseSeat->license_id); $this->authorize('checkout', $license); if (!$license->reassignable) { // Not allowed to checkin Session::flash('error', 'License not reassignable.'); return redirect()->back()->withInput(); } $return_to = User::find($licenseSeat->assigned_to); if (!$return_to) { $return_to = Asset::find($licenseSeat->asset_id); } // Update the asset data $licenseSeat->assigned_to = null; $licenseSeat->asset_id = null; // Was the asset updated? if ($licenseSeat->save()) { $licenseSeat->logCheckin($license, e(request('note'))); if ($backTo=='user') { return redirect()->route("users.show", $return_to->id)->with('success', trans('admin/licenses/message.checkin.success')); } return redirect()->route("licenses.show", $licenseSeat->license_id)->with('success', trans('admin/licenses/message.checkin.success')); } // Redirect to the license page with error return redirect()->route("licenses.index")->with('error', trans('admin/licenses/message.checkin.error')); } /** * Makes the license detail page. * * @author [A. Gianotto] [] * @since [v1.0] * @param int $licenseId * @return \Illuminate\Contracts\View\View */ public function show($licenseId = null) { $license = License::with('assignedusers', 'licenseSeats.user', 'licenseSeats.asset')->find($licenseId); if ($license) { $this->authorize('view', $license); return view('licenses/view', compact('license')); } return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist', compact('id'))); } public function getClone($licenseId = null) { if (is_null($license_to_clone = License::find($licenseId))) { return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist')); } $this->authorize('create', License::class); $maintained_list = [ '' => 'Maintained', '1' => 'Yes', '0' => 'No' ]; //clone the orig $license = clone $license_to_clone; $license->id = null; $license->serial = null; // Show the page return view('licenses/edit') ->with('depreciation_list', Helper::depreciationList()) ->with('item', $license) ->with('maintained_list', $maintained_list); } /** * Validates and stores files associated with a license. * * @todo Switch to using the AssetFileRequest form request validator. * @author [A. Gianotto] [] * @since [v1.0] * @param int $licenseId * @return \Illuminate\Http\RedirectResponse */ public function postUpload(AssetFileRequest $request, $licenseId = null) { $license = License::find($licenseId); // the license is valid $destinationPath = config('app.private_uploads').'/licenses'; if (isset($license->id)) { $this->authorize('update', $license); if (Input::hasFile('file')) { foreach (Input::file('file') as $file) { $extension = $file->getClientOriginalExtension(); $filename = 'license-'.$license->id.'-'.str_random(8).'-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$extension; $upload_success = $file->move($destinationPath, $filename); //Log the upload to the log $license->logUpload($filename, e($request->input('notes'))); } // This being called from a modal seems to confuse redirect()->back() // It thinks we should go to the dashboard. As this is only used // from the modal at present, hardcode the redirect. Longterm // maybe we evaluate something else. if ($upload_success) { 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.error')); } return redirect()->route('licenses.show', $license->id)->with('error', trans('admin/licenses/message.upload.nofiles')); } // Prepare the error message $error = trans('admin/licenses/message.does_not_exist', compact('id')); return redirect()->route('licenses.index')->with('error', $error); } /** * Deletes the selected license file. * * @author [A. Gianotto] [] * @since [v1.0] * @param int $licenseId * @param int $fileId * @return \Illuminate\Http\RedirectResponse */ public function getDeleteFile($licenseId = null, $fileId = null) { $license = License::find($licenseId); $destinationPath = config('app.private_uploads').'/licenses'; // the license is valid if (isset($license->id)) { $this->authorize('edit', $license); $log = Actionlog::find($fileId); $full_filename = $destinationPath.'/'.$log->filename; if (file_exists($full_filename)) { unlink($destinationPath.'/'.$log->filename); } $log->delete(); return redirect()->back()->with('success', trans('admin/licenses/message.deletefile.success')); } // Prepare the error message $error = trans('admin/licenses/message.does_not_exist', compact('id')); // Redirect to the licence management page return redirect()->route('licenses.index')->with('error', $error); } /** * Allows the selected file to be viewed. * * @author [A. Gianotto] [] * @since [v1.4] * @param int $licenseId * @param int $fileId * @return \Symfony\Component\HttpFoundation\BinaryFileResponse */ public function displayFile($licenseId = null, $fileId = null, $download = true) { $license = License::find($licenseId); // the license is valid if (isset($license->id)) { $this->authorize('view', $license); $log = Actionlog::find($fileId); $file = $log->get_src('licenses'); if ($file =='') { return response('File not found on server', 404) ->header('Content-Type', 'text/plain'); } $mimetype = \File::mimeType($file); if (!file_exists($file)) { return response('File '.$file.' not found on server', 404) ->header('Content-Type', 'text/plain'); } if ($download != 'true') { if ($contents = file_get_contents($file)) { return Response::make($contents)->header('Content-Type', $mimetype); } return JsonResponse::create(["error" => "Failed validation: "], 500); } return Response::download($file); } return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist', compact('id'))); } /** * Generates the next free seat ID for checkout. * * @todo This is a dumb way to solve this problem. * Author should refactor. And go hide in a hole and * think about what she's done. And perhaps find a new * line of work. And get in the sea. * * @author [A. Gianotto] [] * @since [v1.0] * @param int $licenseId * @return \Illuminate\Http\RedirectResponse */ public function getFreeLicense($licenseId) { $this->authorize('checkout', License::class); if (is_null($license = License::find($licenseId))) { return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found')); } $seatId = $license->freeSeat($licenseId); return redirect()->route('licenses.checkout', $seatId); } }