From 49ecc083984b31eac5e6129bc47c59b485b64b64 Mon Sep 17 00:00:00 2001 From: Minaev Dmitriy Date: Thu, 23 Aug 2018 20:29:03 +0300 Subject: [PATCH 01/14] Add half-year convention in depreciation for Models/Depreciable.php --- app/Models/Depreciable.php | 64 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/app/Models/Depreciable.php b/app/Models/Depreciable.php index ee12a6506..b26215bc8 100644 --- a/app/Models/Depreciable.php +++ b/app/Models/Depreciable.php @@ -60,6 +60,64 @@ class Depreciable extends SnipeModel return $current_value; } + /** + * @param onlyHalfFirstYear Boolean always applied only second half of the first year + * @return float|int + */ + public function getHalfYearDepreciatedValue($onlyHalfFirstYear = false) + { + // @link http://www.php.net/manual/en/class.dateinterval.php + $current_date = $this->getDateTime(); + $purchase_date = date_create($this->purchase_date); + $currentYear = $this->get_fiscal_year( $current_date ); + $purchaseYear = $this->get_fiscal_year( $purchase_date ); + $yearsPast = $currentYear - $purchaseYear; + $deprecationYears = ceil($this->get_depreciation()->months / 12); + if( $onlyHalfFirstYear ) { + $yearsPast -= 0.5; + } + else { + if( !$this->is_first_half_of_year($purchase_date) ) { + $yearsPast -= 0.5; + } + } + if( !$this->is_first_half_of_year($current_date) ) { + $yearsPast += 0.5; + } + + if($yearsPast >= $deprecationYears) { + $yearsPast = $deprecationYears; + } + else if($yearsPast < 0) { + $yearsPast = 0; + } + return $yearsPast / $deprecationYears * $this->purchase_cost; + } + + /** + * @param \DateTime $date + * @return int + */ + protected function get_fiscal_year($date) { + $year = intval($date->format('Y')); + // also, maybe it'll have to set fiscal year date + if($date->format('nj') === '1231') { + return $year; + } + else { + return $year - 1; + } + } + + /** + * @param \DateTime $date + * @return bool + */ + protected function is_first_half_of_year($date) { + $date0m0d = intval($date->format('md')); + return ($date0m0d < 601) || ($date0m0d >= 1231); + } + public function time_until_depreciated() { // @link http://www.php.net/manual/en/class.datetime.php @@ -81,4 +139,10 @@ class Depreciable extends SnipeModel date_add($date, date_interval_create_from_date_string($this->get_depreciation()->months . ' months')); return $date; //date_format($date, 'Y-m-d'); //don't bake-in format, for internationalization } + + // it's necessary for unit tests + protected function getDateTime($time = null) + { + return new \DateTime($time); + } } From 8d3b201a492231a58079bd93b9b7bda278e048b0 Mon Sep 17 00:00:00 2001 From: Minaev Dmitriy Date: Thu, 23 Aug 2018 20:49:20 +0300 Subject: [PATCH 02/14] Add a setting for the depreciation method --- app/Http/Controllers/SettingsController.php | 2 ++ ...42_add_depreciation_option_to_settings.php | 32 +++++++++++++++++++ resources/views/settings/general.blade.php | 14 ++++++++ 3 files changed, 48 insertions(+) create mode 100644 database/migrations/2018_08_20_204842_add_depreciation_option_to_settings.php diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php index 798d86698..90391a23f 100755 --- a/app/Http/Controllers/SettingsController.php +++ b/app/Http/Controllers/SettingsController.php @@ -351,6 +351,8 @@ class SettingsController extends Controller $setting->thumbnail_max_h = $request->input('thumbnail_max_h'); $setting->privacy_policy_link = $request->input('privacy_policy_link'); + $setting->depreciation_method = $request->input('depreciation_method'); + if (Input::get('per_page')!='') { $setting->per_page = $request->input('per_page'); } else { diff --git a/database/migrations/2018_08_20_204842_add_depreciation_option_to_settings.php b/database/migrations/2018_08_20_204842_add_depreciation_option_to_settings.php new file mode 100644 index 000000000..7678c45d5 --- /dev/null +++ b/database/migrations/2018_08_20_204842_add_depreciation_option_to_settings.php @@ -0,0 +1,32 @@ +char('depreciation_method', 10)->nullable()->default('default'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('settings', function (Blueprint $table) { + $table->dropColumn('depreciation_method'); + }); + } +} diff --git a/resources/views/settings/general.blade.php b/resources/views/settings/general.blade.php index 41fe09ea5..af93a7c8e 100644 --- a/resources/views/settings/general.blade.php +++ b/resources/views/settings/general.blade.php @@ -281,6 +281,20 @@ {{ Form::checkbox('show_in_model_list[]', 'model_number', Input::old('show_in_model_list', $snipeSettings->modellistCheckedValue('model_number')),array('class' => 'minimal')) }} {{ trans('general.model_no') }}
+ + +
+
+ {{ Form::label('depreciation_method', trans('Depreciation method')) }} +
+
+ {{ Form::select('depreciation_method', array( + 'default' => 'Linear (default)', + 'half_1' => 'Half-year convention, always applied', + 'half_2' => 'Half-year convention, applied with condition', + ), Input::old('username_format', $setting->depreciation_method)) }} +
+
From 7b70afa2a14dd10ff9041a09e634f91ca7c7e650 Mon Sep 17 00:00:00 2001 From: Minaev Dmitriy Date: Fri, 24 Aug 2018 20:30:22 +0300 Subject: [PATCH 03/14] Integrate half-year convention inside working output --- app/Models/Depreciable.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/Models/Depreciable.php b/app/Models/Depreciable.php index b26215bc8..9a4fe68b5 100644 --- a/app/Models/Depreciable.php +++ b/app/Models/Depreciable.php @@ -41,6 +41,30 @@ class Depreciable extends SnipeModel */ public function getDepreciatedValue() + { + $depreciation = 0; + $setting = Setting::first(); + switch($setting->depreciation_method) { + case 'defalut': + $depreciation = $this->getLinearDepreciatedValue(); + break; + + case 'half_1': + $depreciation = $this->getHalfYearDepreciatedValue(true); + break; + + case 'half_2': + $depreciation = $this->getHalfYearDepreciatedValue(false); + break; + } + return $depreciation; + } + + /** + * @return float|int + */ + + public function getLinearDepreciatedValue() { if (!$this->get_depreciation()) { // will never happen return $this->purchase_cost; From daba90b346fd01aaff5d1751e2a902ddfd6fa257 Mon Sep 17 00:00:00 2001 From: Minaev Dmitriy Date: Sat, 25 Aug 2018 19:17:48 +0300 Subject: [PATCH 04/14] fix: add more checks at Depreciable.php --- app/Models/Depreciable.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/app/Models/Depreciable.php b/app/Models/Depreciable.php index 9a4fe68b5..43ea0af60 100644 --- a/app/Models/Depreciable.php +++ b/app/Models/Depreciable.php @@ -42,6 +42,13 @@ class Depreciable extends SnipeModel public function getDepreciatedValue() { + if (!$this->get_depreciation()) { // will never happen + return $this->purchase_cost; + } + + if ($this->get_depreciation()->months <= 0) { + return $this->purchase_cost; + } $depreciation = 0; $setting = Setting::first(); switch($setting->depreciation_method) { @@ -66,14 +73,6 @@ class Depreciable extends SnipeModel public function getLinearDepreciatedValue() { - if (!$this->get_depreciation()) { // will never happen - return $this->purchase_cost; - } - - if ($this->get_depreciation()->months <= 0) { - return $this->purchase_cost; - } - // fraction of value left $months_remaining = $this->time_until_depreciated()->m + 12*$this->time_until_depreciated()->y; //UGlY $current_value = round(($months_remaining/ $this->get_depreciation()->months) * $this->purchase_cost, 2); From 40dd34b5bfb1f99d19783b32ccac9b0efd23368a Mon Sep 17 00:00:00 2001 From: Minaev Dmitriy Date: Sat, 25 Aug 2018 20:18:31 +0300 Subject: [PATCH 05/14] depreciation value rounding --- app/Models/Depreciable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/Depreciable.php b/app/Models/Depreciable.php index 43ea0af60..bcdd59904 100644 --- a/app/Models/Depreciable.php +++ b/app/Models/Depreciable.php @@ -114,7 +114,7 @@ class Depreciable extends SnipeModel else if($yearsPast < 0) { $yearsPast = 0; } - return $yearsPast / $deprecationYears * $this->purchase_cost; + return round($yearsPast / $deprecationYears * $this->purchase_cost, 2); } /** From a77b8c202316780fcec0614fd60dea293dca5630 Mon Sep 17 00:00:00 2001 From: Minaev Dmitriy Date: Sun, 26 Aug 2018 18:47:35 +0300 Subject: [PATCH 06/14] Codestyle fix --- app/Models/Depreciable.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/app/Models/Depreciable.php b/app/Models/Depreciable.php index bcdd59904..1ed80fdcb 100644 --- a/app/Models/Depreciable.php +++ b/app/Models/Depreciable.php @@ -52,10 +52,6 @@ class Depreciable extends SnipeModel $depreciation = 0; $setting = Setting::first(); switch($setting->depreciation_method) { - case 'defalut': - $depreciation = $this->getLinearDepreciatedValue(); - break; - case 'half_1': $depreciation = $this->getHalfYearDepreciatedValue(true); break; @@ -63,6 +59,9 @@ class Depreciable extends SnipeModel case 'half_2': $depreciation = $this->getHalfYearDepreciatedValue(false); break; + + default: + $depreciation = $this->getLinearDepreciatedValue(); } return $depreciation; } @@ -99,10 +98,8 @@ class Depreciable extends SnipeModel if( $onlyHalfFirstYear ) { $yearsPast -= 0.5; } - else { - if( !$this->is_first_half_of_year($purchase_date) ) { - $yearsPast -= 0.5; - } + else if( !$this->is_first_half_of_year($purchase_date) ) { + $yearsPast -= 0.5; } if( !$this->is_first_half_of_year($current_date) ) { $yearsPast += 0.5; From 0e66c3cb560456b228d20be5198bedf67e0ba31f Mon Sep 17 00:00:00 2001 From: Minaev Dmitriy Date: Fri, 19 Oct 2018 17:30:25 +0300 Subject: [PATCH 07/14] Predefined kits test --- .../Api/PredefinedKitsController.php | 300 ++++++++++++++++++ .../Kits/PredefinedKitsController.php | 244 ++++++++++++++ app/Providers/RouteServiceProvider.php | 1 + ...8_10_18_191228_add_kits_licenses_table.php | 38 +++ .../2018_10_19_153910_add_kits_table.php | 37 +++ ...018_10_19_154013_add_kits_models_table.php | 38 +++ resources/views/kits/edit.blade.php | 79 +++++ resources/views/kits/index.blade.php | 49 +++ .../views/partials/bootstrap-table.blade.php | 64 +++- .../forms/edit/model-select.blade.php | 11 +- routes/api.php | 76 +++++ routes/web/kits.php | 70 ++++ 12 files changed, 1004 insertions(+), 3 deletions(-) create mode 100644 app/Http/Controllers/Api/PredefinedKitsController.php create mode 100644 app/Http/Controllers/Kits/PredefinedKitsController.php create mode 100644 database/migrations/2018_10_18_191228_add_kits_licenses_table.php create mode 100644 database/migrations/2018_10_19_153910_add_kits_table.php create mode 100644 database/migrations/2018_10_19_154013_add_kits_models_table.php create mode 100644 resources/views/kits/edit.blade.php create mode 100644 resources/views/kits/index.blade.php create mode 100644 routes/web/kits.php diff --git a/app/Http/Controllers/Api/PredefinedKitsController.php b/app/Http/Controllers/Api/PredefinedKitsController.php new file mode 100644 index 000000000..72b99aa97 --- /dev/null +++ b/app/Http/Controllers/Api/PredefinedKitsController.php @@ -0,0 +1,300 @@ +] + * @since [v4.0] + * @return \Illuminate\Http\Response + */ + public function index(Request $request) + { + $this->authorize('view', PredefinedKit::class); + $allowed_columns = ['id', 'name']; + + $kits = PredefinedKit::query(); + + if ($request->filled('search')) { + $kits = $kits->TextSearch($request->input('search')); + } + + $offset = $request->input('offset', 0); + $limit = $request->input('limit', 50); + $order = $request->input('order') === 'asc' ? 'asc' : 'desc'; + $sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'assets_count'; + $kits->orderBy($sort, $order); + + $total = $kits->count(); + $kits = $kits->skip($offset)->take($limit)->get(); + return (new PredefinedKitsTransformer)->transformPrdefinedKits($kits, $total); + + } + + + /** + * Store a newly created resource in storage. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\Response + */ + public function store(Request $request) + { + $this->authorize('create', PredefinedKit::class); + $kit = new PredefinedKit; + $kit->fill($request->all()); + + if ($kit->save()) { + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Created was successfull')); // TODO: trans + } + return response()->json(Helper::formatStandardApiResponse('error', null, $kit->getErrors())); + + } + + /** + * Display the specified resource. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + $this->authorize('view', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($id); + return (new PredefinedKitsTransformer)->transformPrdefinedKit($kit); + } + + + /** + * Update the specified resource in storage. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(Request $request, $id) + { + $this->authorize('update', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($id); + $kit->fill($request->all()); + + if ($kit->save()) { + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Update was successfull')); // TODO: trans + } + + return response()->json(Helper::formatStandardApiResponse('error', null, $kit->getErrors())); + } + + /** + * Remove the specified resource from storage. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + $this->authorize('delete', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($id); + + $kit->delete(); + return response()->json(Helper::formatStandardApiResponse('success', null, 'Delete was successfull')); // TODO: trans + + } + + + /** + * Gets a paginated collection for the select2 menus + * + * @author [A. Gianotto] [] + * @since [v4.0.16] + * @see \App\Http\Transformers\SelectlistTransformer + * + */ + public function selectlist(Request $request) + { + + $kits = PredefinedKit::select([ + 'id', + 'name' + ]); + + if ($request->filled('search')) { + $kits = $kits->where('name', 'LIKE', '%'.$request->get('search').'%'); + } + + $kits = $kits->orderBy('name', 'ASC')->paginate(50); + + return (new SelectlistTransformer)->transformSelectlist($kits); + + } + + /** + * Display the specified resource. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param int $id + * @return \Illuminate\Http\Response + */ + public function indexLicenses($kit_id) { + $this->authorize('view', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($kit_id); + $licenses = $kit->licenses; + return (new PredefinedKitsTransformer)->transformElements($licenses, $licenses->count()); + } + + + /** + * Display the specified resource. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param int $id + * @return \Illuminate\Http\Response + */ + public function storeLicense(Request $request, $kit_id) + { + $this->authorize('update', PredefinedKit::class); + + $kit = PredefinedKit::findOrFail($kit_id); + $quantity = $request->input('quantity', 1); + if( $quantity < 1) { + $quantity = 1; + } + $kit->licenses()->attach( $request->get('license'), ['quantity' => $quantity]); + + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'License added successfull')); // TODO: trans + } + + /** + * Update the specified resource in storage. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function updateLicense(Request $request, $kit_id, $license_id) + { + $this->authorize('update', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($id); + $quantity = $request->input('quantity', 1); + if( $quantity < 1) { + $quantity = 1; + } + $kit->licenses()->sync([$license_id => ['quantity' => $quantity]]); + + return response()->json(Helper::formatStandardApiResponse('success', null, 'License updated')); // TODO: trans + } + + /** + * Remove the specified resource from storage. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param int $kit_id + * @return \Illuminate\Http\Response + */ + public function destroyLicense($kit_id, $license_id) + { + $this->authorize('update', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($id); + + $kit->licenses()->detach($license_id); + return response()->json(Helper::formatStandardApiResponse('success', null, 'Delete was successfull')); // TODO: trans + } + + /** + * Display the specified resource. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param int $id + * @return \Illuminate\Http\Response + */ + public function indexModels($kit_id) { + $this->authorize('view', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($kit_id); + $models = $kit->models; + return (new PredefinedKitsTransformer)->transformElements($models, $models->count()); + } + + /** + * Display the specified resource. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param int $id + * @return \Illuminate\Http\Response + */ + public function storeModel(Request $request, $kit_id) + { + $this->authorize('update', PredefinedKit::class); + + $kit = PredefinedKit::findOrFail($kit_id); + $quantity = $request->input('quantity', 1); + if( $quantity < 1) { + $quantity = 1; + } + $kit->models()->attach( $request->get('model'), ['quantity' => $quantity]); + + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'License added successfull')); // TODO: trans + } + + /** + * Update the specified resource in storage. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function updateModel(Request $request, $kit_id, $model_id) + { + $this->authorize('update', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($id); + $quantity = $request->input('quantity', 1); + if( $quantity < 1) { + $quantity = 1; + } + $kit->models()->sync([$model_id => ['quantity' => $quantity]]); + + return response()->json(Helper::formatStandardApiResponse('success', null, 'License updated')); // TODO: trans + } + + /** + * Remove the specified resource from storage. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param int $kit_id + * @return \Illuminate\Http\Response + */ + public function destroyModel($kit_id, $model_id) + { + $this->authorize('update', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($id); + + $kit->models()->detach($model_id); + return response()->json(Helper::formatStandardApiResponse('success', null, 'Delete was successfull')); // TODO: trans + } +} diff --git a/app/Http/Controllers/Kits/PredefinedKitsController.php b/app/Http/Controllers/Kits/PredefinedKitsController.php new file mode 100644 index 000000000..36ebb27d5 --- /dev/null +++ b/app/Http/Controllers/Kits/PredefinedKitsController.php @@ -0,0 +1,244 @@ +authorize('index', PredefinedKit::class); + return view('kits/index'); + } + + /** + * Returns a form view to create a new asset maintenance. + * + * @see AssetMaintenancesController::postCreate() method that stores the data + * @author Vincent Sposato + * @version v1.0 + * @since [v1.8] + * @return mixed + */ + public function create() + { + //$this->authorize('create', PredefinedKit::class); + + return view('kits/edit')->with('item', new PredefinedKit); + } + + /** + * Validate and process the new Predefined Kit data. + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @return Redirect + */ + public function store(ImageUploadRequest $request) + { + //$this->authorize('create', AssetModel::class); + // Create a new Predefined Kit + $kit = new PredefinedKit; + + // Save the model data + $kit->name = $request->input('name'); + + if(!$kit->save()) { + return redirect()->back()->withInput()->withErrors($kit->getErrors()); + } + + $model_ids = $request->input('models'); + if (!is_array($model_ids)) { + $model_ids = []; + } + $model_ids = array_filter($model_ids); + + $license_ids = $request->get('selected_licenses'); + if (!is_array($license_ids)) { + $license_ids = []; + } + $license_ids = array_filter($license_ids); + + $success = DB::transaction(function() use($kit, $model_ids, $license_ids) { + $ret = $kit->save(); + if($ret) { + $kit->models()->attach($model_ids); // MYTODO: проверить, что работает перед сохранением + $kit->licenses()->attach($license_ids); + } + return $ret; + }); + + if(!$success) { + return redirect()->back()->withInput()->withErrors($kit->getErrors()); + } + return redirect()->route("models.index")->with('success', 'Kit was successfully created.'); // TODO: trans() + } + + /** + * Returns a view containing the Predefined Kit edit form. + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $kitId + * @return View + */ + public function edit($kitId = null) + { + $this->authorize('update', PredefinedKit::class); + if ($kit = PredefinedKit::find($kitId)) { + return view('kits/edit') + ->with('item', $kit) + ->with('models', $kit->models) + ->with('licenses', $kit->licenses); + } + return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans + } + + + /** + * Validates and processes form data from the edit + * Predefined Kit form based on the kit ID passed. + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $kitId + * @return Redirect + */ + public function update(ImageUploadRequest $request, $kitId = null) + { + $this->authorize('update', PredefinedKit::class); + // Check if the kit exists + if (is_null($kit = PredefinedKit::find($kitId))) { + // Redirect to the kits management page + return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + } + + $kit->name = $request->input('name'); + + // update models + $new_model_ids = $request->input('models'); + $old_model_ids = $kit->models()->pluck('id'); // METODO: проверить + // для получения ид надо что-то такое https://stackoverflow.com/questions/34308169/eloquent-orm-laravel-5-get-array-of-ids + // project built on Laravel 5.4 + list($add_model_ids, $remove_model_ids) = $this->getAddingDeletingElements($new_model_ids, $old_model_ids); // METODO: тут ошибка, надо именно ид-шки получать, а не сами модели + + $new_licence_ids = $request->input('licences'); + $old_licence_ids = $kit->licences()->pluck('id'); // METODO: проверить + list($add_licence_ids, $remove_licence_ids) = $this->getAddingDeletingElements($new_licence_ids, $old_licence_ids); + + $success = DB::transaction(function() use($kit, $add_models, $remove_models, $add_licences, $remove_licences) { + $kit->models()->detach($remove_models); + $kit->models()->attach($add_models); + $kit->licenses()->detach($remove_licenses); + $kit->licenses()->attach($add_licenses); + return $kit->save(); + }); + + if ($success) { + return redirect()->route("kits.index")->with('success', 'Kit was successfully updated'); // TODO: trans + } + return redirect()->back()->withInput()->withErrors($kit->getErrors()); + } + + /** + * Validate and delete the given Predefined Kit. + * Also delete all contained helping items + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $kitId + * @return Redirect + */ + public function destroy($kitId) + { + $this->authorize('delete', PredefinedKit::class); + // Check if the kit exists + if (is_null($kit = PredefinedKit::find($kitId))) { + return redirect()->route('kits.index')->with('error', 'Kit not found'); // TODO: trans + } + + // Delete childs + $kit->models()->delete(); + $kit->licenses()->delete(); + // Delete the kit + $kit->delete(); + + // Redirect to the kit management page + return redirect()->route('kits.index')->with('success', 'Kit was successfully deleted'); // TODO: trans + } + + /** + * Get the model information to present to the model view page + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $modelId + * @return View + */ + public function show($modelId = null) + { + $this->authorize('view', AssetModel::class); + $model = AssetModel::withTrashed()->find($modelId); + + if (isset($model->id)) { + return view('models/view', compact('model')); + } + // Prepare the error message + $error = trans('admin/models/message.does_not_exist', compact('id')); + + // Redirect to the user management page + return redirect()->route('models.index')->with('error', $error); + } + + /** + * Returns true if a fieldset is set, 'add default values' is ticked and if + * any default values were entered into the form. + * + * @param array $input + * @return boolean + */ + private function shouldAddDefaultValues(array $input) + { + return !empty($input['add_default_values']) + && !empty($input['default_values']) + && !empty($input['custom_fieldset']); + } + + /** + * Adds default values to a model (as long as they are truthy) + * + * @param AssetModel $model + * @param array $defaultValues + * @return void + */ + private function assignCustomFieldsDefaultValues(AssetModel $model, array $defaultValues) + { + foreach ($defaultValues as $customFieldId => $defaultValue) { + if ($defaultValue) { + $model->defaultValues()->attach($customFieldId, ['default_value' => $defaultValue]); + } + } + } + + /** + * Removes all default values + * + * @return void + */ + private function removeCustomFieldsDefaultValues(AssetModel $model) + { + $model->defaultValues()->detach(); + } +} diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 94f5ca0bf..02bf3dc07 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -63,6 +63,7 @@ class RouteServiceProvider extends ServiceProvider require base_path('routes/web/fields.php'); require base_path('routes/web/components.php'); require base_path('routes/web/users.php'); + require base_path('routes/web/kits.php'); require base_path('routes/web.php'); }); } diff --git a/database/migrations/2018_10_18_191228_add_kits_licenses_table.php b/database/migrations/2018_10_18_191228_add_kits_licenses_table.php new file mode 100644 index 000000000..b600cad3a --- /dev/null +++ b/database/migrations/2018_10_18_191228_add_kits_licenses_table.php @@ -0,0 +1,38 @@ +increments('id'); + $table->integer('kit_id')->nullable()->default(NULL); + $table->integer('license_id')->nullable()->default(NULL); + $table->integer('quantity')->default(1); + $table->timestamps(); + }); + + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + Schema::drop('kits_licenses'); + } + +} diff --git a/database/migrations/2018_10_19_153910_add_kits_table.php b/database/migrations/2018_10_19_153910_add_kits_table.php new file mode 100644 index 000000000..949c15014 --- /dev/null +++ b/database/migrations/2018_10_19_153910_add_kits_table.php @@ -0,0 +1,37 @@ +increments('id'); + $table->string('name')->nullable()->default(NULL); + $table->timestamps(); + $table->engine = 'InnoDB'; + }); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + Schema::drop('kits'); + + } + +} diff --git a/database/migrations/2018_10_19_154013_add_kits_models_table.php b/database/migrations/2018_10_19_154013_add_kits_models_table.php new file mode 100644 index 000000000..6f80df2da --- /dev/null +++ b/database/migrations/2018_10_19_154013_add_kits_models_table.php @@ -0,0 +1,38 @@ +increments('id'); + $table->integer('kit_id')->nullable()->default(NULL); + $table->integer('model_id')->nullable()->default(NULL); + $table->integer('quantity')->default(1); + $table->timestamps(); + }); + + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + Schema::drop('kits_models'); + } + +} diff --git a/resources/views/kits/edit.blade.php b/resources/views/kits/edit.blade.php new file mode 100644 index 000000000..d16d63e11 --- /dev/null +++ b/resources/views/kits/edit.blade.php @@ -0,0 +1,79 @@ +@extends('layouts/edit-form', [ + 'createText' => 'Create kit', + 'updateText' => 'Update kit', + 'formAction' => ($item) ? route('kits.update', ['kit' => $item->id]) : route('kits.store'), +]) + +{{-- Page content --}} +@section('inputFields') +@include ('partials.forms.edit.name') +@stop + +@section('content') +@parent +
+
+
+
+

Models

+
+
+
+ +
+
+
+
+
+
+
+
+
+
+

Licenses

+
+
+
+ + +
+
+
+
+
+
+@stop \ No newline at end of file diff --git a/resources/views/kits/index.blade.php b/resources/views/kits/index.blade.php new file mode 100644 index 000000000..c5e492f7b --- /dev/null +++ b/resources/views/kits/index.blade.php @@ -0,0 +1,49 @@ +@extends('layouts/default') + +{{-- Web site Title --}} +@section('title') +Kits +@parent +@stop + +@section('header_right') +{{ trans('general.create') }} +@stop + + +{{-- Content --}} +@section('content') +
+
+
+
+
+ + +
+
+
+
+
+
+@stop +@section('moar_scripts') +@include ('partials.bootstrap-table', ['exportFile' => 'kits-export', 'search' => true]) +@stop diff --git a/resources/views/partials/bootstrap-table.blade.php b/resources/views/partials/bootstrap-table.blade.php index 65ddfa404..66a6d6360 100644 --- a/resources/views/partials/bootstrap-table.blade.php +++ b/resources/views/partials/bootstrap-table.blade.php @@ -192,6 +192,52 @@ }; } + // This only works for model index pages because it uses the row's model ID + function genericChildActionsFormatter(parent, child) { + return function (value,row) { + + var actions = ''; + + // Add some overrides for any funny urls we have + var dest = destination; + + if (destination=='groups') { + var dest = 'admin/groups'; + } + + if (destination=='maintenances') { + var dest = 'hardware/maintenances'; + } + + if ((row.available_actions) && (row.available_actions.clone === true)) { + actions += ' '; + } + + if ((row.available_actions) && (row.available_actions.update === true)) { + actions += ' '; + } + + if ((row.available_actions) && (row.available_actions.delete === true)) { + actions += '' + + ' '; + } else { + actions += ' '; + } + + if ((row.available_actions) && (row.available_actions.restore === true)) { + actions += ' '; + } + + actions +=''; + return actions; + + }; + } + // This handles the icons and display of polymorphic entries function polymorphicItemFormatter(value) { @@ -320,7 +366,11 @@ 'companies', 'depreciations', 'fieldsets', - 'groups' + 'groups', + 'kits', + // METODO: проверить, что эти пути работают + 'kits.models', + 'kits.licenses', ]; for (var i in formatters) { @@ -330,6 +380,18 @@ window[formatters[i] + 'InOutFormatter'] = genericCheckinCheckoutFormatter(formatters[i]); } + var childFormatters = [ + ['kits', 'models'], + ['kits', 'licenses'], + ]; + + for (var i in childFormatters) { + var parentName = childFormatters[i][0]; + var childName = childFormatters[i][2]; + window[childFormatters[i][0] + 'ChildsActionsFormatter'] = genericChildActionsFormatter(childFormatters[i][0], childFormatters[i][1]); + } + + // This is gross, but necessary so that we can package the API response // for custom fields in a more useful way. diff --git a/resources/views/partials/forms/edit/model-select.blade.php b/resources/views/partials/forms/edit/model-select.blade.php index 48385b6a7..0fd438acf 100644 --- a/resources/views/partials/forms/edit/model-select.blade.php +++ b/resources/views/partials/forms/edit/model-select.blade.php @@ -5,12 +5,19 @@
diff --git a/routes/api.php b/routes/api.php index d23adb046..f5300b1e3 100644 --- a/routes/api.php +++ b/routes/api.php @@ -751,6 +751,82 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () { [ 'as' => 'api.activity.index', 'uses' => 'ReportsController@index' ] ); + // kits + Route::resource('kits', 'PredefinedKitsController', + [ + 'names' => + [ + 'index' => 'api.kits.index', + 'show' => 'api.kits.show', + 'store' => 'api.kits.store', + 'update' => 'api.kits.update', + 'destroy' => 'api.kits.destroy', + ], + 'except' => ['create', 'edit'], + 'parameters' => ['kit' => 'kit_id'] + ] + ); + Route::group([ 'prefix' => 'kits/{kit_id}' ], function () { + + Route::get('licenses', + [ + 'as' => 'api.kits.licenses.index', + 'uses' => 'PredefinedKitsController@indexLicenses', + ] + ); + + Route::post('licenses', + [ + 'as' => 'api.kits.licenses.store', + 'uses' => 'PredefinedKitsController@storeLicense', + ] + ); + + Route::put('licenses/{license_id}', + [ + 'as' => 'api.kits.licenses.update', + 'uses' => 'PredefinedKitsController@updateLicense', + ] + ); + + Route::delete('licenses/{license_id}', + [ + 'as' => 'api.kits.licenses.destroy', + 'uses' => 'PredefinedKitsController@destroyLicense', + ] + ); + + + Route::get('models', + [ + 'as' => 'api.kits.models.index', + 'uses' => 'PredefinedKitsController@indexModels', + ] + ); + + Route::post('models', + [ + 'as' => 'api.kits.models.store', + 'uses' => 'PredefinedKitsController@storeModel', + ] + ); + + Route::put('models/{model_id}', + [ + 'as' => 'api.kits.models.update', + 'uses' => 'PredefinedKitsController@updateModel', + ] + ); + + Route::delete('models/{model_id}', + [ + 'as' => 'api.kits.models.destroy', + 'uses' => 'PredefinedKitsController@destroyModel', + ] + ); + + }); // kits + }); diff --git a/routes/web/kits.php b/routes/web/kits.php new file mode 100644 index 000000000..cecd86f59 --- /dev/null +++ b/routes/web/kits.php @@ -0,0 +1,70 @@ + ['auth'], + 'parameters' => ['kit' => 'kit_id'] +]); + + + +Route::group([ 'prefix' => 'kits/{kit_id}', 'middleware' => ['auth'] ], function () { + + Route::get('licenses', + [ + 'as' => 'kits.licenses.index', + 'uses' => 'Kits\PredefinedKitsController@indexLicenses', + ] + ); + + Route::post('licenses', + [ + 'as' => 'kits.licenses.store', + 'uses' => 'Kits\PredefinedKitsController@storeLicense', + ] + ); + + Route::put('licenses/{license_id}', + [ + 'as' => 'kits.licenses.update', + 'uses' => 'Kits\PredefinedKitsController@updateLicense', + ] + ); + + Route::delete('licenses/{license_id}', + [ + 'as' => 'kits.licenses.destroy', + 'uses' => 'Kits\PredefinedKitsController@destroyLicense', + ] + ); + + + Route::get('models', + [ + 'as' => 'kits.models.index', + 'uses' => 'Kits\PredefinedKitsController@indexModels', + ] + ); + + Route::post('models', + [ + 'as' => 'kits.models.store', + 'uses' => 'Kits\PredefinedKitsController@storeModel', + ] + ); + + Route::put('models/{model_id}', + [ + 'as' => 'kits.models.update', + 'uses' => 'Kits\PredefinedKitsController@updateModel', + ] + ); + + Route::delete('models/{model_id}', + [ + 'as' => 'kits.models.destroy', + 'uses' => 'Kits\PredefinedKitsController@destroyModel', + ] + ); + +}); // kits \ No newline at end of file From 9d5cd27575465bbc694a5d17e14e4c4249a6a273 Mon Sep 17 00:00:00 2001 From: Minaev Dmitriy Date: Wed, 31 Oct 2018 16:06:38 +0300 Subject: [PATCH 08/14] New save mechanic --- .../Api/PredefinedKitsController.php | 12 +- .../Kits/PredefinedKitsController.php | 163 ++++++++++++---- app/Http/Controllers/ModalController.php | 7 + .../PredefinedKitsTransformer.php | 72 +++++++ app/Models/PredefinedKit.php | 106 +++++++++++ app/Models/SnipeItPivot.php | 11 ++ app/Presenters/PredefinedKitPresenter.php | 178 ++++++++++++++++++ resources/views/kits/create.blade.php | 10 + resources/views/kits/edit.blade.php | 18 +- resources/views/kits/index.blade.php | 24 ++- resources/views/kits/model-edit.blade.php | 58 ++++++ resources/views/modals/kit-model.blade.php | 38 ++++ .../views/partials/bootstrap-table.blade.php | 73 ++----- routes/web.php | 2 + routes/web/kits.php | 41 ++-- 15 files changed, 685 insertions(+), 128 deletions(-) create mode 100644 app/Http/Transformers/PredefinedKitsTransformer.php create mode 100644 app/Models/PredefinedKit.php create mode 100644 app/Models/SnipeItPivot.php create mode 100644 app/Presenters/PredefinedKitPresenter.php create mode 100644 resources/views/kits/create.blade.php create mode 100644 resources/views/kits/model-edit.blade.php create mode 100644 resources/views/modals/kit-model.blade.php diff --git a/app/Http/Controllers/Api/PredefinedKitsController.php b/app/Http/Controllers/Api/PredefinedKitsController.php index 72b99aa97..03740bfc3 100644 --- a/app/Http/Controllers/Api/PredefinedKitsController.php +++ b/app/Http/Controllers/Api/PredefinedKitsController.php @@ -36,7 +36,7 @@ class PredefinedKitsController extends Controller $total = $kits->count(); $kits = $kits->skip($offset)->take($limit)->get(); - return (new PredefinedKitsTransformer)->transformPrdefinedKits($kits, $total); + return (new PredefinedKitsTransformer)->transformPredefinedKits($kits, $total); } @@ -74,7 +74,7 @@ class PredefinedKitsController extends Controller { $this->authorize('view', PredefinedKit::class); $kit = PredefinedKit::findOrFail($id); - return (new PredefinedKitsTransformer)->transformPrdefinedKit($kit); + return (new PredefinedKitsTransformer)->transformPredefinedKit($kit); } @@ -247,16 +247,20 @@ class PredefinedKitsController extends Controller */ public function storeModel(Request $request, $kit_id) { + //return response()->json(Helper::formatStandardApiResponse('error', 'string11', dd($request))); // TODO: trans + $this->authorize('update', PredefinedKit::class); $kit = PredefinedKit::findOrFail($kit_id); + $quantity = $request->input('quantity', 1); if( $quantity < 1) { $quantity = 1; } + //echo $request->get('model'); $kit->models()->attach( $request->get('model'), ['quantity' => $quantity]); - - return response()->json(Helper::formatStandardApiResponse('success', $kit, 'License added successfull')); // TODO: trans + + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Model added successfull')); // TODO: trans } /** diff --git a/app/Http/Controllers/Kits/PredefinedKitsController.php b/app/Http/Controllers/Kits/PredefinedKitsController.php index 36ebb27d5..93c64553f 100644 --- a/app/Http/Controllers/Kits/PredefinedKitsController.php +++ b/app/Http/Controllers/Kits/PredefinedKitsController.php @@ -1,5 +1,5 @@ authorize('create', PredefinedKit::class); - return view('kits/edit')->with('item', new PredefinedKit); + return view('kits/create')->with('item', new PredefinedKit); } /** @@ -83,7 +88,7 @@ class PredefinedKitsController extends Controller if(!$success) { return redirect()->back()->withInput()->withErrors($kit->getErrors()); } - return redirect()->route("models.index")->with('success', 'Kit was successfully created.'); // TODO: trans() + return redirect()->route("kits.index")->with('success', 'Kit was successfully created.'); // TODO: trans() } /** @@ -91,13 +96,13 @@ class PredefinedKitsController extends Controller * * @author [A. Gianotto] [] * @since [v1.0] - * @param int $kitId + * @param int $kit_id * @return View */ - public function edit($kitId = null) + public function edit($kit_id = null) { $this->authorize('update', PredefinedKit::class); - if ($kit = PredefinedKit::find($kitId)) { + if ($kit = PredefinedKit::find($kit_id)) { return view('kits/edit') ->with('item', $kit) ->with('models', $kit->models) @@ -113,40 +118,21 @@ class PredefinedKitsController extends Controller * * @author [A. Gianotto] [] * @since [v1.0] - * @param int $kitId + * @param int $kit_id * @return Redirect */ - public function update(ImageUploadRequest $request, $kitId = null) + public function update(ImageUploadRequest $request, $kit_id = null) { $this->authorize('update', PredefinedKit::class); // Check if the kit exists - if (is_null($kit = PredefinedKit::find($kitId))) { + if (is_null($kit = PredefinedKit::find($kit_id))) { // Redirect to the kits management page return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans } $kit->name = $request->input('name'); - - // update models - $new_model_ids = $request->input('models'); - $old_model_ids = $kit->models()->pluck('id'); // METODO: проверить - // для получения ид надо что-то такое https://stackoverflow.com/questions/34308169/eloquent-orm-laravel-5-get-array-of-ids - // project built on Laravel 5.4 - list($add_model_ids, $remove_model_ids) = $this->getAddingDeletingElements($new_model_ids, $old_model_ids); // METODO: тут ошибка, надо именно ид-шки получать, а не сами модели - - $new_licence_ids = $request->input('licences'); - $old_licence_ids = $kit->licences()->pluck('id'); // METODO: проверить - list($add_licence_ids, $remove_licence_ids) = $this->getAddingDeletingElements($new_licence_ids, $old_licence_ids); - - $success = DB::transaction(function() use($kit, $add_models, $remove_models, $add_licences, $remove_licences) { - $kit->models()->detach($remove_models); - $kit->models()->attach($add_models); - $kit->licenses()->detach($remove_licenses); - $kit->licenses()->attach($add_licenses); - return $kit->save(); - }); - - if ($success) { + + if ($kit->save()) { return redirect()->route("kits.index")->with('success', 'Kit was successfully updated'); // TODO: trans } return redirect()->back()->withInput()->withErrors($kit->getErrors()); @@ -158,14 +144,14 @@ class PredefinedKitsController extends Controller * * @author [A. Gianotto] [] * @since [v1.0] - * @param int $kitId + * @param int $kit_id * @return Redirect */ - public function destroy($kitId) + public function destroy($kit_id) { $this->authorize('delete', PredefinedKit::class); // Check if the kit exists - if (is_null($kit = PredefinedKit::find($kitId))) { + if (is_null($kit = PredefinedKit::find($kit_id))) { return redirect()->route('kits.index')->with('error', 'Kit not found'); // TODO: trans } @@ -180,28 +166,123 @@ class PredefinedKitsController extends Controller } /** - * Get the model information to present to the model view page + * Get the kit information to present to the kit view page * * @author [A. Gianotto] [] * @since [v1.0] * @param int $modelId * @return View */ - public function show($modelId = null) + public function show($kit_id = null) { - $this->authorize('view', AssetModel::class); - $model = AssetModel::withTrashed()->find($modelId); + $this->authorize('view', PredefinedKit::class); + $kit = PredefinedKit::find($kit_id); - if (isset($model->id)) { - return view('models/view', compact('model')); + if (isset($kit->id)) { + return view('kits/view', compact('kit')); } // Prepare the error message - $error = trans('admin/models/message.does_not_exist', compact('id')); + $error = 'Kit does not exist.'; // TODO: trans // Redirect to the user management page - return redirect()->route('models.index')->with('error', $error); + return redirect()->route('kits.index')->with('error', $error); } + + /** + * Returns a view containing the Predefined Kit edit form. + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $kit_id + * @return View + */ + public function editModel($kit_id, $model_id) + { + $this->authorize('update', PredefinedKit::class); + if ( ($kit = PredefinedKit::find($kit_id)) + && ($model = $kit->models()->find($model_id)) ) { + // $item = $model->pivot; + // $item->name1 = 'tesn1'; + // dd($item); + //dd($model->pivot); + // $item = $model->pivot; + + return view('kits/model-edit', [ + 'kit' => $kit, + 'model' => $model, + 'item' => $model->pivot + ]); + } + return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans + } + + /** + * Get the kit information to present to the kit view page + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $modelId + * @return View + */ + public function updateModel(Request $request, $kit_id) { + $this->authorize('update', PredefinedKit::class); + if (is_null($kit = PredefinedKit::find($kit_id))) { + // Redirect to the kits management page + return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + } + //return view('kits/create-model')->with('item', $kit); + + + // $quantity = $request->input('quantity', 1); + // if( $quantity < 1) { + // $quantity = 1; + // } + + $validator = \Validator::make($request->all(), $kit->modelRules); + if ($validator->fails()) { + return redirect()->back()->withInput()->withErrors($validator); + } + // $kit->models()->sync([$request->input('model_id') => ['quantity' => $request->input('quantity')]]); + // $kit->models()->updateExistingPivot($request->input('pivot_id'), ['model_id' => $request->input('model_id'), 'quantity' => $request->input('quantity')]); + // $s = [$request->input('pivot_id') => ['model_id' => $request->input('model_id'), 'quantity' => $request->input('quantity')]]; + //dd($s); + // $changes = $kit->models()->syncWithoutDetaching([$request->input('pivot_id') => ['model_id' => $request->input('model_id'), 'quantity' => $request->input('quantity')]]); + // $changes = $kit->models()->syncWithoutDetaching(['1' => ['model_id' => '2', 'quantity' => '35']]); + $pivot = $kit->models()->wherePivot('id', $request->input('pivot_id'))->first()->pivot; + // $pivot = $kit->models()->newPivotStatement()->find('1'); + // $ret = $kit->models()->newPivotStatement()->find('1'); + $pivot->model_id = $request->input('model_id'); + $pivot->quantity = $request->input('quantity'); + $pivot->save(); + + // return $this->edit($kit_id)->with('success', 'Model updated successfully.'); + return redirect()->route('kits.edit', $kit_id)->with('success', 'Model updated successfully.'); // TODO: trans + } + + /** + * Get the kit information to present to the kit view page + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $modelId + * @return View + */ + public function detachModel($kit_id, $model_id) { + $this->authorize('update', PredefinedKit::class); + if (is_null($kit = PredefinedKit::find($kit_id))) { + // Redirect to the kits management page + return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + } + + // Delete childs + $kit->models()->detach($model_id); + + // Redirect to the kit management page + return redirect()->route('kits.index')->with('success', 'Kit was successfully deleted'); // TODO: trans + } + + /** * Returns true if a fieldset is set, 'add default values' is ticked and if * any default values were entered into the form. diff --git a/app/Http/Controllers/ModalController.php b/app/Http/Controllers/ModalController.php index c55ad04a4..791d342a8 100644 --- a/app/Http/Controllers/ModalController.php +++ b/app/Http/Controllers/ModalController.php @@ -36,4 +36,11 @@ class ModalController extends Controller return view('modals.manufacturer'); } + function kitModel() { + return view('modals.kit-model'); + } + + function kitLicense() { + return view('modals.kit-license'); + } } diff --git a/app/Http/Transformers/PredefinedKitsTransformer.php b/app/Http/Transformers/PredefinedKitsTransformer.php new file mode 100644 index 000000000..9efa11fc4 --- /dev/null +++ b/app/Http/Transformers/PredefinedKitsTransformer.php @@ -0,0 +1,72 @@ +transformDatatables($array, $total); + } + + public function transformPredefinedKit (PredefinedKit $kit) + { + $array = [ + 'id' => (int) $kit->id, + 'name' => e($kit->name) + ]; + + $permissions_array['available_actions'] = [ + 'update' => Gate::allows('update', PredefinedKit::class), + 'delete' => Gate::allows('delete', PredefinedKit::class), + // 'clone' => Gate::allows('create', PredefinedKit::class), + // 'restore' => Gate::allows('create', PredefinedKit::class), + ]; + + $array += $permissions_array; + return $array; + } + + public function transformElements(Collection $elements, $total) { + $array = array(); + foreach ($elements as $element) { + $array[] = self::transformElement($element); + } + return (new DatatablesTransformer)->transformDatatables($array, $total); + } + + public function transformElement(SnipeModel $element) { + $array = [ + 'id' => (int) $element->id, + 'pivot_id' => (int) $element->pivot->id, + 'owner_id' => (int) $element->pivot->kit_id, + 'quantity' => (int) $element->pivot->quantity, + 'name' => e($element->name) + ]; + + $permissions_array['available_actions'] = [ + 'update' => Gate::allows('update', PredefinedKit::class), + 'delete' => Gate::allows('delete', PredefinedKit::class), + ]; + + $array += $permissions_array; + return $array; + } + + public function transformPredefinedKitsDatatable($kits) { + return (new DatatablesTransformer)->transformDatatables($kits); + } + + +} diff --git a/app/Models/PredefinedKit.php b/app/Models/PredefinedKit.php new file mode 100644 index 000000000..5f2b46f4c --- /dev/null +++ b/app/Models/PredefinedKit.php @@ -0,0 +1,106 @@ + 'required|min:1|max:255|unique' + ); + + use ValidatingTrait; + + public $modelRules = [ + 'model_id' => 'required|exists:models,id', + 'quantity' => 'required|integer|min:1', + 'pivot_id' => 'integer|exists:kits_models,id' + ]; + + public $licenseRules = [ + 'license_id' => 'required|exists:licenses,id', + 'quantity' => 'required|integer|min:1', + 'pivot_id' => 'integer|exists:kits_licenses,id' + ]; + + + /** + * The attributes that are mass assignable. + * + * @var array + */ + protected $fillable = [ + 'name' + ]; + + use Searchable; + + /** + * The attributes that should be included when searching the model. + * + * @var array + */ + protected $searchableAttributes = ['name']; + + /** + * The relations and their attributes that should be included when searching the model. + * + * @var array + */ + protected $searchableRelations = []; + + + /** + * Establishes the kits -> models relationship + * + * @author [A. Gianotto] [] + * @since [v2.0] + * @return \Illuminate\Database\Eloquent\Relations\Relation + */ + public function models() + { + return $this->belongsToMany('\App\Models\AssetModel', 'kits_models', 'kit_id', 'model_id')->withPivot('id', 'quantity'); + } + + /** + * Establishes the kits -> licenses relationship + * + * @author [A. Gianotto] [] + * @since [v4.3] + * @return \Illuminate\Database\Eloquent\Relations\Relation + */ + public function licenses() + { + return $this->belongsToMany('\App\Models\License', 'kits_licenses', 'kit_id', 'license_id')->withPivot('id', 'quantity'); + } + + + + /** + * ----------------------------------------------- + * BEGIN QUERY SCOPES + * ----------------------------------------------- + **/ + +} diff --git a/app/Models/SnipeItPivot.php b/app/Models/SnipeItPivot.php new file mode 100644 index 000000000..143185420 --- /dev/null +++ b/app/Models/SnipeItPivot.php @@ -0,0 +1,11 @@ + "id", + "searchable" => false, + "sortable" => true, + "switchable" => true, + "title" => trans('general.id'), + "visible" => false + ], [ + "field" => "name", + "searchable" => true, + "sortable" => true, + "title" => 'Name', // TODO: trans + "formatter" => "kitsLinkFormatter" + ] + ]; + + $layout[] = [ + "field" => "actions", + "searchable" => false, + "sortable" => false, + "switchable" => false, + "title" => trans('table.actions'), + "formatter" => "kitsActionsFormatter", + ]; + + + return json_encode($layout); + } + + + /** + * Json Column Layout for bootstrap table + * @return string + */ + public static function dataTableModels() + { + $layout = [ + [ + "field" => "id", + "searchable" => false, + "sortable" => true, + "switchable" => true, + "title" => trans('general.id'), + "visible" => false + ], [ + "field" => "pivot_id", + "searchable" => false, + "sortable" => true, + "switchable" => true, + "title" => trans('general.id'), + "visible" => false + ], [ + "field" => "owner_id", + "searchable" => false, + "sortable" => true, + "switchable" => true, + "title" => trans('general.id'), + "visible" => false + ], [ + "field" => "name", + "searchable" => true, + "sortable" => true, + "title" => 'Name', // TODO: trans + "formatter" => "modelsLinkFormatter" + ], [ + "field" => "quantity", + "searchable" => false, + "sortable" => false, + "title" => 'Quantity', // TODO: trans + ], [ + "field" => "actions", + "searchable" => false, + "sortable" => false, + "switchable" => false, + "title" => trans('table.actions'), + "formatter" => "kits_modelsActionsFormatter", + ] + ]; + + return json_encode($layout); + } + + /** + * Json Column Layout for bootstrap table + * @return string + */ + public static function dataTableLicenses() + { + $layout = [ + [ + "field" => "id", + "searchable" => false, + "sortable" => true, + "switchable" => true, + "title" => trans('general.id'), + "visible" => false + ], [ + "field" => "pivot_id", + "searchable" => false, + "sortable" => true, + "switchable" => true, + "title" => trans('general.id'), + "visible" => false + ], [ + "field" => "owner_id", + "searchable" => false, + "sortable" => true, + "switchable" => true, + "title" => trans('general.id'), + "visible" => false + ], [ + "field" => "name", + "searchable" => true, + "sortable" => true, + "title" => 'Name', // TODO: trans + "formatter" => "licensesLinkFormatter" + ], [ + "field" => "actions", + "searchable" => false, + "sortable" => false, + "switchable" => false, + "title" => trans('table.actions'), + "formatter" => "kits_licensesActionsFormatter", + ] + ]; + + return json_encode($layout); + } + + + + /** + * Link to this kit Name + * @return string + */ + public function nameUrl() + { + return (string)link_to_route('kits.show', $this->name, $this->id); + } + + /** + * Link to this kit Name + * @return string + */ + public function fullName() + { + return $this->name; + } + + /** + * Url to view this item. + * @return string + */ + public function viewUrl() + { + return route('kits.show', $this->id); + } +} diff --git a/resources/views/kits/create.blade.php b/resources/views/kits/create.blade.php new file mode 100644 index 000000000..4be2bb5dc --- /dev/null +++ b/resources/views/kits/create.blade.php @@ -0,0 +1,10 @@ +@extends('layouts/edit-form', [ + 'createText' => 'Create kit', + 'updateText' => 'Update kit', + 'formAction' => ($item) ? route('kits.update', ['kit' => $item->id]) : route('kits.store'), +]) + +{{-- Page content --}} +@section('inputFields') +@include ('partials.forms.edit.name', ['translated_name' => 'Name']) {{-- TODO: trans --}} +@stop \ No newline at end of file diff --git a/resources/views/kits/edit.blade.php b/resources/views/kits/edit.blade.php index d16d63e11..6e6ab8742 100644 --- a/resources/views/kits/edit.blade.php +++ b/resources/views/kits/edit.blade.php @@ -6,7 +6,7 @@ {{-- Page content --}} @section('inputFields') -@include ('partials.forms.edit.name') +@include ('partials.forms.edit.name', ['translated_name' => 'Name']) {{-- TODO: trans --}} @stop @section('content') @@ -15,13 +15,14 @@
-

Models

+ {{--

Models Append

--}} +

Models

@@ -54,7 +56,7 @@ +@stop + +@section('moar_scripts') +@include ('partials.bootstrap-table') @stop \ No newline at end of file diff --git a/resources/views/kits/index.blade.php b/resources/views/kits/index.blade.php index c5e492f7b..6cf41e73f 100644 --- a/resources/views/kits/index.blade.php +++ b/resources/views/kits/index.blade.php @@ -21,7 +21,7 @@ Kits
+ {{--

Test

+
+ +
+
--}}
diff --git a/resources/views/kits/model-edit.blade.php b/resources/views/kits/model-edit.blade.php new file mode 100644 index 000000000..7a283c580 --- /dev/null +++ b/resources/views/kits/model-edit.blade.php @@ -0,0 +1,58 @@ +@extends('layouts/edit-form', [ + 'createText' => 'Append model', // TODO: trans + 'updateText' => 'Update appended model', // TODO: trans + 'formAction' => ($item) ? route('kits.models.update', ['kit_id' => $kit->id, 'model_id' => $item->model_id]) : route('kits.models.store', ['kit_id' => $kit->id]), +]) + +{{-- Page content --}} +@section('inputFields') +{{--
+ +
+ + @if ($model_id = Input::old('model_id', (isset($item)) ? $item->model_id : '')) + + @else + + @endif + + +
+
+ @can('create', \App\Models\AssetModel::class) + @if ((!isset($hide_new)) || ($hide_new!='true')) + New + + @endif + @endcan +
+ + {!! $errors->first('model_id', '
:message
') !!} +
--}} +
+ +
+
+ +
+ {!! $errors->first('quantity', ' :message') !!} +
+
+ + +{{-- --}} + +@stop diff --git a/resources/views/modals/kit-model.blade.php b/resources/views/modals/kit-model.blade.php new file mode 100644 index 000000000..4f90f2572 --- /dev/null +++ b/resources/views/modals/kit-model.blade.php @@ -0,0 +1,38 @@ +{{-- See snipeit_modals.js for what powers this --}} + diff --git a/resources/views/partials/bootstrap-table.blade.php b/resources/views/partials/bootstrap-table.blade.php index e96f88d1a..28f93dad7 100644 --- a/resources/views/partials/bootstrap-table.blade.php +++ b/resources/views/partials/bootstrap-table.blade.php @@ -150,22 +150,26 @@ } // Make the edit/delete buttons - function genericActionsFormatter(destination) { + function genericActionsFormatter(owner_name, element_name = '') { return function (value,row) { var actions = ''; // Add some overrides for any funny urls we have - var dest = destination; + var dest = owner_name; - if (destination=='groups') { + if (dest =='groups') { var dest = 'admin/groups'; } - if (destination=='maintenances') { + if (dest =='maintenances') { var dest = 'hardware/maintenances'; } + if(element_name != '') { + dest = dest + '/' + row.owner_id + '/' + element_name; + } + if ((row.available_actions) && (row.available_actions.clone === true)) { actions += ' '; } @@ -195,52 +199,6 @@ }; } - // This only works for model index pages because it uses the row's model ID - function genericChildActionsFormatter(parent, child) { - return function (value,row) { - - var actions = ''; - - // Add some overrides for any funny urls we have - var dest = destination; - - if (destination=='groups') { - var dest = 'admin/groups'; - } - - if (destination=='maintenances') { - var dest = 'hardware/maintenances'; - } - - if ((row.available_actions) && (row.available_actions.clone === true)) { - actions += ' '; - } - - if ((row.available_actions) && (row.available_actions.update === true)) { - actions += ' '; - } - - if ((row.available_actions) && (row.available_actions.delete === true)) { - actions += '' - + ' '; - } else { - actions += ' '; - } - - if ((row.available_actions) && (row.available_actions.restore === true)) { - actions += ' '; - } - - actions +=''; - return actions; - - }; - } - // This handles the icons and display of polymorphic entries function polymorphicItemFormatter(value) { @@ -370,10 +328,7 @@ 'depreciations', 'fieldsets', 'groups', - 'kits', - // METODO: проверить, что эти пути работают - 'kits.models', - 'kits.licenses', + 'kits' ]; for (var i in formatters) { @@ -383,15 +338,15 @@ window[formatters[i] + 'InOutFormatter'] = genericCheckinCheckoutFormatter(formatters[i]); } - var childFormatters = [ + var child_formatters = [ ['kits', 'models'], ['kits', 'licenses'], ]; - for (var i in childFormatters) { - var parentName = childFormatters[i][0]; - var childName = childFormatters[i][2]; - window[childFormatters[i][0] + 'ChildsActionsFormatter'] = genericChildActionsFormatter(childFormatters[i][0], childFormatters[i][1]); + for (var i in child_formatters) { + var owner_name = child_formatters[i][0]; + var child_name = child_formatters[i][1]; + window[owner_name + '_' + child_name + 'ActionsFormatter'] = genericActionsFormatter(owner_name, child_name); } diff --git a/routes/web.php b/routes/web.php index f59362c76..827088ed8 100644 --- a/routes/web.php +++ b/routes/web.php @@ -87,6 +87,8 @@ Route::group(['middleware' => 'auth','prefix' => 'modals'], function () { Route::get('statuslabel',['as' => 'modal.statuslabel','uses' => 'ModalController@statuslabel']); Route::get('supplier',['as' => 'modal.supplier','uses' => 'ModalController@supplier']); Route::get('user',['as' => 'modal.user','uses' => 'ModalController@user']); + Route::get('kit-model',['as' => 'modal.kit.model','uses' => 'ModalController@kitModel']); + Route::get('kit-license',['as' => 'modal.kit.license','uses' => 'ModalController@kitLicense']); }); /* diff --git a/routes/web/kits.php b/routes/web/kits.php index cecd86f59..204af83f8 100644 --- a/routes/web/kits.php +++ b/routes/web/kits.php @@ -1,7 +1,7 @@ ['auth'], 'parameters' => ['kit' => 'kit_id'] ]); @@ -10,12 +10,12 @@ Route::resource('kit', 'Kits\PredefinedKitController', [ Route::group([ 'prefix' => 'kits/{kit_id}', 'middleware' => ['auth'] ], function () { - Route::get('licenses', - [ - 'as' => 'kits.licenses.index', - 'uses' => 'Kits\PredefinedKitsController@indexLicenses', - ] - ); + // Route::get('licenses', + // [ + // 'as' => 'kits.licenses.index', + // 'uses' => 'Kits\PredefinedKitsController@indexLicenses', + // ] + // ); Route::post('licenses', [ @@ -33,18 +33,18 @@ Route::group([ 'prefix' => 'kits/{kit_id}', 'middleware' => ['auth'] ], function Route::delete('licenses/{license_id}', [ - 'as' => 'kits.licenses.destroy', - 'uses' => 'Kits\PredefinedKitsController@destroyLicense', + 'as' => 'kits.licenses.detach', + 'uses' => 'Kits\PredefinedKitsController@detachLicense', ] ); - Route::get('models', - [ - 'as' => 'kits.models.index', - 'uses' => 'Kits\PredefinedKitsController@indexModels', - ] - ); + // Route::get('models', + // [ + // 'as' => 'kits.models.index', + // 'uses' => 'Kits\PredefinedKitsController@indexModels', + // ] + // ); Route::post('models', [ @@ -59,11 +59,18 @@ Route::group([ 'prefix' => 'kits/{kit_id}', 'middleware' => ['auth'] ], function 'uses' => 'Kits\PredefinedKitsController@updateModel', ] ); + + Route::get('models/{model_id}/edit', + [ + 'as' => 'kits.models.edit', + 'uses' => 'Kits\PredefinedKitsController@editModel', + ] + ); Route::delete('models/{model_id}', [ - 'as' => 'kits.models.destroy', - 'uses' => 'Kits\PredefinedKitsController@destroyModel', + 'as' => 'kits.models.detach', + 'uses' => 'Kits\PredefinedKitsController@detachModel', ] ); From 79d979f47f2b235e8416860850eba54e089d40b0 Mon Sep 17 00:00:00 2001 From: Minaev Dmitriy Date: Tue, 6 Nov 2018 19:27:28 +0300 Subject: [PATCH 09/14] Full kits manipulation without users intagration --- .../Api/PredefinedKitsController.php | 43 +++++++++++-------- .../Kits/PredefinedKitsController.php | 25 ++++++++--- app/Models/PredefinedKit.php | 27 ++++++++++++ app/Providers/RouteServiceProvider.php | 1 + routes/api.php | 4 +- routes/web/kits.php | 2 + 6 files changed, 76 insertions(+), 26 deletions(-) diff --git a/app/Http/Controllers/Api/PredefinedKitsController.php b/app/Http/Controllers/Api/PredefinedKitsController.php index 03740bfc3..e72966ec8 100644 --- a/app/Http/Controllers/Api/PredefinedKitsController.php +++ b/app/Http/Controllers/Api/PredefinedKitsController.php @@ -202,7 +202,7 @@ class PredefinedKitsController extends Controller } $kit->licenses()->sync([$license_id => ['quantity' => $quantity]]); - return response()->json(Helper::formatStandardApiResponse('success', null, 'License updated')); // TODO: trans + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'License updated')); // TODO: trans } /** @@ -213,13 +213,13 @@ class PredefinedKitsController extends Controller * @param int $kit_id * @return \Illuminate\Http\Response */ - public function destroyLicense($kit_id, $license_id) + public function detachLicense($kit_id, $license_id) { $this->authorize('update', PredefinedKit::class); $kit = PredefinedKit::findOrFail($id); $kit->licenses()->detach($license_id); - return response()->json(Helper::formatStandardApiResponse('success', null, 'Delete was successfull')); // TODO: trans + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Delete was successfull')); // TODO: trans } /** @@ -249,18 +249,23 @@ class PredefinedKitsController extends Controller { //return response()->json(Helper::formatStandardApiResponse('error', 'string11', dd($request))); // TODO: trans - $this->authorize('update', PredefinedKit::class); - - $kit = PredefinedKit::findOrFail($kit_id); - - $quantity = $request->input('quantity', 1); - if( $quantity < 1) { - $quantity = 1; - } - //echo $request->get('model'); - $kit->models()->attach( $request->get('model'), ['quantity' => $quantity]); - - return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Model added successfull')); // TODO: trans + $this->authorize('update', PredefinedKit::class); + + $kit = PredefinedKit::findOrFail($kit_id); + + $model_id = $request->get('model'); + $quantity = $request->input('quantity', 1); + if( $quantity < 1) { + $quantity = 1; + } + //echo $request->get('model'); + $relation = $kit->models(); + if( $relation->find($model_id) ) { + return response()->json(Helper::formatStandardApiResponse('error', null, 'Model already exists')); + } + $relation->attach($model_id, ['quantity' => $quantity]); + + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Model added successfull')); // TODO: trans } /** @@ -280,9 +285,9 @@ class PredefinedKitsController extends Controller if( $quantity < 1) { $quantity = 1; } - $kit->models()->sync([$model_id => ['quantity' => $quantity]]); + $kit->models()->syncWithoutDetaching([$model_id => ['quantity' => $quantity]]); - return response()->json(Helper::formatStandardApiResponse('success', null, 'License updated')); // TODO: trans + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'License updated')); // TODO: trans } /** @@ -293,12 +298,12 @@ class PredefinedKitsController extends Controller * @param int $kit_id * @return \Illuminate\Http\Response */ - public function destroyModel($kit_id, $model_id) + public function detachModel($kit_id, $model_id) { $this->authorize('update', PredefinedKit::class); $kit = PredefinedKit::findOrFail($id); $kit->models()->detach($model_id); - return response()->json(Helper::formatStandardApiResponse('success', null, 'Delete was successfull')); // TODO: trans + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Delete was successfull')); // TODO: trans } } diff --git a/app/Http/Controllers/Kits/PredefinedKitsController.php b/app/Http/Controllers/Kits/PredefinedKitsController.php index 93c64553f..4fd717b2f 100644 --- a/app/Http/Controllers/Kits/PredefinedKitsController.php +++ b/app/Http/Controllers/Kits/PredefinedKitsController.php @@ -156,8 +156,8 @@ class PredefinedKitsController extends Controller } // Delete childs - $kit->models()->delete(); - $kit->licenses()->delete(); + $kit->models()->detach(); + $kit->licenses()->detach(); // Delete the kit $kit->delete(); @@ -225,7 +225,11 @@ class PredefinedKitsController extends Controller * @param int $modelId * @return View */ - public function updateModel(Request $request, $kit_id) { + public function updateModel(Request $request, $kit_id, $model_id) { + // $r = $request->all(); + // $r['__model_id'] = $model_id; + // $r['__kit_id'] = $kit_id; + // dd($r); $this->authorize('update', PredefinedKit::class); if (is_null($kit = PredefinedKit::find($kit_id))) { // Redirect to the kits management page @@ -239,7 +243,18 @@ class PredefinedKitsController extends Controller // $quantity = 1; // } - $validator = \Validator::make($request->all(), $kit->modelRules); + // $validator = \Validator::make($request->all(), $kit->modelRules); + $validator = \Validator::make($request->all(), $kit->makeModelRules($model_id)); + // $pivot_id = $request->input('pivot_id'); + // $kit->models()->wherePivot('id', '!=', $pivot_id) + // ->wherePivot('id', '!=', $pivot_id) + // ->first()->pivot; + // $validator->after(function ($validator) use($kit) { + + // // if ($this->somethingElseIsInvalid()) { + // // $validator->errors()->add('field', 'Something is wrong with this field!'); + // // } + // }); if ($validator->fails()) { return redirect()->back()->withInput()->withErrors($validator); } @@ -279,7 +294,7 @@ class PredefinedKitsController extends Controller $kit->models()->detach($model_id); // Redirect to the kit management page - return redirect()->route('kits.index')->with('success', 'Kit was successfully deleted'); // TODO: trans + return redirect()->route('kits.edit', $kit_id)->with('success', 'Model was successfully detached'); // TODO: trans } diff --git a/app/Models/PredefinedKit.php b/app/Models/PredefinedKit.php index 5f2b46f4c..7564bafab 100644 --- a/app/Models/PredefinedKit.php +++ b/app/Models/PredefinedKit.php @@ -8,6 +8,7 @@ use App\Presenters\Presentable; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; use Watson\Validating\ValidatingTrait; +use Illuminate\Validation\Rule; /** * Model for Categories. Categories are a higher-level group @@ -34,10 +35,28 @@ class PredefinedKit extends SnipeModel public $modelRules = [ 'model_id' => 'required|exists:models,id', + // 'model_id' => [ + // 'required', + // 'exists:models,id', + // Rule::unique('kits_models')->where('model_id', $model_id)->whereNot('kit_id', $this->id) + // ], 'quantity' => 'required|integer|min:1', 'pivot_id' => 'integer|exists:kits_models,id' ]; + public function makeModelRules($model_id) { + return [ + // 'model_id' => 'required|exists:models,id', + 'model_id' => [ + 'required', + 'exists:models,id', + Rule::unique('kits_models')->whereNot('model_id', $model_id)->where('kit_id', $this->id) + ], + 'quantity' => 'required|integer|min:1', + 'pivot_id' => 'integer|exists:kits_models,id' + ]; + } + public $licenseRules = [ 'license_id' => 'required|exists:licenses,id', 'quantity' => 'required|integer|min:1', @@ -83,6 +102,11 @@ class PredefinedKit extends SnipeModel return $this->belongsToMany('\App\Models\AssetModel', 'kits_models', 'kit_id', 'model_id')->withPivot('id', 'quantity'); } + public function assets() + { + return $this->hasManyThrough('\App\Models\Asset', '\App\Models\AssetModel', 'country_id', 'user_id'); + } + /** * Establishes the kits -> licenses relationship * @@ -96,6 +120,9 @@ class PredefinedKit extends SnipeModel } + public function applyToUser(User $user) { + $models = $this->models(); + } /** * ----------------------------------------------- diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 02bf3dc07..0ccda1ea3 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -64,6 +64,7 @@ class RouteServiceProvider extends ServiceProvider require base_path('routes/web/components.php'); require base_path('routes/web/users.php'); require base_path('routes/web/kits.php'); + require base_path('routes/web/dbtest.php'); require base_path('routes/web.php'); }); } diff --git a/routes/api.php b/routes/api.php index f5300b1e3..cf7f74961 100644 --- a/routes/api.php +++ b/routes/api.php @@ -794,7 +794,7 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () { Route::delete('licenses/{license_id}', [ 'as' => 'api.kits.licenses.destroy', - 'uses' => 'PredefinedKitsController@destroyLicense', + 'uses' => 'PredefinedKitsController@detachLicense', ] ); @@ -823,7 +823,7 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () { Route::delete('models/{model_id}', [ 'as' => 'api.kits.models.destroy', - 'uses' => 'PredefinedKitsController@destroyModel', + 'uses' => 'PredefinedKitsController@detachModel', ] ); diff --git a/routes/web/kits.php b/routes/web/kits.php index 204af83f8..239210468 100644 --- a/routes/web/kits.php +++ b/routes/web/kits.php @@ -57,6 +57,7 @@ Route::group([ 'prefix' => 'kits/{kit_id}', 'middleware' => ['auth'] ], function [ 'as' => 'kits.models.update', 'uses' => 'Kits\PredefinedKitsController@updateModel', + 'parameters' => [2 => 'kit_id', 1 => 'model_id'] ] ); @@ -64,6 +65,7 @@ Route::group([ 'prefix' => 'kits/{kit_id}', 'middleware' => ['auth'] ], function [ 'as' => 'kits.models.edit', 'uses' => 'Kits\PredefinedKitsController@editModel', + ] ); From 0bbe4994140c51d69eb2ad38d15daa7534d5afd2 Mon Sep 17 00:00:00 2001 From: Minaev Dmitriy Date: Tue, 13 Nov 2018 20:33:32 +0300 Subject: [PATCH 10/14] Kits checkout. But only with models. --- .../Kits/CheckoutKitController.php | 78 +++++++++++++++ .../Kits/PredefinedKitsController.php | 44 ++------- .../PredefinedKitsTransformer.php | 3 +- app/Presenters/PredefinedKitPresenter.php | 10 ++ app/Services/PredefinedKitService.php | 99 +++++++++++++++++++ resources/views/kits/checkout.blade.php | 97 ++++++++++++++++++ resources/views/notifications.blade.php | 13 +++ .../partials/forms/edit/kit-select.blade.php | 27 +++++ routes/web/kits.php | 13 +++ 9 files changed, 346 insertions(+), 38 deletions(-) create mode 100644 app/Http/Controllers/Kits/CheckoutKitController.php create mode 100644 app/Services/PredefinedKitService.php create mode 100644 resources/views/kits/checkout.blade.php create mode 100644 resources/views/partials/forms/edit/kit-select.blade.php diff --git a/app/Http/Controllers/Kits/CheckoutKitController.php b/app/Http/Controllers/Kits/CheckoutKitController.php new file mode 100644 index 000000000..260826d6c --- /dev/null +++ b/app/Http/Controllers/Kits/CheckoutKitController.php @@ -0,0 +1,78 @@ +kitService = $kitService; + } + + + /** + * Show Bulk Checkout Page + * @return View View to checkout multiple assets + */ + public function showCheckout($kit_id) + { + // METODO: добавить больше проверок, тут ещё и модель и прочее что мне надо бу + $this->authorize('checkout', Asset::class); + + $kit = PredefinedKit::findOrFail($kit_id); + return view('kits/checkout')->with('kit', $kit); + } + + /** + * Validate and process the new Predefined Kit data. + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @return Redirect + */ + public function store(Request $request, $kit_id) + { + $user_id = e($request->get('user_id')); + if ( is_null($user = User::find( $user_id )) ) { + return redirect()->back()->with('error', trans('admin/users/message.user_not_found')); + } + + $kit = new PredefinedKit(); + $kit->id = $kit_id; + + $errors = $this->kitService->checkout($request, $kit, $user); + if( count($errors) > 0 ) { + return redirect()->back()->with('error', trans('admin/hardware/message.checkout.error'))->with('error_messages', $errors); + } + return redirect()->back()->with('success', trans('admin/hardware/message.checkout.success')); + + } +} diff --git a/app/Http/Controllers/Kits/PredefinedKitsController.php b/app/Http/Controllers/Kits/PredefinedKitsController.php index 4fd717b2f..b13ef7d27 100644 --- a/app/Http/Controllers/Kits/PredefinedKitsController.php +++ b/app/Http/Controllers/Kits/PredefinedKitsController.php @@ -39,8 +39,7 @@ class PredefinedKitsController extends Controller */ public function create() { - //$this->authorize('create', PredefinedKit::class); - + $this->authorize('create', PredefinedKit::class); return view('kits/create')->with('item', new PredefinedKit); } @@ -53,17 +52,15 @@ class PredefinedKitsController extends Controller */ public function store(ImageUploadRequest $request) { - //$this->authorize('create', AssetModel::class); + $this->authorize('create', PredefinedKit::class); // Create a new Predefined Kit $kit = new PredefinedKit; - - // Save the model data $kit->name = $request->input('name'); if(!$kit->save()) { return redirect()->back()->withInput()->withErrors($kit->getErrors()); } - + // METODO: удалить $model_ids = $request->input('models'); if (!is_array($model_ids)) { $model_ids = []; @@ -226,52 +223,25 @@ class PredefinedKitsController extends Controller * @return View */ public function updateModel(Request $request, $kit_id, $model_id) { - // $r = $request->all(); - // $r['__model_id'] = $model_id; - // $r['__kit_id'] = $kit_id; - // dd($r); + $this->authorize('update', PredefinedKit::class); if (is_null($kit = PredefinedKit::find($kit_id))) { // Redirect to the kits management page return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans } - //return view('kits/create-model')->with('item', $kit); - - - // $quantity = $request->input('quantity', 1); - // if( $quantity < 1) { - // $quantity = 1; - // } - // $validator = \Validator::make($request->all(), $kit->modelRules); $validator = \Validator::make($request->all(), $kit->makeModelRules($model_id)); - // $pivot_id = $request->input('pivot_id'); - // $kit->models()->wherePivot('id', '!=', $pivot_id) - // ->wherePivot('id', '!=', $pivot_id) - // ->first()->pivot; - // $validator->after(function ($validator) use($kit) { - - // // if ($this->somethingElseIsInvalid()) { - // // $validator->errors()->add('field', 'Something is wrong with this field!'); - // // } - // }); + if ($validator->fails()) { return redirect()->back()->withInput()->withErrors($validator); } - // $kit->models()->sync([$request->input('model_id') => ['quantity' => $request->input('quantity')]]); - // $kit->models()->updateExistingPivot($request->input('pivot_id'), ['model_id' => $request->input('model_id'), 'quantity' => $request->input('quantity')]); - // $s = [$request->input('pivot_id') => ['model_id' => $request->input('model_id'), 'quantity' => $request->input('quantity')]]; - //dd($s); - // $changes = $kit->models()->syncWithoutDetaching([$request->input('pivot_id') => ['model_id' => $request->input('model_id'), 'quantity' => $request->input('quantity')]]); - // $changes = $kit->models()->syncWithoutDetaching(['1' => ['model_id' => '2', 'quantity' => '35']]); + $pivot = $kit->models()->wherePivot('id', $request->input('pivot_id'))->first()->pivot; - // $pivot = $kit->models()->newPivotStatement()->find('1'); - // $ret = $kit->models()->newPivotStatement()->find('1'); + $pivot->model_id = $request->input('model_id'); $pivot->quantity = $request->input('quantity'); $pivot->save(); - // return $this->edit($kit_id)->with('success', 'Model updated successfully.'); return redirect()->route('kits.edit', $kit_id)->with('success', 'Model updated successfully.'); // TODO: trans } diff --git a/app/Http/Transformers/PredefinedKitsTransformer.php b/app/Http/Transformers/PredefinedKitsTransformer.php index 9efa11fc4..4596f3e74 100644 --- a/app/Http/Transformers/PredefinedKitsTransformer.php +++ b/app/Http/Transformers/PredefinedKitsTransformer.php @@ -30,10 +30,11 @@ class PredefinedKitsTransformer $permissions_array['available_actions'] = [ 'update' => Gate::allows('update', PredefinedKit::class), 'delete' => Gate::allows('delete', PredefinedKit::class), + 'checkout' => Gate::allows('checkout', PredefinedKit::class) ? true : false, // 'clone' => Gate::allows('create', PredefinedKit::class), // 'restore' => Gate::allows('create', PredefinedKit::class), ]; - + $array['user_can_checkout'] = true; $array += $permissions_array; return $array; } diff --git a/app/Presenters/PredefinedKitPresenter.php b/app/Presenters/PredefinedKitPresenter.php index 0a679174f..05f86441c 100644 --- a/app/Presenters/PredefinedKitPresenter.php +++ b/app/Presenters/PredefinedKitPresenter.php @@ -34,6 +34,16 @@ class PredefinedKitPresenter extends Presenter ] ]; + $layout[] = [ + "field" => "checkincheckout", + "searchable" => false, + "sortable" => false, + "switchable" => true, + "title" => trans('general.checkin').'/'.trans('general.checkout'), + "visible" => true, + "formatter" => "kitsInOutFormatter", + ]; + $layout[] = [ "field" => "actions", "searchable" => false, diff --git a/app/Services/PredefinedKitService.php b/app/Services/PredefinedKitService.php new file mode 100644 index 000000000..d07f82610 --- /dev/null +++ b/app/Services/PredefinedKitService.php @@ -0,0 +1,99 @@ +models() + ->with( ['assets' => function($hasMany) { $hasMany->RTD(); }] ) + ->get(); + //$licenses = $kit->licenses()->with(['assets' => function($hasMany) { $hasMany->RTD(); }])->get(); + + // Check if the user exists + if (is_null($user) ) { + return [trans('admin/users/message.user_not_found')]; + } + + $assets_to_add = []; + $errors = []; + foreach($models as $model) { + $assets = $model->assets; + $quantity = $model->pivot->quantity; + foreach($assets as $asset) { + + if ($asset->availableForCheckout() + && !$asset->is($user)) { + + $this->authorize('checkout', $asset); + $quantity -= 1; + $assets_to_add []= $asset; + if($quantity <= 0) { + break; + } + } + } + if($quantity > 0) { + $errors []= "Don't have available assets for model " . $model->name . '. Need ' . $model->pivot->quantity . ' assets.'; // TODO: trans + } + } + + if( count($errors) > 0 ) { + return $errors; + } + + $checkout_at = date("Y-m-d H:i:s"); + if (($request->filled('checkout_at')) && ($request->get('checkout_at')!= date("Y-m-d"))) { + $checkout_at = $request->get('checkout_at'); + } + + $expected_checkin = ''; + if ($request->filled('expected_checkin')) { + $expected_checkin = $request->get('expected_checkin'); + } + + $admin = Auth::user(); + + $note = e($request->get('note')); + + $errors = DB::transaction(function () use ($user, $admin, $checkout_at, $expected_checkin, $errors, $assets_to_add, $note) { + + foreach ($assets_to_add as $asset) { + + $asset->location_id = $user->location_id; + + $error = $asset->checkOut($user, $admin, $checkout_at, $expected_checkin, $note, null); + + if ($error) { + array_merge_recursive($errors, $asset->getErrors()->toArray()); + } + } + return $errors; + }); + + return $errors; + + } catch (ModelNotFoundException $e) { + return [$e->getMessage()]; + } catch (CheckoutNotAllowed $e) { + return [$e->getMessage()]; + } + } + +} diff --git a/resources/views/kits/checkout.blade.php b/resources/views/kits/checkout.blade.php new file mode 100644 index 000000000..d9ca25f55 --- /dev/null +++ b/resources/views/kits/checkout.blade.php @@ -0,0 +1,97 @@ +@extends('layouts/default') + +{{-- Page title --}} +@section('title') + Apply predefined kit{{-- TODO: trans --}} +@parent +@stop + +{{-- Page content --}} +@section('content') + + + + +
+ +
+
+
+

Apply predefined kit {{ $kit->name }} to user {{-- TODO: trans --}}

+
+
+
+ {{ csrf_field() }} + @include ('partials.forms.edit.user-select', ['translated_name' => trans('general.select_user'), 'fieldname' => 'user_id', 'required'=> 'true']) + + +
+ {{ Form::label('name', trans('admin/hardware/form.checkout_date'), array('class' => 'col-md-3 control-label')) }} +
+
+ + +
+ {!! $errors->first('checkout_at', ' :message') !!} +
+
+ + +
+ {{ Form::label('name', trans('admin/hardware/form.expected_checkin'), array('class' => 'col-md-3 control-label')) }} +
+
+ + +
+ {!! $errors->first('expected_checkin', ' :message') !!} +
+
+ + + +
+ {{ Form::label('note', trans('admin/hardware/form.notes'), array('class' => 'col-md-3 control-label')) }} +
+ + {!! $errors->first('note', ' :message') !!} +
+
+ +
+ +
+ +
+ + + +
+@stop + +@section('moar_scripts') +@include('partials/assets-assigned') + +@stop + +@section('notifications') +@parent + +@stop diff --git a/resources/views/notifications.blade.php b/resources/views/notifications.blade.php index dff9ab953..4ba0bcae9 100755 --- a/resources/views/notifications.blade.php +++ b/resources/views/notifications.blade.php @@ -45,6 +45,19 @@ @endif +@if ($messages = Session::get('error_messages')) +@foreach ($messages as $message) +
+
+ + + Error: + {{ $message }} +
+
+@endforeach +@endif + @if ($message = Session::get('warning'))
diff --git a/resources/views/partials/forms/edit/kit-select.blade.php b/resources/views/partials/forms/edit/kit-select.blade.php new file mode 100644 index 000000000..3bf251263 --- /dev/null +++ b/resources/views/partials/forms/edit/kit-select.blade.php @@ -0,0 +1,27 @@ +
+ + {{ Form::label($fieldname, $translated_name, array('class' => 'col-md-3 control-label')) }} + +
+ +
+ +
+ @can('create', \App\Models\PredefinedKit::class) + @if ((!isset($hide_new)) || ($hide_new!='true')) + {{-- New --}} + @endif + @endcan +
+ + {!! $errors->first($fieldname, '
:message
') !!} + +
diff --git a/routes/web/kits.php b/routes/web/kits.php index 239210468..e53c70269 100644 --- a/routes/web/kits.php +++ b/routes/web/kits.php @@ -76,4 +76,17 @@ Route::group([ 'prefix' => 'kits/{kit_id}', 'middleware' => ['auth'] ], function ] ); + Route::get('checkout', + [ + 'as' => 'kits.checkout.show', + 'uses' => 'Kits\CheckoutKitController@showCheckout', + ] + ); + + Route::post('checkout', + [ + 'as' => 'kits.checkout.store', + 'uses' => 'Kits\CheckoutKitController@store', + ] + ); }); // kits \ No newline at end of file From e01e0c559600a032a6baa843c9abd4f9e5c95cb6 Mon Sep 17 00:00:00 2001 From: Dmitrii Minaev Date: Sun, 27 Jan 2019 23:19:24 +0300 Subject: [PATCH 11/14] Add licenses, accessories and consumables table presenters app\Presenters\PredefinedKitPresenter.php resources\views\partials\bootstrap-table.blade.php Add refresh licenses, accessories and consumables tables refresh when add a new element resources\assets\js\snipeit_modals.js Some design fixes resources\views\kits\edit.blade.php Add default value to form (template) resources\views\modals\kit-model.blade.php New routes for kit accessories and kit consumables routes\api.php New routes for kit models, kit accessories and kit consumables routes\web\kits.php New templates --- app/Models/PredefinedKit.php | 4 - app/Presenters/PredefinedKitPresenter.php | 109 ++++++++++++++++++ app/Providers/RouteServiceProvider.php | 2 +- resources/assets/js/snipeit_modals.js | 10 +- resources/views/kits/edit.blade.php | 10 +- .../views/modals/kit-accessory.blade.php | 38 ++++++ .../views/modals/kit-consumable.blade.php | 38 ++++++ resources/views/modals/kit-license.blade.php | 38 ++++++ resources/views/modals/kit-model.blade.php | 2 +- .../views/partials/bootstrap-table.blade.php | 2 + routes/api.php | 64 +++++++++- routes/web/kits.php | 84 ++++++++++++-- 12 files changed, 380 insertions(+), 21 deletions(-) create mode 100644 resources/views/modals/kit-accessory.blade.php create mode 100644 resources/views/modals/kit-consumable.blade.php create mode 100644 resources/views/modals/kit-license.blade.php diff --git a/app/Models/PredefinedKit.php b/app/Models/PredefinedKit.php index 7564bafab..ea6f478fa 100644 --- a/app/Models/PredefinedKit.php +++ b/app/Models/PredefinedKit.php @@ -120,10 +120,6 @@ class PredefinedKit extends SnipeModel } - public function applyToUser(User $user) { - $models = $this->models(); - } - /** * ----------------------------------------------- * BEGIN QUERY SCOPES diff --git a/app/Presenters/PredefinedKitPresenter.php b/app/Presenters/PredefinedKitPresenter.php index 05f86441c..26ae3bf6a 100644 --- a/app/Presenters/PredefinedKitPresenter.php +++ b/app/Presenters/PredefinedKitPresenter.php @@ -144,6 +144,11 @@ class PredefinedKitPresenter extends Presenter "sortable" => true, "title" => 'Name', // TODO: trans "formatter" => "licensesLinkFormatter" + ], [ + "field" => "quantity", + "searchable" => false, + "sortable" => false, + "title" => 'Quantity', // TODO: trans ], [ "field" => "actions", "searchable" => false, @@ -157,6 +162,110 @@ class PredefinedKitPresenter extends Presenter return json_encode($layout); } + /** + * Json Column Layout for bootstrap table + * @return string + */ + public static function dataTableAccessories() + { + $layout = [ + [ + "field" => "id", + "searchable" => false, + "sortable" => true, + "switchable" => true, + "title" => trans('general.id'), + "visible" => false + ], [ + "field" => "pivot_id", + "searchable" => false, + "sortable" => true, + "switchable" => true, + "title" => trans('general.id'), + "visible" => false + ], [ + "field" => "owner_id", + "searchable" => false, + "sortable" => true, + "switchable" => true, + "title" => trans('general.id'), + "visible" => false + ], [ + "field" => "name", + "searchable" => true, + "sortable" => true, + "title" => 'Name', // TODO: trans + "formatter" => "accessoriesLinkFormatter" // MYTODO: check + ], [ + "field" => "quantity", + "searchable" => false, + "sortable" => false, + "title" => 'Quantity', // TODO: trans + ], [ + "field" => "actions", + "searchable" => false, + "sortable" => false, + "switchable" => false, + "title" => trans('table.actions'), + "formatter" => "kits_accessoriesActionsFormatter", // MYTODO: check + ] + ]; + + return json_encode($layout); + } + + + /** + * Json Column Layout for bootstrap table + * @return string + */ + public static function dataTableConsumables() + { + $layout = [ + [ + "field" => "id", + "searchable" => false, + "sortable" => true, + "switchable" => true, + "title" => trans('general.id'), + "visible" => false + ], [ + "field" => "pivot_id", + "searchable" => false, + "sortable" => true, + "switchable" => true, + "title" => trans('general.id'), + "visible" => false + ], [ + "field" => "owner_id", + "searchable" => false, + "sortable" => true, + "switchable" => true, + "title" => trans('general.id'), + "visible" => false + ], [ + "field" => "name", + "searchable" => true, + "sortable" => true, + "title" => 'Name', // TODO: trans + "formatter" => "consumablesLinkFormatter" // MYTODO: check + ], [ + "field" => "quantity", + "searchable" => false, + "sortable" => false, + "title" => 'Quantity', // TODO: trans + ], [ + "field" => "actions", + "searchable" => false, + "sortable" => false, + "switchable" => false, + "title" => trans('table.actions'), + "formatter" => "kits_consumablesActionsFormatter", // MYTODO: check + ] + ]; + + return json_encode($layout); + } /** diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 0ccda1ea3..4e17c798c 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -64,7 +64,7 @@ class RouteServiceProvider extends ServiceProvider require base_path('routes/web/components.php'); require base_path('routes/web/users.php'); require base_path('routes/web/kits.php'); - require base_path('routes/web/dbtest.php'); + //require base_path('routes/web/dbtest.php'); require base_path('routes/web.php'); }); } diff --git a/resources/assets/js/snipeit_modals.js b/resources/assets/js/snipeit_modals.js index 56fcdcbc2..30791ce42 100644 --- a/resources/assets/js/snipeit_modals.js +++ b/resources/assets/js/snipeit_modals.js @@ -28,7 +28,7 @@ $(function () { //handle modal-add-interstitial calls - var model, select; + var model, select, refreshSelector; if($('#createModal').length == 0) { $('body').append(''); @@ -38,6 +38,8 @@ $(function () { var link = $(event.relatedTarget); model = link.data("dependency"); select = link.data("select"); + refreshSelector = link.data("refresh"); + $('#createModal').load(link.attr('href'),function () { //do we need to re-select2 this, after load? Probably. $('#createModal').find('select.select2').select2(); @@ -123,6 +125,12 @@ $(function () { $('#createModal').modal('hide'); $('#createModal').html(""); + var refreshTable = $('#' + refreshSelector); + + if(refreshTable.length > 0) { + refreshTable.bootstrapTable('refresh'); + } + // "select" is the original drop-down menu that someone // clicked 'add' on to add a new 'thing' // this code adds the newly created object to that select diff --git a/resources/views/kits/edit.blade.php b/resources/views/kits/edit.blade.php index 6e6ab8742..db16d9dd7 100644 --- a/resources/views/kits/edit.blade.php +++ b/resources/views/kits/edit.blade.php @@ -11,12 +11,13 @@ @section('content') @parent +{{-- Assets by model --}}
{{--

Models Append

--}} -

Models

+

Assets (by models){{-- TODO: trans --}}

@@ -39,21 +40,21 @@ "ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"] }'> - Append + Append
+{{-- Licenses --}}
-

Licenses

+

Licenses{{-- TODO: trans --}}

diff --git a/resources/views/modals/kit-accessory.blade.php b/resources/views/modals/kit-accessory.blade.php new file mode 100644 index 000000000..654116a44 --- /dev/null +++ b/resources/views/modals/kit-accessory.blade.php @@ -0,0 +1,38 @@ +{{-- See snipeit_modals.js for what powers this --}} + diff --git a/resources/views/modals/kit-consumable.blade.php b/resources/views/modals/kit-consumable.blade.php new file mode 100644 index 000000000..ae948b850 --- /dev/null +++ b/resources/views/modals/kit-consumable.blade.php @@ -0,0 +1,38 @@ +{{-- See snipeit_modals.js for what powers this --}} + diff --git a/resources/views/modals/kit-license.blade.php b/resources/views/modals/kit-license.blade.php new file mode 100644 index 000000000..e3306ae86 --- /dev/null +++ b/resources/views/modals/kit-license.blade.php @@ -0,0 +1,38 @@ +{{-- See snipeit_modals.js for what powers this --}} + diff --git a/resources/views/modals/kit-model.blade.php b/resources/views/modals/kit-model.blade.php index 4f90f2572..1800184a7 100644 --- a/resources/views/modals/kit-model.blade.php +++ b/resources/views/modals/kit-model.blade.php @@ -24,7 +24,7 @@
- +
diff --git a/resources/views/partials/bootstrap-table.blade.php b/resources/views/partials/bootstrap-table.blade.php index 28f93dad7..a96585555 100644 --- a/resources/views/partials/bootstrap-table.blade.php +++ b/resources/views/partials/bootstrap-table.blade.php @@ -341,6 +341,8 @@ var child_formatters = [ ['kits', 'models'], ['kits', 'licenses'], + ['kits', 'consumables'], + ['kits', 'accessories'], ]; for (var i in child_formatters) { diff --git a/routes/api.php b/routes/api.php index cf7f74961..ab038aa81 100644 --- a/routes/api.php +++ b/routes/api.php @@ -751,7 +751,8 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () { [ 'as' => 'api.activity.index', 'uses' => 'ReportsController@index' ] ); - // kits + /*--- Kits API ---*/ + Route::resource('kits', 'PredefinedKitsController', [ 'names' => @@ -770,6 +771,7 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () { Route::group([ 'prefix' => 'kits/{kit_id}' ], function () { + // kit licenses Route::get('licenses', [ 'as' => 'api.kits.licenses.index', @@ -798,7 +800,7 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () { ] ); - + // kit models Route::get('models', [ 'as' => 'api.kits.models.index', @@ -827,6 +829,64 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () { ] ); + // kit accessories + Route::get('accessories', + [ + 'as' => 'api.kits.accessories.index', + 'uses' => 'PredefinedKitsController@indexAccessories', + ] + ); + + Route::post('accessories', + [ + 'as' => 'api.kits.accessories.store', + 'uses' => 'PredefinedKitsController@storeAccessory', + ] + ); + + Route::put('accessories/{accessory_id}', + [ + 'as' => 'api.kits.accessories.update', + 'uses' => 'PredefinedKitsController@updateAccessory', + ] + ); + + Route::delete('accessories/{accessory_id}', + [ + 'as' => 'api.kits.accessories.destroy', + 'uses' => 'PredefinedKitsController@detachAccessory', + ] + ); + + // kit consumables + Route::get('consumables', + [ + 'as' => 'api.kits.consumables.index', + 'uses' => 'PredefinedKitsController@indexConsumables', + ] + ); + + Route::post('consumables', + [ + 'as' => 'api.kits.consumables.store', + 'uses' => 'PredefinedKitsController@storeConsumable', + ] + ); + + Route::put('consumables/{consumable_id}', + [ + 'as' => 'api.kits.consumables.update', + 'uses' => 'PredefinedKitsController@updateConsumable', + ] + ); + + Route::delete('consumables/{consumable_id}', + [ + 'as' => 'api.kits.consumables.destroy', + 'uses' => 'PredefinedKitsController@detachConsumable', + ] + ); + }); // kits }); diff --git a/routes/web/kits.php b/routes/web/kits.php index e53c70269..ca1ff534a 100644 --- a/routes/web/kits.php +++ b/routes/web/kits.php @@ -30,6 +30,14 @@ Route::group([ 'prefix' => 'kits/{kit_id}', 'middleware' => ['auth'] ], function 'uses' => 'Kits\PredefinedKitsController@updateLicense', ] ); + + Route::get('licenses/{license_id}/edit', + [ + 'as' => 'kits.licenses.edit', + 'uses' => 'Kits\PredefinedKitsController@editLicense', + + ] + ); Route::delete('licenses/{license_id}', [ @@ -37,15 +45,10 @@ Route::group([ 'prefix' => 'kits/{kit_id}', 'middleware' => ['auth'] ], function 'uses' => 'Kits\PredefinedKitsController@detachLicense', ] ); + - - // Route::get('models', - // [ - // 'as' => 'kits.models.index', - // 'uses' => 'Kits\PredefinedKitsController@indexModels', - // ] - // ); - + // Models + Route::post('models', [ 'as' => 'kits.models.store', @@ -76,6 +79,71 @@ Route::group([ 'prefix' => 'kits/{kit_id}', 'middleware' => ['auth'] ], function ] ); + + // Consumables + + Route::post('consumables', + [ + 'as' => 'kits.consumables.store', + 'uses' => 'Kits\PredefinedKitsController@storeConsumable', + ] + ); + + Route::put('consumables/{consumable_id}', + [ + 'as' => 'kits.consumables.update', + 'uses' => 'Kits\PredefinedKitsController@updateConsumable', + 'parameters' => [2 => 'kit_id', 1 => 'consumable_id'] + ] + ); + + Route::get('consumables/{consumable_id}/edit', + [ + 'as' => 'kits.consumables.edit', + 'uses' => 'Kits\PredefinedKitsController@editConsumable', + + ] + ); + + Route::delete('consumables/{consumable_id}', + [ + 'as' => 'kits.consumables.detach', + 'uses' => 'Kits\PredefinedKitsController@detachConsumable', + ] + ); + + + // Accessories + + Route::post('accessories', + [ + 'as' => 'kits.accessories.store', + 'uses' => 'Kits\PredefinedKitsController@storeAccessory', + ] + ); + + Route::put('accessories/{accessory_id}', + [ + 'as' => 'kits.accessories.update', + 'uses' => 'Kits\PredefinedKitsController@updateAccessory', + 'parameters' => [2 => 'kit_id', 1 => 'accessory_id'] + ] + ); + + Route::get('accessories/{accessory_id}/edit', + [ + 'as' => 'kits.accessories.edit', + 'uses' => 'Kits\PredefinedKitsController@editAccessory', + + ] + ); + + Route::delete('accessories/{accessory_id}', + [ + 'as' => 'kits.accessories.detach', + 'uses' => 'Kits\PredefinedKitsController@detachAccessory', + ] + ); Route::get('checkout', [ 'as' => 'kits.checkout.show', From 5f3a0bdea568b7a4b4b8ca3b1724b9dd56dd1293 Mon Sep 17 00:00:00 2001 From: Dmitrii Minaev Date: Tue, 19 Feb 2019 22:19:00 +0300 Subject: [PATCH 12/14] app\Services\PredefinedKitService.php rename to app\Services\PredefinedKitCheckoutService.php add accessories and consumables tables add selectlist api to: app\Http\Controllers\Api\AccessoriesController.php app\Http\Controllers\Api\ConsumablesController.php app\Http\Controllers\Api\LicensesController.php templates for selectlist apply kit to user works --- .../Controllers/Api/AccessoriesController.php | 27 ++ .../Controllers/Api/ConsumablesController.php | 27 ++ .../Controllers/Api/LicensesController.php | 28 ++ .../Api/PredefinedKitsController.php | 191 +++++++++++++- .../Kits/CheckoutKitController.php | 8 +- .../Kits/PredefinedKitsController.php | 246 +++++++++++++++++- app/Http/Controllers/ModalController.php | 8 + app/Models/PredefinedKit.php | 93 +++++-- app/Providers/RouteServiceProvider.php | 1 - app/Services/PredefinedKitCheckoutService.php | 174 +++++++++++++ app/Services/PredefinedKitService.php | 99 ------- ...018_10_19_154013_add_kits_models_table.php | 2 - ...2_07_185953_add_kits_consumables_table.php | 36 +++ ...2_07_190030_add_kits_accessories_table.php | 36 +++ resources/views/kits/accessory-edit.blade.php | 58 +++++ .../views/kits/consumable-edit.blade.php | 58 +++++ resources/views/kits/edit.blade.php | 68 +++++ resources/views/kits/license-edit.blade.php | 58 +++++ resources/views/layouts/default.blade.php | 7 + .../forms/edit/accessory-select.blade.php | 20 ++ .../forms/edit/consumable-select.blade.php | 20 ++ .../forms/edit/license-select.blade.php | 20 ++ routes/api.php | 41 ++- routes/web.php | 2 + routes/web/kits.php | 23 -- 25 files changed, 1189 insertions(+), 162 deletions(-) create mode 100644 app/Services/PredefinedKitCheckoutService.php delete mode 100644 app/Services/PredefinedKitService.php create mode 100644 database/migrations/2019_02_07_185953_add_kits_consumables_table.php create mode 100644 database/migrations/2019_02_07_190030_add_kits_accessories_table.php create mode 100644 resources/views/kits/accessory-edit.blade.php create mode 100644 resources/views/kits/consumable-edit.blade.php create mode 100644 resources/views/kits/license-edit.blade.php create mode 100644 resources/views/partials/forms/edit/accessory-select.blade.php create mode 100644 resources/views/partials/forms/edit/consumable-select.blade.php create mode 100644 resources/views/partials/forms/edit/license-select.blade.php diff --git a/app/Http/Controllers/Api/AccessoriesController.php b/app/Http/Controllers/Api/AccessoriesController.php index 4e4793dcf..6c8716e54 100644 --- a/app/Http/Controllers/Api/AccessoriesController.php +++ b/app/Http/Controllers/Api/AccessoriesController.php @@ -8,6 +8,7 @@ use App\Helpers\Helper; use App\Models\Accessory; use App\Http\Transformers\AccessoriesTransformer; use App\Models\Company; +use App\Http\Transformers\SelectlistTransformer; class AccessoriesController extends Controller @@ -201,4 +202,30 @@ class AccessoriesController extends Controller return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/accessories/message.delete.success'))); } + + /** + * Gets a paginated collection for the select2 menus + * + * @author [A. Gianotto] [] + * @since [v4.0.16] + * @see \App\Http\Transformers\SelectlistTransformer + * + */ + public function selectlist(Request $request) + { + + $accessories = Accessory::select([ + 'accessories.id', + 'accessories.name' + ]); + + if ($request->filled('search')) { + $accessories = $accessories->where('accessories.name', 'LIKE', '%'.$request->get('search').'%'); + } + + $accessories = $accessories->orderBy('name', 'ASC')->paginate(50); + + + return (new SelectlistTransformer)->transformSelectlist($accessories); + } } diff --git a/app/Http/Controllers/Api/ConsumablesController.php b/app/Http/Controllers/Api/ConsumablesController.php index 85b520172..a97f92771 100644 --- a/app/Http/Controllers/Api/ConsumablesController.php +++ b/app/Http/Controllers/Api/ConsumablesController.php @@ -8,6 +8,7 @@ use App\Models\Company; use App\Models\Consumable; use App\Http\Transformers\ConsumablesTransformer; use App\Helpers\Helper; +use App\Http\Transformers\SelectlistTransformer; class ConsumablesController extends Controller { @@ -187,4 +188,30 @@ class ConsumablesController extends Controller $data = array('total' => $consumableCount, 'rows' => $rows); return $data; } + + /** + * Gets a paginated collection for the select2 menus + * + * @author [A. Gianotto] [] + * @since [v4.0.16] + * @see \App\Http\Transformers\SelectlistTransformer + * + */ + public function selectlist(Request $request) + { + + $consumables = Consumable::select([ + 'consumables.id', + 'consumables.name' + ]); + + if ($request->filled('search')) { + $consumables = $consumables->where('consumables.name', 'LIKE', '%'.$request->get('search').'%'); + } + + $consumables = $consumables->orderBy('name', 'ASC')->paginate(50); + + + return (new SelectlistTransformer)->transformSelectlist($consumables); + } } diff --git a/app/Http/Controllers/Api/LicensesController.php b/app/Http/Controllers/Api/LicensesController.php index 5df6c52d3..9defee8cd 100644 --- a/app/Http/Controllers/Api/LicensesController.php +++ b/app/Http/Controllers/Api/LicensesController.php @@ -11,6 +11,7 @@ use App\Models\License; use App\Models\LicenseSeat; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; +use App\Http\Transformers\SelectlistTransformer; class LicensesController extends Controller { @@ -244,5 +245,32 @@ class LicensesController extends Controller } + + /** + * Gets a paginated collection for the select2 menus + * + * @author [A. Gianotto] [] + * @since [v4.0.16] + * @see \App\Http\Transformers\SelectlistTransformer + * + */ + public function selectlist(Request $request) + { + + $licenses = License::select([ + 'licenses.id', + 'licenses.name' + ]); + + if ($request->filled('search')) { + $licenses = $licenses->where('licenses.name', 'LIKE', '%'.$request->get('search').'%'); + } + + $licenses = $licenses->orderBy('name', 'ASC')->paginate(50); + + + return (new SelectlistTransformer)->transformSelectlist($licenses); + } + } diff --git a/app/Http/Controllers/Api/PredefinedKitsController.php b/app/Http/Controllers/Api/PredefinedKitsController.php index e72966ec8..70d5c17a7 100644 --- a/app/Http/Controllers/Api/PredefinedKitsController.php +++ b/app/Http/Controllers/Api/PredefinedKitsController.php @@ -113,6 +113,12 @@ class PredefinedKitsController extends Controller $this->authorize('delete', PredefinedKit::class); $kit = PredefinedKit::findOrFail($id); + // Delete childs + $kit->models()->detach(); + $kit->licenses()->detach(); + $kit->consumables()->detach(); + $kit->accessories()->detach(); + $kit->delete(); return response()->json(Helper::formatStandardApiResponse('success', null, 'Delete was successfull')); // TODO: trans @@ -178,8 +184,14 @@ class PredefinedKitsController extends Controller if( $quantity < 1) { $quantity = 1; } - $kit->licenses()->attach( $request->get('license'), ['quantity' => $quantity]); - + + $license_id = $request->get('license'); + $relation = $kit->licenses(); + if( $relation->find($license_id) ) { + return response()->json(Helper::formatStandardApiResponse('error', null, ['license' => 'License already attached to kit'])); + } + + $relation->attach( $license_id, ['quantity' => $quantity]); return response()->json(Helper::formatStandardApiResponse('success', $kit, 'License added successfull')); // TODO: trans } @@ -200,7 +212,7 @@ class PredefinedKitsController extends Controller if( $quantity < 1) { $quantity = 1; } - $kit->licenses()->sync([$license_id => ['quantity' => $quantity]]); + $kit->licenses()->syncWithoutDetaching([$license_id => ['quantity' => $quantity]]); return response()->json(Helper::formatStandardApiResponse('success', $kit, 'License updated')); // TODO: trans } @@ -258,10 +270,10 @@ class PredefinedKitsController extends Controller if( $quantity < 1) { $quantity = 1; } - //echo $request->get('model'); + $relation = $kit->models(); if( $relation->find($model_id) ) { - return response()->json(Helper::formatStandardApiResponse('error', null, 'Model already exists')); + return response()->json(Helper::formatStandardApiResponse('error', null, ['model' => 'Model already attached to kit'])); } $relation->attach($model_id, ['quantity' => $quantity]); @@ -306,4 +318,173 @@ class PredefinedKitsController extends Controller $kit->models()->detach($model_id); return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Delete was successfull')); // TODO: trans } + + + + /** + * Display the specified resource. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param int $id + * @return \Illuminate\Http\Response + */ + public function indexConsumables($kit_id) { + $this->authorize('view', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($kit_id); + $consumables = $kit->consumables; + return (new PredefinedKitsTransformer)->transformElements($consumables, $consumables->count()); + } + + + /** + * Display the specified resource. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param int $id + * @return \Illuminate\Http\Response + */ + public function storeConsumable(Request $request, $kit_id) + { + $this->authorize('update', PredefinedKit::class); + + $kit = PredefinedKit::findOrFail($kit_id); + $quantity = $request->input('quantity', 1); + if( $quantity < 1) { + $quantity = 1; + } + + $consumable_id = $request->get('consumable'); + $relation = $kit->consumables(); + if( $relation->find($consumable_id) ) { + return response()->json(Helper::formatStandardApiResponse('error', null, ['consumable' => 'Consumable already attached to kit'])); + } + + $relation->attach( $consumable_id, ['quantity' => $quantity]); + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Consumable added successfull')); // TODO: trans + } + + /** + * Update the specified resource in storage. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function updateConsumable(Request $request, $kit_id, $consumable_id) + { + $this->authorize('update', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($id); + $quantity = $request->input('quantity', 1); + if( $quantity < 1) { + $quantity = 1; + } + $kit->consumables()->syncWithoutDetaching([$consumable_id => ['quantity' => $quantity]]); + + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Consumable updated')); // TODO: trans + } + + /** + * Remove the specified resource from storage. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param int $kit_id + * @return \Illuminate\Http\Response + */ + public function detachConsumable($kit_id, $consumable_id) + { + $this->authorize('update', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($id); + + $kit->consumables()->detach($consumable_id); + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Delete was successfull')); // TODO: trans + } + + + /** + * Display the specified resource. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param int $id + * @return \Illuminate\Http\Response + */ + public function indexAccessories($kit_id) { + $this->authorize('view', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($kit_id); + $accessories = $kit->accessories; + return (new PredefinedKitsTransformer)->transformElements($accessories, $accessories->count()); + } + + + /** + * Display the specified resource. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param int $id + * @return \Illuminate\Http\Response + */ + public function storeAccessory(Request $request, $kit_id) + { + $this->authorize('update', PredefinedKit::class); + + $kit = PredefinedKit::findOrFail($kit_id); + $quantity = $request->input('quantity', 1); + if( $quantity < 1) { + $quantity = 1; + } + + $accessory_id = $request->get('accessory'); + $relation = $kit->accessories(); + if( $relation->find($accessory_id) ) { + return response()->json(Helper::formatStandardApiResponse('error', null, ['accessory' => 'Accessory already attached to kit'])); + } + + $relation->attach( $accessory_id, ['quantity' => $quantity]); + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Accessory added successfull')); // TODO: trans + } + + /** + * Update the specified resource in storage. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function updateAccessory(Request $request, $kit_id, $accessory_id) + { + $this->authorize('update', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($id); + $quantity = $request->input('quantity', 1); + if( $quantity < 1) { + $quantity = 1; + } + $kit->accessories()->syncWithoutDetaching([$accessory_id => ['quantity' => $quantity]]); + + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Accessory updated')); // TODO: trans + } + + /** + * Remove the specified resource from storage. + * + * @author [A. Gianotto] [] + * @since [v4.0] + * @param int $kit_id + * @return \Illuminate\Http\Response + */ + public function detachAccessory($kit_id, $accessory_id) + { + $this->authorize('update', PredefinedKit::class); + $kit = PredefinedKit::findOrFail($id); + + $kit->accessories()->detach($accessory_id); + return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Delete was successfull')); // TODO: trans + } } diff --git a/app/Http/Controllers/Kits/CheckoutKitController.php b/app/Http/Controllers/Kits/CheckoutKitController.php index 260826d6c..36f0b6bda 100644 --- a/app/Http/Controllers/Kits/CheckoutKitController.php +++ b/app/Http/Controllers/Kits/CheckoutKitController.php @@ -13,7 +13,7 @@ use App\Models\Accessory; use App\Models\SnipeItPivot; use Illuminate\Http\Request; use App\Http\Controllers\CheckInOutRequest; -use App\Services\PredefinedKitService; +use App\Services\PredefinedKitCheckoutService; use App\Models\User; @@ -32,7 +32,7 @@ class CheckoutKitController extends Controller use CheckInOutRequest; - public function __construct(PredefinedKitService $kitService) + public function __construct(PredefinedKitCheckoutService $kitService) { $this->kitService = $kitService; } @@ -70,9 +70,9 @@ class CheckoutKitController extends Controller $errors = $this->kitService->checkout($request, $kit, $user); if( count($errors) > 0 ) { - return redirect()->back()->with('error', trans('admin/hardware/message.checkout.error'))->with('error_messages', $errors); + return redirect()->back()->with('error', 'Checkout error')->with('error_messages', $errors); // TODO: trans } - return redirect()->back()->with('success', trans('admin/hardware/message.checkout.success')); + return redirect()->back()->with('success', 'Checkout was successfully'); // TODO: trans } } diff --git a/app/Http/Controllers/Kits/PredefinedKitsController.php b/app/Http/Controllers/Kits/PredefinedKitsController.php index b13ef7d27..d71d99a60 100644 --- a/app/Http/Controllers/Kits/PredefinedKitsController.php +++ b/app/Http/Controllers/Kits/PredefinedKitsController.php @@ -155,6 +155,8 @@ class PredefinedKitsController extends Controller // Delete childs $kit->models()->detach(); $kit->licenses()->detach(); + $kit->consumables()->detach(); + $kit->accessories()->detach(); // Delete the kit $kit->delete(); @@ -246,7 +248,7 @@ class PredefinedKitsController extends Controller } /** - * Get the kit information to present to the kit view page + * Remove the model from set * * @author [A. Gianotto] [] * @since [v1.0] @@ -267,6 +269,246 @@ class PredefinedKitsController extends Controller return redirect()->route('kits.edit', $kit_id)->with('success', 'Model was successfully detached'); // TODO: trans } + /** + * Returns a view containing attached license edit form. + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $kit_id + * @param int $licenseId + * @return View + */ + public function editLicense($kit_id, $license_id) + { + $this->authorize('update', PredefinedKit::class); + if( !($kit = PredefinedKit::find($kit_id)) ) { + return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans + } + if( !($license = $kit->licenses()->find($license_id)) ) { + return redirect()->route('kits.index')->with('error', 'License does not exist'); // TODO: trans + } + + return view('kits/license-edit', [ + 'kit' => $kit, + 'license' => $license, + 'item' => $license->pivot + ]); + } + + /** + * Update attached licese + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $kit_id + * @param int $licenseId + * @return View + */ + public function updateLicense(Request $request, $kit_id, $license_id) { + + $this->authorize('update', PredefinedKit::class); + if (is_null($kit = PredefinedKit::find($kit_id))) { + // Redirect to the kits management page + return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + } + + $validator = \Validator::make($request->all(), $kit->makeLicenseRules($license_id)); + + if ($validator->fails()) { + return redirect()->back()->withInput()->withErrors($validator); + } + + $pivot = $kit->licenses()->wherePivot('id', $request->input('pivot_id'))->first()->pivot; + + $pivot->license_id = $request->input('license_id'); + $pivot->quantity = $request->input('quantity'); + $pivot->save(); + + return redirect()->route('kits.edit', $kit_id)->with('success', 'License updated successfully.'); // TODO: trans + } + + /** + * + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $licenseId + * @return View + */ + public function detachLicense($kit_id, $license_id) { + $this->authorize('update', PredefinedKit::class); + if (is_null($kit = PredefinedKit::find($kit_id))) { + // Redirect to the kits management page + return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + } + + // Delete childs + $kit->licenses()->detach($license_id); + + // Redirect to the kit management page + return redirect()->route('kits.edit', $kit_id)->with('success', 'License was successfully detached'); // TODO: trans + } + + + /** + * Returns a view containing attached accessory edit form. + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $kit_id + * @param int $accessoryId + * @return View + */ + public function editAccessory($kit_id, $accessory_id) + { + $this->authorize('update', PredefinedKit::class); + if( !($kit = PredefinedKit::find($kit_id)) ) { + return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans + } + if( !($accessory = $kit->accessories()->find($accessory_id)) ) { + return redirect()->route('kits.index')->with('error', 'Accessory does not exist'); // TODO: trans + } + + return view('kits/accessory-edit', [ + 'kit' => $kit, + 'accessory' => $accessory, + 'item' => $accessory->pivot + ]); + } + + /** + * Update attached accessory + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $kit_id + * @param int $accessoryId + * @return View + */ + public function updateAccessory(Request $request, $kit_id, $accessory_id) { + + $this->authorize('update', PredefinedKit::class); + if (is_null($kit = PredefinedKit::find($kit_id))) { + // Redirect to the kits management page + return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + } + + $validator = \Validator::make($request->all(), $kit->makeAccessoryRules($accessory_id)); + + if ($validator->fails()) { + return redirect()->back()->withInput()->withErrors($validator); + } + + $pivot = $kit->accessories()->wherePivot('id', $request->input('pivot_id'))->first()->pivot; + + $pivot->accessory_id = $request->input('accessory_id'); + $pivot->quantity = $request->input('quantity'); + $pivot->save(); + + return redirect()->route('kits.edit', $kit_id)->with('success', 'Accessory updated successfully.'); // TODO: trans + } + + /** + * + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $accessoryId + * @return View + */ + public function detachAccessory($kit_id, $accessory_id) { + $this->authorize('update', PredefinedKit::class); + if (is_null($kit = PredefinedKit::find($kit_id))) { + // Redirect to the kits management page + return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + } + + // Delete childs + $kit->accessories()->detach($accessory_id); + + // Redirect to the kit management page + return redirect()->route('kits.edit', $kit_id)->with('success', 'Accessory was successfully detached'); // TODO: trans + } + + /** + * Returns a view containing attached consumable edit form. + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $kit_id + * @param int $consumableId + * @return View + */ + public function editConsumable($kit_id, $consumable_id) + { + $this->authorize('update', PredefinedKit::class); + if( !($kit = PredefinedKit::find($kit_id)) ) { + return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans + } + if( !($consumable = $kit->consumables()->find($consumable_id)) ) { + return redirect()->route('kits.index')->with('error', 'Consumable does not exist'); // TODO: trans + } + + return view('kits/consumable-edit', [ + 'kit' => $kit, + 'consumable' => $consumable, + 'item' => $consumable->pivot + ]); + } + + /** + * Update attached consumable + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $kit_id + * @param int $consumableId + * @return View + */ + public function updateConsumable(Request $request, $kit_id, $consumable_id) { + + $this->authorize('update', PredefinedKit::class); + if (is_null($kit = PredefinedKit::find($kit_id))) { + // Redirect to the kits management page + return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + } + + $validator = \Validator::make($request->all(), $kit->makeConsumableRules($consumable_id)); + + if ($validator->fails()) { + return redirect()->back()->withInput()->withErrors($validator); + } + + $pivot = $kit->consumables()->wherePivot('id', $request->input('pivot_id'))->first()->pivot; + + $pivot->consumable_id = $request->input('consumable_id'); + $pivot->quantity = $request->input('quantity'); + $pivot->save(); + + return redirect()->route('kits.edit', $kit_id)->with('success', 'Consumable updated successfully.'); // TODO: trans + } + + /** + * + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param int $consumableId + * @return View + */ + public function detachConsumable($kit_id, $consumable_id) { + $this->authorize('update', PredefinedKit::class); + if (is_null($kit = PredefinedKit::find($kit_id))) { + // Redirect to the kits management page + return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + } + + // Delete childs + $kit->consumables()->detach($consumable_id); + + // Redirect to the kit management page + return redirect()->route('kits.edit', $kit_id)->with('success', 'Consumable was successfully detached'); // TODO: trans + } /** * Returns true if a fieldset is set, 'add default values' is ticked and if @@ -283,7 +525,7 @@ class PredefinedKitsController extends Controller } /** - * Adds default values to a model (as long as they are truthy) + * Adds default values to a accessory (as long as they are truthy) * * @param AssetModel $model * @param array $defaultValues diff --git a/app/Http/Controllers/ModalController.php b/app/Http/Controllers/ModalController.php index 791d342a8..168a46e5b 100644 --- a/app/Http/Controllers/ModalController.php +++ b/app/Http/Controllers/ModalController.php @@ -43,4 +43,12 @@ class ModalController extends Controller function kitLicense() { return view('modals.kit-license'); } + + function kitConsumable() { + return view('modals.kit-consumable'); + } + + function kitAccessory() { + return view('modals.kit-accessory'); + } } diff --git a/app/Models/PredefinedKit.php b/app/Models/PredefinedKit.php index ea6f478fa..9044945ec 100644 --- a/app/Models/PredefinedKit.php +++ b/app/Models/PredefinedKit.php @@ -44,24 +44,62 @@ class PredefinedKit extends SnipeModel 'pivot_id' => 'integer|exists:kits_models,id' ]; - public function makeModelRules($model_id) { - return [ - // 'model_id' => 'required|exists:models,id', - 'model_id' => [ - 'required', - 'exists:models,id', - Rule::unique('kits_models')->whereNot('model_id', $model_id)->where('kit_id', $this->id) - ], - 'quantity' => 'required|integer|min:1', - 'pivot_id' => 'integer|exists:kits_models,id' - ]; + public function makeModelRules($model_id, $new = false) { + // return [ + // // 'model_id' => 'required|exists:models,id', + // 'model_id' => [ + // 'required', + // 'exists:models,id', + // Rule::unique('kits_models')->whereNot('model_id', $model_id)->where('kit_id', $this->id) + // ], + // 'quantity' => 'required|integer|min:1', + // 'pivot_id' => 'integer|exists:kits_models,id' + // ]; + return $this->_makeRuleHelper('licenses', 'kits_licenses', 'license_id', $license_id, $new); } - public $licenseRules = [ - 'license_id' => 'required|exists:licenses,id', - 'quantity' => 'required|integer|min:1', - 'pivot_id' => 'integer|exists:kits_licenses,id' - ]; + public function makeLicenseRules($license_id, $new = false) { + return $this->_makeRuleHelper('licenses', 'kits_licenses', 'license_id', $license_id, $new); + } + + public function makeAccessoriesRules($accessoriy_id, $new = false) { + return $this->_makeRuleHelper('accessories', 'kits_accessories', 'accessoriy_id', $accessoriy_id, $new); + } + + public function makeConsumablesRules($consumable_id, $new = false) { + return $this->_makeRuleHelper('consumables', 'kits_consumables', 'consumable_id', $consumable_id, $new); + } + + protected function _makeRuleHelper($table, $pivot_table, $pivot_elem_key, $element_id, $new) { + // return [ + // $pivot_elem_key => [ + // 'required', + // "exists:$table,id", + // Rule::unique($pivot_table)->whereNot($pivot_elem_key, $element_id)->where('kit_id', $this->id) + // ], + // 'quantity' => 'required|integer|min:1', + // 'pivot_id' => "integer|exists:$pivot_table,id" + // ]; + $rule = [ + $pivot_elem_key => [ + 'required', + "exists:$table,id", + Rule::unique($pivot_table)->whereNot($pivot_elem_key, $element_id)->where('kit_id', $this->id) + ], + 'quantity' => 'required|integer|min:1' + ]; + if(!$new) { + $rule['pivot_id'] = "integer|exists:$pivot_table,id"; + + } + return $rule; + } + + // public $licenseRules = [ + // 'license_id' => 'required|exists:licenses,id', + // 'quantity' => 'required|integer|min:1', + // 'pivot_id' => 'integer|exists:kits_licenses,id' + // ]; /** @@ -119,6 +157,29 @@ class PredefinedKit extends SnipeModel return $this->belongsToMany('\App\Models\License', 'kits_licenses', 'kit_id', 'license_id')->withPivot('id', 'quantity'); } + /** + * Establishes the kits -> licenses relationship + * + * @author [A. Gianotto] [] + * @since [v4.3] + * @return \Illuminate\Database\Eloquent\Relations\Relation + */ + public function consumables() + { + return $this->belongsToMany('\App\Models\Consumable', 'kits_consumables', 'kit_id', 'consumable_id')->withPivot('id', 'quantity'); + } + + /** + * Establishes the kits -> licenses relationship + * + * @author [A. Gianotto] [] + * @since [v4.3] + * @return \Illuminate\Database\Eloquent\Relations\Relation + */ + public function accessories() + { + return $this->belongsToMany('\App\Models\Accessory', 'kits_accessories', 'kit_id', 'accessory_id')->withPivot('id', 'quantity'); + } /** * ----------------------------------------------- diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 4e17c798c..02bf3dc07 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -64,7 +64,6 @@ class RouteServiceProvider extends ServiceProvider require base_path('routes/web/components.php'); require base_path('routes/web/users.php'); require base_path('routes/web/kits.php'); - //require base_path('routes/web/dbtest.php'); require base_path('routes/web.php'); }); } diff --git a/app/Services/PredefinedKitCheckoutService.php b/app/Services/PredefinedKitCheckoutService.php new file mode 100644 index 000000000..decdb1db1 --- /dev/null +++ b/app/Services/PredefinedKitCheckoutService.php @@ -0,0 +1,174 @@ +getAssetsToAdd($kit, $user, $errors); + $license_seats_to_add = $this->getLicenseSeatsToAdd($kit, $user, $errors); + $consumables_to_add = $this->getConsumablesToAdd($kit, $user, $errors); + $accessories_to_add = $this->getAccessoriesToAdd($kit, $user, $errors); + + if( count($errors) > 0 ) { + return $errors; + } + + $checkout_at = date("Y-m-d H:i:s"); + if (($request->filled('checkout_at')) && ($request->get('checkout_at')!= date("Y-m-d"))) { + $checkout_at = $request->get('checkout_at'); + } + + $expected_checkin = ''; + if ($request->filled('expected_checkin')) { + $expected_checkin = $request->get('expected_checkin'); + } + + $admin = Auth::user(); + + $note = e($request->get('note')); + + $errors = DB::transaction( + function () use ($user, $admin, $checkout_at, $expected_checkin, $errors, $assets_to_add, $license_seats_to_add, $consumables_to_add, $accessories_to_add, $note) { + // assets + foreach ($assets_to_add as $asset) { + $asset->location_id = $user->location_id; + $error = $asset->checkOut($user, $admin, $checkout_at, $expected_checkin, $note, null); + if ($error) { + array_merge_recursive($errors, $asset->getErrors()->toArray()); + } + } + // licenses + foreach ($license_seats_to_add as $licenseSeat) { + $licenseSeat->user_id = $admin->id; + $licenseSeat->assigned_to = $user->id; + if ($licenseSeat->save()) { + event(new CheckoutableCheckedOut($licenseSeat, $user, $admin, $note)); + } + else { + $errors []= 'Something went wrong saving a license seat'; + } + } + // consumables + foreach($consumables_to_add as $consumable) { + $consumable->assigned_to = $user->id; + $consumable->users()->attach($consumable->id, [ + 'consumable_id' => $consumable->id, + 'user_id' => $admin->id, + 'assigned_to' => $user->id + ]); + event(new CheckoutableCheckedOut($consumable, $user, $admin, $note)); + } + //accessories + foreach($accessories_to_add as $accessory) { + $accessory->assigned_to = $user->id; + $accessory->users()->attach($accessory->id, [ + 'accessory_id' => $accessory->id, + 'user_id' => $admin->id, + 'assigned_to' => $user->id + ]); + event(new CheckoutableCheckedOut($accessory, $user, $admin, $note)); + } + return $errors; + }); + + return $errors; + + } catch (ModelNotFoundException $e) { + return [$e->getMessage()]; + } catch (CheckoutNotAllowed $e) { + return [$e->getMessage()]; + } + } + + protected function getAssetsToAdd($kit, $user, &$errors) { + $models = $kit->models() + ->with( ['assets' => function($hasMany) { $hasMany->RTD(); }] ) + ->get(); + $assets_to_add = []; + foreach($models as $model) { + $assets = $model->assets; + $quantity = $model->pivot->quantity; + foreach($assets as $asset) { + + if ($asset->availableForCheckout() + && !$asset->is($user)) { + + $this->authorize('checkout', $asset); + $quantity -= 1; + $assets_to_add []= $asset; + if($quantity <= 0) { + break; + } + } + } + if($quantity > 0) { + $errors []= "Don't have available assets for model " . $model->name . '. Need ' . $model->pivot->quantity . ' assets.'; // TODO: trans + } + } + + return $assets_to_add; + } + + protected function getLicenseSeatsToAdd($kit, $user, &$errors) { + $seats_to_add = []; + $licenses = $kit->licenses() + ->with('freeSeats') + ->get(); + foreach($licenses as $license) { + $quantity = $license->pivot->quantity; + if( $quantity > count($license->freeSeats) ) { + $errors []= "Don't have free seats for license " . $license->name . '. Need ' . $quantity . ' seats.'; // TODO: trans + } + for($i=0; $i < $quantity; $i++) { + $seats_to_add []= $license->freeSeats[$i]; + } + } + return $seats_to_add; + } + + protected function getConsumablesToAdd($kit, $user, &$errors) { + // $consumables = $kit->consumables()->withCount('consumableAssignments as consumable_assignments_count')->get(); + $consumables = $kit->consumables()->with('users')->get(); + foreach($consumables as $consumable) { + if( $consumable->numRemaining() < $consumable->pivot->quantity ) { + $errors []= "Don't have available consumable " . $consumable->name . '. Need ' . $consumable->pivot->quantity; // TODO: trans + } + } + return $consumables; + } + + protected function getAccessoriesToAdd($kit, $user, &$errors) { + $accessories = $kit->accessories()->with('users')->get(); + foreach($accessories as $accossory) { + if( $accossory->numRemaining() < $accossory->pivot->quantity ) { + $errors []= "Don't have available accossory " . $accossory->name . '. Need ' . $accossory->pivot->quantity; // TODO: trans + } + } + return $accessories; + } +} diff --git a/app/Services/PredefinedKitService.php b/app/Services/PredefinedKitService.php deleted file mode 100644 index d07f82610..000000000 --- a/app/Services/PredefinedKitService.php +++ /dev/null @@ -1,99 +0,0 @@ -models() - ->with( ['assets' => function($hasMany) { $hasMany->RTD(); }] ) - ->get(); - //$licenses = $kit->licenses()->with(['assets' => function($hasMany) { $hasMany->RTD(); }])->get(); - - // Check if the user exists - if (is_null($user) ) { - return [trans('admin/users/message.user_not_found')]; - } - - $assets_to_add = []; - $errors = []; - foreach($models as $model) { - $assets = $model->assets; - $quantity = $model->pivot->quantity; - foreach($assets as $asset) { - - if ($asset->availableForCheckout() - && !$asset->is($user)) { - - $this->authorize('checkout', $asset); - $quantity -= 1; - $assets_to_add []= $asset; - if($quantity <= 0) { - break; - } - } - } - if($quantity > 0) { - $errors []= "Don't have available assets for model " . $model->name . '. Need ' . $model->pivot->quantity . ' assets.'; // TODO: trans - } - } - - if( count($errors) > 0 ) { - return $errors; - } - - $checkout_at = date("Y-m-d H:i:s"); - if (($request->filled('checkout_at')) && ($request->get('checkout_at')!= date("Y-m-d"))) { - $checkout_at = $request->get('checkout_at'); - } - - $expected_checkin = ''; - if ($request->filled('expected_checkin')) { - $expected_checkin = $request->get('expected_checkin'); - } - - $admin = Auth::user(); - - $note = e($request->get('note')); - - $errors = DB::transaction(function () use ($user, $admin, $checkout_at, $expected_checkin, $errors, $assets_to_add, $note) { - - foreach ($assets_to_add as $asset) { - - $asset->location_id = $user->location_id; - - $error = $asset->checkOut($user, $admin, $checkout_at, $expected_checkin, $note, null); - - if ($error) { - array_merge_recursive($errors, $asset->getErrors()->toArray()); - } - } - return $errors; - }); - - return $errors; - - } catch (ModelNotFoundException $e) { - return [$e->getMessage()]; - } catch (CheckoutNotAllowed $e) { - return [$e->getMessage()]; - } - } - -} diff --git a/database/migrations/2018_10_19_154013_add_kits_models_table.php b/database/migrations/2018_10_19_154013_add_kits_models_table.php index 6f80df2da..a0abeeef7 100644 --- a/database/migrations/2018_10_19_154013_add_kits_models_table.php +++ b/database/migrations/2018_10_19_154013_add_kits_models_table.php @@ -20,8 +20,6 @@ class AddKitsModelsTable extends Migration { $table->integer('quantity')->default(1); $table->timestamps(); }); - - } /** diff --git a/database/migrations/2019_02_07_185953_add_kits_consumables_table.php b/database/migrations/2019_02_07_185953_add_kits_consumables_table.php new file mode 100644 index 000000000..b6d14e428 --- /dev/null +++ b/database/migrations/2019_02_07_185953_add_kits_consumables_table.php @@ -0,0 +1,36 @@ +increments('id'); + $table->integer('kit_id')->nullable()->default(NULL); + $table->integer('consumable_id')->nullable()->default(NULL); + $table->integer('quantity')->default(1); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + Schema::drop('kits_consumables'); + } +} diff --git a/database/migrations/2019_02_07_190030_add_kits_accessories_table.php b/database/migrations/2019_02_07_190030_add_kits_accessories_table.php new file mode 100644 index 000000000..f0e80249d --- /dev/null +++ b/database/migrations/2019_02_07_190030_add_kits_accessories_table.php @@ -0,0 +1,36 @@ +increments('id'); + $table->integer('kit_id')->nullable()->default(NULL); + $table->integer('accessory_id')->nullable()->default(NULL); + $table->integer('quantity')->default(1); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + Schema::drop('kits_accessories'); + } +} diff --git a/resources/views/kits/accessory-edit.blade.php b/resources/views/kits/accessory-edit.blade.php new file mode 100644 index 000000000..807cd7fa7 --- /dev/null +++ b/resources/views/kits/accessory-edit.blade.php @@ -0,0 +1,58 @@ +@extends('layouts/edit-form', [ + 'createText' => 'Append accessory', // TODO: trans + 'updateText' => 'Update appended accessory', // TODO: trans + 'formAction' => ($item) ? route('kits.accessories.update', ['kit_id' => $kit->id, 'accessory_id' => $item->accessory_id]) : route('kits.accessories.store', ['kit_id' => $kit->id]), +]) + +{{-- Page content --}} +@section('inputFields') +{{--
+ +
+ + @if ($accessory_id = Input::old('accessory_id', (isset($item)) ? $item->accessory_id : '')) + + @else + + @endif + + +
+
+ @can('create', \App\Accessories\Accessory::class) + @if ((!isset($hide_new)) || ($hide_new!='true')) + New + + @endif + @endcan +
+ + {!! $errors->first('accessory_id', '
:message
') !!} +
--}} +
+ +
+
+ +
+ {!! $errors->first('quantity', ' :message') !!} +
+
+ + +{{-- --}} + +@stop diff --git a/resources/views/kits/consumable-edit.blade.php b/resources/views/kits/consumable-edit.blade.php new file mode 100644 index 000000000..857850e8b --- /dev/null +++ b/resources/views/kits/consumable-edit.blade.php @@ -0,0 +1,58 @@ +@extends('layouts/edit-form', [ + 'createText' => 'Append consumable', // TODO: trans + 'updateText' => 'Update appended consumable', // TODO: trans + 'formAction' => ($item) ? route('kits.consumables.update', ['kit_id' => $kit->id, 'consumable_id' => $item->consumable_id]) : route('kits.consumables.store', ['kit_id' => $kit->id]), +]) + +{{-- Page content --}} +@section('inputFields') +{{--
+ +
+ + @if ($consumable_id = Input::old('consumable_id', (isset($item)) ? $item->consumable_id : '')) + + @else + + @endif + + +
+
+ @can('create', \App\Consumables\Consumable::class) + @if ((!isset($hide_new)) || ($hide_new!='true')) + New + + @endif + @endcan +
+ + {!! $errors->first('consumable_id', '
:message
') !!} +
--}} +
+ +
+
+ +
+ {!! $errors->first('quantity', ' :message') !!} +
+
+ + +{{-- --}} + +@stop diff --git a/resources/views/kits/edit.blade.php b/resources/views/kits/edit.blade.php index db16d9dd7..7d26142d0 100644 --- a/resources/views/kits/edit.blade.php +++ b/resources/views/kits/edit.blade.php @@ -80,6 +80,74 @@
+{{-- Consumables --}} +
+
+
+
+

Consumables{{-- TODO: trans --}}

+
+ +
+
+
+{{-- Accessories --}} +
+
+
+
+

Accessories{{-- TODO: trans --}}

+
+ +
+
+
@stop @section('moar_scripts') diff --git a/resources/views/kits/license-edit.blade.php b/resources/views/kits/license-edit.blade.php new file mode 100644 index 000000000..5a5e6858d --- /dev/null +++ b/resources/views/kits/license-edit.blade.php @@ -0,0 +1,58 @@ +@extends('layouts/edit-form', [ + 'createText' => 'Append license', // TODO: trans + 'updateText' => 'Update appended license', // TODO: trans + 'formAction' => ($item) ? route('kits.licenses.update', ['kit_id' => $kit->id, 'license_id' => $item->license_id]) : route('kits.licenses.store', ['kit_id' => $kit->id]), +]) + +{{-- Page content --}} +@section('inputFields') +{{--
+ +
+ + @if ($license_id = Input::old('license_id', (isset($item)) ? $item->license_id : '')) + + @else + + @endif + + +
+
+ @can('create', \App\Licenses\License::class) + @if ((!isset($hide_new)) || ($hide_new!='true')) + New + + @endif + @endcan +
+ + {!! $errors->first('license_id', '
:message
') !!} +
--}} +
+ +
+
+ +
+ {!! $errors->first('quantity', ' :message') !!} +
+
+ + +{{-- --}} + +@stop diff --git a/resources/views/layouts/default.blade.php b/resources/views/layouts/default.blade.php index 169033ed7..74bde6cf8 100644 --- a/resources/views/layouts/default.blade.php +++ b/resources/views/layouts/default.blade.php @@ -662,6 +662,13 @@ @endcan + + + + + Predefined kits{{-- TODO: trans --}} + + diff --git a/resources/views/partials/forms/edit/accessory-select.blade.php b/resources/views/partials/forms/edit/accessory-select.blade.php new file mode 100644 index 000000000..d8c919c0f --- /dev/null +++ b/resources/views/partials/forms/edit/accessory-select.blade.php @@ -0,0 +1,20 @@ + +
+ {{ Form::label($fieldname, $translated_name, array('class' => 'col-md-3 control-label')) }} +
+ +
+ {!! $errors->first($fieldname, '
:message
') !!} + +
diff --git a/resources/views/partials/forms/edit/consumable-select.blade.php b/resources/views/partials/forms/edit/consumable-select.blade.php new file mode 100644 index 000000000..82fb54f53 --- /dev/null +++ b/resources/views/partials/forms/edit/consumable-select.blade.php @@ -0,0 +1,20 @@ + +
+ {{ Form::label($fieldname, $translated_name, array('class' => 'col-md-3 control-label')) }} +
+ +
+ {!! $errors->first($fieldname, '
:message
') !!} + +
diff --git a/resources/views/partials/forms/edit/license-select.blade.php b/resources/views/partials/forms/edit/license-select.blade.php new file mode 100644 index 000000000..ecb07e074 --- /dev/null +++ b/resources/views/partials/forms/edit/license-select.blade.php @@ -0,0 +1,20 @@ + +
+ {{ Form::label($fieldname, $translated_name, array('class' => 'col-md-3 control-label')) }} +
+ +
+ {!! $errors->first($fieldname, '
:message
') !!} + +
diff --git a/routes/api.php b/routes/api.php index ab038aa81..1178e62f0 100644 --- a/routes/api.php +++ b/routes/api.php @@ -33,7 +33,23 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () { }); - /*--- Accessories API ---*/ + /*--- Accessories API ---*/ + Route::group(['prefix' => 'accessories'], function () { + + Route::get('{accessory}/checkedout', + [ + 'as' => 'api.accessories.checkedout', + 'uses' => 'AccessoriesController@checkedout' + ] + ); + + Route::get('selectlist', + [ + 'as' => 'api.accessories.selectlist', + 'uses'=> 'AccessoriesController@selectlist' + ] + ); + }); // Accessories group Route::resource('accessories', 'AccessoriesController', ['names' => [ @@ -48,15 +64,7 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () { ] ); // Accessories resource - Route::group(['prefix' => 'accessories'], function () { - Route::get('{accessory}/checkedout', - [ - 'as' => 'api.accessories.checkedout', - 'uses' => 'AccessoriesController@checkedout' - ] - ); - }); // Accessories group /*--- Categories API ---*/ @@ -174,7 +182,12 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () { /*--- Consumables API ---*/ - + Route::get('consumables/selectlist', + [ + 'as' => 'api.consumables.selectlist', + 'uses'=> 'ConsumablesController@selectlist' + ] + ); Route::resource('consumables', 'ConsumablesController', [ 'names' => @@ -414,6 +427,14 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () { 'as' => 'api.license.seats', 'uses' => 'LicensesController@seats' ]); + + Route::get('selectlist', + [ + 'as' => 'api.licenses.selectlist', + 'uses'=> 'LicensesController@selectlist' + ] + ); + }); // Licenses group Route::resource('licenses', 'LicensesController', diff --git a/routes/web.php b/routes/web.php index 827088ed8..7ecc4b1fe 100644 --- a/routes/web.php +++ b/routes/web.php @@ -89,6 +89,8 @@ Route::group(['middleware' => 'auth','prefix' => 'modals'], function () { Route::get('user',['as' => 'modal.user','uses' => 'ModalController@user']); Route::get('kit-model',['as' => 'modal.kit.model','uses' => 'ModalController@kitModel']); Route::get('kit-license',['as' => 'modal.kit.license','uses' => 'ModalController@kitLicense']); + Route::get('kit-consumable',['as' => 'modal.kit.consumable','uses' => 'ModalController@kitConsumable']); + Route::get('kit-accessory',['as' => 'modal.kit.accessory','uses' => 'ModalController@kitAccessory']); }); /* diff --git a/routes/web/kits.php b/routes/web/kits.php index ca1ff534a..50712aba4 100644 --- a/routes/web/kits.php +++ b/routes/web/kits.php @@ -48,13 +48,6 @@ Route::group([ 'prefix' => 'kits/{kit_id}', 'middleware' => ['auth'] ], function // Models - - Route::post('models', - [ - 'as' => 'kits.models.store', - 'uses' => 'Kits\PredefinedKitsController@storeModel', - ] - ); Route::put('models/{model_id}', [ @@ -81,14 +74,6 @@ Route::group([ 'prefix' => 'kits/{kit_id}', 'middleware' => ['auth'] ], function // Consumables - - Route::post('consumables', - [ - 'as' => 'kits.consumables.store', - 'uses' => 'Kits\PredefinedKitsController@storeConsumable', - ] - ); - Route::put('consumables/{consumable_id}', [ 'as' => 'kits.consumables.update', @@ -114,14 +99,6 @@ Route::group([ 'prefix' => 'kits/{kit_id}', 'middleware' => ['auth'] ], function // Accessories - - Route::post('accessories', - [ - 'as' => 'kits.accessories.store', - 'uses' => 'Kits\PredefinedKitsController@storeAccessory', - ] - ); - Route::put('accessories/{accessory_id}', [ 'as' => 'kits.accessories.update', From d3c320e56f6f7e8072cd8acf2bf324d217bdeeb2 Mon Sep 17 00:00:00 2001 From: Dmitrii Minaev Date: Sat, 23 Feb 2019 22:44:03 +0300 Subject: [PATCH 13/14] Code comments and format --- .../Controllers/Api/AccessoriesController.php | 2 - .../Controllers/Api/ConsumablesController.php | 2 - .../Controllers/Api/LicensesController.php | 3 - .../Api/PredefinedKitsController.php | 57 +-- .../Kits/CheckoutKitController.php | 33 +- .../Kits/PredefinedKitsController.php | 442 ++++++++---------- .../PredefinedKitsTransformer.php | 12 +- app/Models/PredefinedKit.php | 133 +++--- app/Models/SnipeItPivot.php | 11 - app/Presenters/PredefinedKitPresenter.php | 19 +- app/Services/PredefinedKitCheckoutService.php | 10 +- ...8_10_18_191228_add_kits_licenses_table.php | 2 - 12 files changed, 297 insertions(+), 429 deletions(-) delete mode 100644 app/Models/SnipeItPivot.php diff --git a/app/Http/Controllers/Api/AccessoriesController.php b/app/Http/Controllers/Api/AccessoriesController.php index 6c8716e54..27ebd42cd 100644 --- a/app/Http/Controllers/Api/AccessoriesController.php +++ b/app/Http/Controllers/Api/AccessoriesController.php @@ -206,8 +206,6 @@ class AccessoriesController extends Controller /** * Gets a paginated collection for the select2 menus * - * @author [A. Gianotto] [] - * @since [v4.0.16] * @see \App\Http\Transformers\SelectlistTransformer * */ diff --git a/app/Http/Controllers/Api/ConsumablesController.php b/app/Http/Controllers/Api/ConsumablesController.php index a97f92771..5221a03b9 100644 --- a/app/Http/Controllers/Api/ConsumablesController.php +++ b/app/Http/Controllers/Api/ConsumablesController.php @@ -192,8 +192,6 @@ class ConsumablesController extends Controller /** * Gets a paginated collection for the select2 menus * - * @author [A. Gianotto] [] - * @since [v4.0.16] * @see \App\Http\Transformers\SelectlistTransformer * */ diff --git a/app/Http/Controllers/Api/LicensesController.php b/app/Http/Controllers/Api/LicensesController.php index 9defee8cd..49f0696d1 100644 --- a/app/Http/Controllers/Api/LicensesController.php +++ b/app/Http/Controllers/Api/LicensesController.php @@ -249,10 +249,7 @@ class LicensesController extends Controller /** * Gets a paginated collection for the select2 menus * - * @author [A. Gianotto] [] - * @since [v4.0.16] * @see \App\Http\Transformers\SelectlistTransformer - * */ public function selectlist(Request $request) { diff --git a/app/Http/Controllers/Api/PredefinedKitsController.php b/app/Http/Controllers/Api/PredefinedKitsController.php index 70d5c17a7..f84c86845 100644 --- a/app/Http/Controllers/Api/PredefinedKitsController.php +++ b/app/Http/Controllers/Api/PredefinedKitsController.php @@ -8,13 +8,14 @@ use App\Helpers\Helper; use App\Models\PredefinedKit; use App\Http\Transformers\PredefinedKitsTransformer; +/** + * @author [D. Minaev.] [] + */ class PredefinedKitsController extends Controller { /** * Display a listing of the resource. * - * @author [A. Gianotto] [] - * @since [v4.0] * @return \Illuminate\Http\Response */ public function index(Request $request) @@ -44,8 +45,6 @@ class PredefinedKitsController extends Controller /** * Store a newly created resource in storage. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ @@ -65,8 +64,6 @@ class PredefinedKitsController extends Controller /** * Display the specified resource. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param int $id * @return \Illuminate\Http\Response */ @@ -81,10 +78,8 @@ class PredefinedKitsController extends Controller /** * Update the specified resource in storage. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param \Illuminate\Http\Request $request - * @param int $id + * @param int $id kit id * @return \Illuminate\Http\Response */ public function update(Request $request, $id) @@ -103,8 +98,6 @@ class PredefinedKitsController extends Controller /** * Remove the specified resource from storage. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param int $id * @return \Illuminate\Http\Response */ @@ -128,8 +121,6 @@ class PredefinedKitsController extends Controller /** * Gets a paginated collection for the select2 menus * - * @author [A. Gianotto] [] - * @since [v4.0.16] * @see \App\Http\Transformers\SelectlistTransformer * */ @@ -154,8 +145,6 @@ class PredefinedKitsController extends Controller /** * Display the specified resource. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param int $id * @return \Illuminate\Http\Response */ @@ -168,10 +157,8 @@ class PredefinedKitsController extends Controller /** - * Display the specified resource. + * Store the specified resource. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param int $id * @return \Illuminate\Http\Response */ @@ -198,8 +185,6 @@ class PredefinedKitsController extends Controller /** * Update the specified resource in storage. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response @@ -220,8 +205,6 @@ class PredefinedKitsController extends Controller /** * Remove the specified resource from storage. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param int $kit_id * @return \Illuminate\Http\Response */ @@ -237,8 +220,6 @@ class PredefinedKitsController extends Controller /** * Display the specified resource. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param int $id * @return \Illuminate\Http\Response */ @@ -250,10 +231,8 @@ class PredefinedKitsController extends Controller } /** - * Display the specified resource. + * Store the specified resource. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param int $id * @return \Illuminate\Http\Response */ @@ -283,8 +262,6 @@ class PredefinedKitsController extends Controller /** * Update the specified resource in storage. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response @@ -305,8 +282,6 @@ class PredefinedKitsController extends Controller /** * Remove the specified resource from storage. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param int $kit_id * @return \Illuminate\Http\Response */ @@ -324,8 +299,6 @@ class PredefinedKitsController extends Controller /** * Display the specified resource. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param int $id * @return \Illuminate\Http\Response */ @@ -338,10 +311,8 @@ class PredefinedKitsController extends Controller /** - * Display the specified resource. + * Store the specified resource. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param int $id * @return \Illuminate\Http\Response */ @@ -368,8 +339,6 @@ class PredefinedKitsController extends Controller /** * Update the specified resource in storage. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response @@ -390,8 +359,6 @@ class PredefinedKitsController extends Controller /** * Remove the specified resource from storage. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param int $kit_id * @return \Illuminate\Http\Response */ @@ -408,8 +375,6 @@ class PredefinedKitsController extends Controller /** * Display the specified resource. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param int $id * @return \Illuminate\Http\Response */ @@ -422,10 +387,8 @@ class PredefinedKitsController extends Controller /** - * Display the specified resource. + * Store the specified resource. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param int $id * @return \Illuminate\Http\Response */ @@ -452,8 +415,6 @@ class PredefinedKitsController extends Controller /** * Update the specified resource in storage. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response @@ -474,8 +435,6 @@ class PredefinedKitsController extends Controller /** * Remove the specified resource from storage. * - * @author [A. Gianotto] [] - * @since [v4.0] * @param int $kit_id * @return \Illuminate\Http\Response */ diff --git a/app/Http/Controllers/Kits/CheckoutKitController.php b/app/Http/Controllers/Kits/CheckoutKitController.php index 36f0b6bda..0007372a4 100644 --- a/app/Http/Controllers/Kits/CheckoutKitController.php +++ b/app/Http/Controllers/Kits/CheckoutKitController.php @@ -10,7 +10,6 @@ use Illuminate\Support\Facades\DB; use App\Http\Controllers\Controller; use App\Http\Requests\ImageUploadRequest; use App\Models\Accessory; -use App\Models\SnipeItPivot; use Illuminate\Http\Request; use App\Http\Controllers\CheckInOutRequest; use App\Services\PredefinedKitCheckoutService; @@ -23,7 +22,7 @@ use App\Models\User; * This controller handles all access kits management: * list, add/remove/change * - * @version v2.0 + * @author [D. Minaev.] [] */ class CheckoutKitController extends Controller { @@ -31,37 +30,35 @@ class CheckoutKitController extends Controller public $kitService; use CheckInOutRequest; - - public function __construct(PredefinedKitCheckoutService $kitService) + public function __construct(PredefinedKitCheckoutService $kitService) { $this->kitService = $kitService; } - /** - * Show Bulk Checkout Page - * @return View View to checkout multiple assets - */ + * Show Bulk Checkout Page + * + * @author [D. Minaev.] [] + * @return View View to checkout + */ public function showCheckout($kit_id) { - // METODO: добавить больше проверок, тут ещё и модель и прочее что мне надо бу $this->authorize('checkout', Asset::class); $kit = PredefinedKit::findOrFail($kit_id); return view('kits/checkout')->with('kit', $kit); } - + /** - * Validate and process the new Predefined Kit data. - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @return Redirect - */ + * Validate and process the new Predefined Kit data. + * + * @author [D. Minaev.] [] + * @return Redirect + */ public function store(Request $request, $kit_id) { $user_id = e($request->get('user_id')); - if ( is_null($user = User::find( $user_id )) ) { + if (is_null($user = User::find($user_id))) { return redirect()->back()->with('error', trans('admin/users/message.user_not_found')); } @@ -69,7 +66,7 @@ class CheckoutKitController extends Controller $kit->id = $kit_id; $errors = $this->kitService->checkout($request, $kit, $user); - if( count($errors) > 0 ) { + if (count($errors) > 0) { return redirect()->back()->with('error', 'Checkout error')->with('error_messages', $errors); // TODO: trans } return redirect()->back()->with('success', 'Checkout was successfully'); // TODO: trans diff --git a/app/Http/Controllers/Kits/PredefinedKitsController.php b/app/Http/Controllers/Kits/PredefinedKitsController.php index d71d99a60..533d6d2cb 100644 --- a/app/Http/Controllers/Kits/PredefinedKitsController.php +++ b/app/Http/Controllers/Kits/PredefinedKitsController.php @@ -10,7 +10,6 @@ use Illuminate\Support\Facades\DB; use App\Http\Controllers\Controller; use App\Http\Requests\ImageUploadRequest; use App\Models\Accessory; -use App\Models\SnipeItPivot; use Illuminate\Http\Request; @@ -18,23 +17,26 @@ use Illuminate\Http\Request; * This controller handles all access kits management: * list, add/remove/change * - * @version v2.0 + * @author [D. Minaev] [] */ class PredefinedKitsController extends Controller { + /** + * @author [D. Minaev] [] + * @return \Illuminate\Contracts\View\View + * @throws \Illuminate\Auth\Access\AuthorizationException + */ public function index() { - //$this->authorize('index', PredefinedKit::class); + $this->authorize('index', PredefinedKit::class); return view('kits/index'); } /** - * Returns a form view to create a new asset maintenance. - * - * @see AssetMaintenancesController::postCreate() method that stores the data - * @author Vincent Sposato - * @version v1.0 - * @since [v1.8] + * Returns a form view to create a new kit. + * + * @author [D. Minaev] [] + * @throws \Illuminate\Auth\Access\AuthorizationException * @return mixed */ public function create() @@ -44,91 +46,69 @@ class PredefinedKitsController extends Controller } /** - * Validate and process the new Predefined Kit data. - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @return Redirect - */ + * Validate and process the new Predefined Kit data. + * + * @author [D. Minaev] [] + * @return Redirect + */ public function store(ImageUploadRequest $request) { $this->authorize('create', PredefinedKit::class); // Create a new Predefined Kit $kit = new PredefinedKit; - $kit->name = $request->input('name'); + $kit->name = $request->input('name'); - if(!$kit->save()) { + if (!$kit->save()) { return redirect()->back()->withInput()->withErrors($kit->getErrors()); } - // METODO: удалить - $model_ids = $request->input('models'); - if (!is_array($model_ids)) { - $model_ids = []; - } - $model_ids = array_filter($model_ids); - - $license_ids = $request->get('selected_licenses'); - if (!is_array($license_ids)) { - $license_ids = []; - } - $license_ids = array_filter($license_ids); - - $success = DB::transaction(function() use($kit, $model_ids, $license_ids) { - $ret = $kit->save(); - if($ret) { - $kit->models()->attach($model_ids); // MYTODO: проверить, что работает перед сохранением - $kit->licenses()->attach($license_ids); - } - return $ret; - }); - - if(!$success) { + $success = $kit->save(); + if (!$success) { return redirect()->back()->withInput()->withErrors($kit->getErrors()); } return redirect()->route("kits.index")->with('success', 'Kit was successfully created.'); // TODO: trans() } /** - * Returns a view containing the Predefined Kit edit form. - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $kit_id - * @return View - */ + * Returns a view containing the Predefined Kit edit form. + * + * @author [D. Minaev] [] + * @since [v1.0] + * @param int $kit_id + * @return View + */ public function edit($kit_id = null) { $this->authorize('update', PredefinedKit::class); if ($kit = PredefinedKit::find($kit_id)) { return view('kits/edit') - ->with('item', $kit) - ->with('models', $kit->models) - ->with('licenses', $kit->licenses); + ->with('item', $kit) + ->with('models', $kit->models) + ->with('licenses', $kit->licenses); } return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans } /** - * Validates and processes form data from the edit - * Predefined Kit form based on the kit ID passed. - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $kit_id - * @return Redirect - */ + * Validates and processes form data from the edit + * Predefined Kit form based on the kit ID passed. + * + * @author [D. Minaev] [] + * @since [v1.0] + * @param int $kit_id + * @return Redirect + */ public function update(ImageUploadRequest $request, $kit_id = null) { $this->authorize('update', PredefinedKit::class); // Check if the kit exists if (is_null($kit = PredefinedKit::find($kit_id))) { // Redirect to the kits management page - return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans } - $kit->name = $request->input('name'); - + $kit->name = $request->input('name'); + if ($kit->save()) { return redirect()->route("kits.index")->with('success', 'Kit was successfully updated'); // TODO: trans } @@ -136,14 +116,14 @@ class PredefinedKitsController extends Controller } /** - * Validate and delete the given Predefined Kit. - * Also delete all contained helping items - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $kit_id - * @return Redirect - */ + * Validate and delete the given Predefined Kit. + * Also delete all contained helping items + * + * @author [D. Minaev] [] + * @since [v1.0] + * @param int $kit_id + * @return Redirect + */ public function destroy($kit_id) { $this->authorize('delete', PredefinedKit::class); @@ -165,48 +145,32 @@ class PredefinedKitsController extends Controller } /** - * Get the kit information to present to the kit view page - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $modelId - * @return View - */ + * Get the kit information to present to the kit view page + * + * @author [D. Minaev] [] + * @since [v1.0] + * @param int $modelId + * @return View + */ public function show($kit_id = null) { - $this->authorize('view', PredefinedKit::class); - $kit = PredefinedKit::find($kit_id); - - if (isset($kit->id)) { - return view('kits/view', compact('kit')); - } - // Prepare the error message - $error = 'Kit does not exist.'; // TODO: trans - - // Redirect to the user management page - return redirect()->route('kits.index')->with('error', $error); + return $this->edit($kit_id); } - + /** - * Returns a view containing the Predefined Kit edit form. - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $kit_id - * @return View - */ + * Returns a view containing the Predefined Kit edit form. + * + * @author [D. Minaev] [] + * @param int $kit_id + * @return View + */ public function editModel($kit_id, $model_id) - { + { $this->authorize('update', PredefinedKit::class); - if ( ($kit = PredefinedKit::find($kit_id)) - && ($model = $kit->models()->find($model_id)) ) { - // $item = $model->pivot; - // $item->name1 = 'tesn1'; - // dd($item); - //dd($model->pivot); - // $item = $model->pivot; - + if (($kit = PredefinedKit::find($kit_id)) + && ($model = $kit->models()->find($model_id))) { + return view('kits/model-edit', [ 'kit' => $kit, 'model' => $model, @@ -217,19 +181,19 @@ class PredefinedKitsController extends Controller } /** - * Get the kit information to present to the kit view page - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $modelId - * @return View - */ - public function updateModel(Request $request, $kit_id, $model_id) { + * Get the kit information to present to the kit view page + * + * @author [D. Minaev] [] + * @param int $modelId + * @return View + */ + public function updateModel(Request $request, $kit_id, $model_id) + { $this->authorize('update', PredefinedKit::class); if (is_null($kit = PredefinedKit::find($kit_id))) { // Redirect to the kits management page - return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans } $validator = \Validator::make($request->all(), $kit->makeModelRules($model_id)); @@ -243,23 +207,23 @@ class PredefinedKitsController extends Controller $pivot->model_id = $request->input('model_id'); $pivot->quantity = $request->input('quantity'); $pivot->save(); - + return redirect()->route('kits.edit', $kit_id)->with('success', 'Model updated successfully.'); // TODO: trans } /** - * Remove the model from set - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $modelId - * @return View - */ - public function detachModel($kit_id, $model_id) { + * Remove the model from set + * + * @author [D. Minaev] [] + * @param int $modelId + * @return View + */ + public function detachModel($kit_id, $model_id) + { $this->authorize('update', PredefinedKit::class); if (is_null($kit = PredefinedKit::find($kit_id))) { // Redirect to the kits management page - return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans } // Delete childs @@ -270,24 +234,23 @@ class PredefinedKitsController extends Controller } /** - * Returns a view containing attached license edit form. - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $kit_id - * @param int $licenseId - * @return View - */ + * Returns a view containing attached license edit form. + * + * @author [D. Minaev] [] + * @param int $kit_id + * @param int $license_id + * @return View + */ public function editLicense($kit_id, $license_id) - { + { $this->authorize('update', PredefinedKit::class); - if( !($kit = PredefinedKit::find($kit_id)) ) { + if (!($kit = PredefinedKit::find($kit_id))) { return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans } - if( !($license = $kit->licenses()->find($license_id)) ) { + if (!($license = $kit->licenses()->find($license_id))) { return redirect()->route('kits.index')->with('error', 'License does not exist'); // TODO: trans } - + return view('kits/license-edit', [ 'kit' => $kit, 'license' => $license, @@ -296,20 +259,20 @@ class PredefinedKitsController extends Controller } /** - * Update attached licese - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $kit_id - * @param int $licenseId - * @return View - */ - public function updateLicense(Request $request, $kit_id, $license_id) { + * Update attached licese + * + * @author [D. Minaev] [] + * @param int $kit_id + * @param int $license_id + * @return View + */ + public function updateLicense(Request $request, $kit_id, $license_id) + { $this->authorize('update', PredefinedKit::class); if (is_null($kit = PredefinedKit::find($kit_id))) { // Redirect to the kits management page - return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans } $validator = \Validator::make($request->all(), $kit->makeLicenseRules($license_id)); @@ -323,23 +286,24 @@ class PredefinedKitsController extends Controller $pivot->license_id = $request->input('license_id'); $pivot->quantity = $request->input('quantity'); $pivot->save(); - + return redirect()->route('kits.edit', $kit_id)->with('success', 'License updated successfully.'); // TODO: trans } /** - * - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $licenseId - * @return View - */ - public function detachLicense($kit_id, $license_id) { + * Remove the license from set + * + * @author [D. Minaev] [] + * @param int $kit_id + * @param int $license_id + * @return View + */ + public function detachLicense($kit_id, $license_id) + { $this->authorize('update', PredefinedKit::class); if (is_null($kit = PredefinedKit::find($kit_id))) { // Redirect to the kits management page - return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans } // Delete childs @@ -349,26 +313,25 @@ class PredefinedKitsController extends Controller return redirect()->route('kits.edit', $kit_id)->with('success', 'License was successfully detached'); // TODO: trans } - + /** - * Returns a view containing attached accessory edit form. - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $kit_id - * @param int $accessoryId - * @return View - */ + * Returns a view containing attached accessory edit form. + * + * @author [D. Minaev] [] + * @param int $kit_id + * @param int $accessoryId + * @return View + */ public function editAccessory($kit_id, $accessory_id) - { + { $this->authorize('update', PredefinedKit::class); - if( !($kit = PredefinedKit::find($kit_id)) ) { + if (!($kit = PredefinedKit::find($kit_id))) { return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans } - if( !($accessory = $kit->accessories()->find($accessory_id)) ) { + if (!($accessory = $kit->accessories()->find($accessory_id))) { return redirect()->route('kits.index')->with('error', 'Accessory does not exist'); // TODO: trans } - + return view('kits/accessory-edit', [ 'kit' => $kit, 'accessory' => $accessory, @@ -377,20 +340,20 @@ class PredefinedKitsController extends Controller } /** - * Update attached accessory - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $kit_id - * @param int $accessoryId - * @return View - */ - public function updateAccessory(Request $request, $kit_id, $accessory_id) { + * Update attached accessory + * + * @author [D. Minaev] [] + * @param int $kit_id + * @param int $accessory_id + * @return View + */ + public function updateAccessory(Request $request, $kit_id, $accessory_id) + { $this->authorize('update', PredefinedKit::class); if (is_null($kit = PredefinedKit::find($kit_id))) { // Redirect to the kits management page - return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans } $validator = \Validator::make($request->all(), $kit->makeAccessoryRules($accessory_id)); @@ -404,23 +367,23 @@ class PredefinedKitsController extends Controller $pivot->accessory_id = $request->input('accessory_id'); $pivot->quantity = $request->input('quantity'); $pivot->save(); - + return redirect()->route('kits.edit', $kit_id)->with('success', 'Accessory updated successfully.'); // TODO: trans } /** - * - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $accessoryId - * @return View - */ - public function detachAccessory($kit_id, $accessory_id) { + * Remove the accessory from set + * + * @author [D. Minaev] [] + * @param int $accessory_id + * @return View + */ + public function detachAccessory($kit_id, $accessory_id) + { $this->authorize('update', PredefinedKit::class); if (is_null($kit = PredefinedKit::find($kit_id))) { // Redirect to the kits management page - return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans } // Delete childs @@ -431,24 +394,23 @@ class PredefinedKitsController extends Controller } /** - * Returns a view containing attached consumable edit form. - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $kit_id - * @param int $consumableId - * @return View - */ + * Returns a view containing attached consumable edit form. + * + * @author [D. Minaev] [] + * @param int $kit_id + * @param int $consumable_id + * @return View + */ public function editConsumable($kit_id, $consumable_id) - { + { $this->authorize('update', PredefinedKit::class); - if( !($kit = PredefinedKit::find($kit_id)) ) { + if (!($kit = PredefinedKit::find($kit_id))) { return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans } - if( !($consumable = $kit->consumables()->find($consumable_id)) ) { + if (!($consumable = $kit->consumables()->find($consumable_id))) { return redirect()->route('kits.index')->with('error', 'Consumable does not exist'); // TODO: trans } - + return view('kits/consumable-edit', [ 'kit' => $kit, 'consumable' => $consumable, @@ -457,20 +419,20 @@ class PredefinedKitsController extends Controller } /** - * Update attached consumable - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $kit_id - * @param int $consumableId - * @return View - */ - public function updateConsumable(Request $request, $kit_id, $consumable_id) { + * Update attached consumable + * + * @author [D. Minaev] [] + * @param int $kit_id + * @param int $consumableId + * @return View + */ + public function updateConsumable(Request $request, $kit_id, $consumable_id) + { $this->authorize('update', PredefinedKit::class); if (is_null($kit = PredefinedKit::find($kit_id))) { // Redirect to the kits management page - return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans } $validator = \Validator::make($request->all(), $kit->makeConsumableRules($consumable_id)); @@ -484,23 +446,23 @@ class PredefinedKitsController extends Controller $pivot->consumable_id = $request->input('consumable_id'); $pivot->quantity = $request->input('quantity'); $pivot->save(); - + return redirect()->route('kits.edit', $kit_id)->with('success', 'Consumable updated successfully.'); // TODO: trans } /** - * - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param int $consumableId - * @return View - */ - public function detachConsumable($kit_id, $consumable_id) { + * Remove the consumable from set + * + * @author [D. Minaev] [] + * @param int $consumable_id + * @return View + */ + public function detachConsumable($kit_id, $consumable_id) + { $this->authorize('update', PredefinedKit::class); if (is_null($kit = PredefinedKit::find($kit_id))) { // Redirect to the kits management page - return redirect()->route('kits.index')->with('error','Kit does not exist'); // TODO: trans + return redirect()->route('kits.index')->with('error', 'Kit does not exist'); // TODO: trans } // Delete childs @@ -509,44 +471,4 @@ class PredefinedKitsController extends Controller // Redirect to the kit management page return redirect()->route('kits.edit', $kit_id)->with('success', 'Consumable was successfully detached'); // TODO: trans } - - /** - * Returns true if a fieldset is set, 'add default values' is ticked and if - * any default values were entered into the form. - * - * @param array $input - * @return boolean - */ - private function shouldAddDefaultValues(array $input) - { - return !empty($input['add_default_values']) - && !empty($input['default_values']) - && !empty($input['custom_fieldset']); - } - - /** - * Adds default values to a accessory (as long as they are truthy) - * - * @param AssetModel $model - * @param array $defaultValues - * @return void - */ - private function assignCustomFieldsDefaultValues(AssetModel $model, array $defaultValues) - { - foreach ($defaultValues as $customFieldId => $defaultValue) { - if ($defaultValue) { - $model->defaultValues()->attach($customFieldId, ['default_value' => $defaultValue]); - } - } - } - - /** - * Removes all default values - * - * @return void - */ - private function removeCustomFieldsDefaultValues(AssetModel $model) - { - $model->defaultValues()->detach(); - } } diff --git a/app/Http/Transformers/PredefinedKitsTransformer.php b/app/Http/Transformers/PredefinedKitsTransformer.php index 4596f3e74..8ff4664f4 100644 --- a/app/Http/Transformers/PredefinedKitsTransformer.php +++ b/app/Http/Transformers/PredefinedKitsTransformer.php @@ -4,10 +4,14 @@ namespace App\Http\Transformers; use App\Models\PredefinedKit; use Illuminate\Database\Eloquent\Collection; use Gate; -use App\Helpers\Helper; -use Illuminate\Support\Facades\Storage; use App\Models\SnipeModel; +/** + * transforms collection of models to array with simple typres + * + * @author [D. Minaev] [] + * @return array + */ class PredefinedKitsTransformer { @@ -39,6 +43,10 @@ class PredefinedKitsTransformer return $array; } + /** + * transform collection of any elemets attached to kit + * @return array + */ public function transformElements(Collection $elements, $total) { $array = array(); foreach ($elements as $element) { diff --git a/app/Models/PredefinedKit.php b/app/Models/PredefinedKit.php index 9044945ec..81169aa75 100644 --- a/app/Models/PredefinedKit.php +++ b/app/Models/PredefinedKit.php @@ -11,11 +11,9 @@ use Watson\Validating\ValidatingTrait; use Illuminate\Validation\Rule; /** - * Model for Categories. Categories are a higher-level group - * than Asset Models, and handle things like whether or not - * to require acceptance from the user, whether or not to - * send a EULA to the user, etc. - * + * Model for predefined kits. + * + * @author [D. Minaev.] [] * @version v1.0 */ class PredefinedKit extends SnipeModel @@ -25,61 +23,79 @@ class PredefinedKit extends SnipeModel protected $table = 'kits'; /** - * Category validation rules - */ + * Category validation rules + */ public $rules = array( - 'name' => 'required|min:1|max:255|unique' + 'name' => 'required|min:1|max:255|unique' ); use ValidatingTrait; public $modelRules = [ 'model_id' => 'required|exists:models,id', - // 'model_id' => [ - // 'required', - // 'exists:models,id', - // Rule::unique('kits_models')->where('model_id', $model_id)->whereNot('kit_id', $this->id) - // ], 'quantity' => 'required|integer|min:1', 'pivot_id' => 'integer|exists:kits_models,id' ]; - public function makeModelRules($model_id, $new = false) { - // return [ - // // 'model_id' => 'required|exists:models,id', - // 'model_id' => [ - // 'required', - // 'exists:models,id', - // Rule::unique('kits_models')->whereNot('model_id', $model_id)->where('kit_id', $this->id) - // ], - // 'quantity' => 'required|integer|min:1', - // 'pivot_id' => 'integer|exists:kits_models,id' - // ]; + /** + * this rules use in edit an attached asset model form + * see PredefinedKit::_makeRuleHelper function for details + * @param int $model_id + * @param bool $new = true if append a new element to kit + */ + public function makeModelRules($model_id, $new = false) + { + return $this->_makeRuleHelper('models', 'kits_models', 'model_id', $model_id, $new); + } + + /** + * this rules use in edit an attached license form + * see PredefinedKit::_makeRuleHelper function for details + * @param int $license_id + * @param bool $new = true if append a new element to kit + */ + public function makeLicenseRules($license_id, $new = false) + { return $this->_makeRuleHelper('licenses', 'kits_licenses', 'license_id', $license_id, $new); } - public function makeLicenseRules($license_id, $new = false) { - return $this->_makeRuleHelper('licenses', 'kits_licenses', 'license_id', $license_id, $new); + /** + * this rules use in edit an attached accessory form + * see PredefinedKit::_makeRuleHelper function for details + * @param int $accessoriy_id + * @param bool $new = true if append a new element to kit + */ + public function makeAccessoriesRules($accessory_id, $new = false) + { + return $this->_makeRuleHelper('accessories', 'kits_accessories', 'accessory_id', $accessory_id, $new); } - public function makeAccessoriesRules($accessoriy_id, $new = false) { - return $this->_makeRuleHelper('accessories', 'kits_accessories', 'accessoriy_id', $accessoriy_id, $new); - } - - public function makeConsumablesRules($consumable_id, $new = false) { + /** + * this rules use in edit an attached consumable form + * see PredefinedKit::_makeRuleHelper function for details + * @param int $consumable_id + * @param bool $new = true if append a new element to kit + */ + public function makeConsumablesRules($consumable_id, $new = false) + { return $this->_makeRuleHelper('consumables', 'kits_consumables', 'consumable_id', $consumable_id, $new); } - protected function _makeRuleHelper($table, $pivot_table, $pivot_elem_key, $element_id, $new) { - // return [ - // $pivot_elem_key => [ - // 'required', - // "exists:$table,id", - // Rule::unique($pivot_table)->whereNot($pivot_elem_key, $element_id)->where('kit_id', $this->id) - // ], - // 'quantity' => 'required|integer|min:1', - // 'pivot_id' => "integer|exists:$pivot_table,id" - // ]; + /** + * Make rules for validation kit attached elements via Illuminate\Validation\Rule + * checks: + * uniqueness of the record in table for this kit + * existence of record in table + * and simple types check + * @param string $table element table name + * @param string $pivot_table kit+element table name + * @param string $pivot_elem_key element key name inside pivot table + * @param int $element_id + * @param bool $new = true if append a new element to kit + * @return array + */ + protected function _makeRuleHelper($table, $pivot_table, $pivot_elem_key, $element_id, $new) + { $rule = [ $pivot_elem_key => [ 'required', @@ -88,20 +104,13 @@ class PredefinedKit extends SnipeModel ], 'quantity' => 'required|integer|min:1' ]; - if(!$new) { + if (!$new) { $rule['pivot_id'] = "integer|exists:$pivot_table,id"; - + } return $rule; } - // public $licenseRules = [ - // 'license_id' => 'required|exists:licenses,id', - // 'quantity' => 'required|integer|min:1', - // 'pivot_id' => 'integer|exists:kits_licenses,id' - // ]; - - /** * The attributes that are mass assignable. * @@ -112,16 +121,16 @@ class PredefinedKit extends SnipeModel ]; use Searchable; - + /** - * The attributes that should be included when searching the model. + * The attributes that should be included when searching the kit. * * @var array */ protected $searchableAttributes = ['name']; /** - * The relations and their attributes that should be included when searching the model. + * The relations and their attributes that should be included when searching the kit. * * @var array */ @@ -130,9 +139,6 @@ class PredefinedKit extends SnipeModel /** * Establishes the kits -> models relationship - * - * @author [A. Gianotto] [] - * @since [v2.0] * @return \Illuminate\Database\Eloquent\Relations\Relation */ public function models() @@ -147,9 +153,6 @@ class PredefinedKit extends SnipeModel /** * Establishes the kits -> licenses relationship - * - * @author [A. Gianotto] [] - * @since [v4.3] * @return \Illuminate\Database\Eloquent\Relations\Relation */ public function licenses() @@ -159,9 +162,6 @@ class PredefinedKit extends SnipeModel /** * Establishes the kits -> licenses relationship - * - * @author [A. Gianotto] [] - * @since [v4.3] * @return \Illuminate\Database\Eloquent\Relations\Relation */ public function consumables() @@ -170,12 +170,9 @@ class PredefinedKit extends SnipeModel } /** - * Establishes the kits -> licenses relationship - * - * @author [A. Gianotto] [] - * @since [v4.3] - * @return \Illuminate\Database\Eloquent\Relations\Relation - */ + * Establishes the kits -> licenses relationship + * @return \Illuminate\Database\Eloquent\Relations\Relation + */ public function accessories() { return $this->belongsToMany('\App\Models\Accessory', 'kits_accessories', 'kit_id', 'accessory_id')->withPivot('id', 'quantity'); diff --git a/app/Models/SnipeItPivot.php b/app/Models/SnipeItPivot.php deleted file mode 100644 index 143185420..000000000 --- a/app/Models/SnipeItPivot.php +++ /dev/null @@ -1,11 +0,0 @@ - true, "sortable" => true, "title" => 'Name', // TODO: trans - "formatter" => "accessoriesLinkFormatter" // MYTODO: check + "formatter" => "accessoriesLinkFormatter" ], [ "field" => "quantity", "searchable" => false, @@ -207,7 +207,7 @@ class PredefinedKitPresenter extends Presenter "sortable" => false, "switchable" => false, "title" => trans('table.actions'), - "formatter" => "kits_accessoriesActionsFormatter", // MYTODO: check + "formatter" => "kits_accessoriesActionsFormatter", ] ]; @@ -216,7 +216,7 @@ class PredefinedKitPresenter extends Presenter /** - * Json Column Layout for bootstrap table + * Json Column Layout for bootstrap table of kit consumables * @return string */ public static function dataTableConsumables() @@ -248,7 +248,7 @@ class PredefinedKitPresenter extends Presenter "searchable" => true, "sortable" => true, "title" => 'Name', // TODO: trans - "formatter" => "consumablesLinkFormatter" // MYTODO: check + "formatter" => "consumablesLinkFormatter" ], [ "field" => "quantity", "searchable" => false, @@ -260,7 +260,7 @@ class PredefinedKitPresenter extends Presenter "sortable" => false, "switchable" => false, "title" => trans('table.actions'), - "formatter" => "kits_consumablesActionsFormatter", // MYTODO: check + "formatter" => "kits_consumablesActionsFormatter", ] ]; @@ -278,7 +278,6 @@ class PredefinedKitPresenter extends Presenter } /** - * Link to this kit Name * @return string */ public function fullName() diff --git a/app/Services/PredefinedKitCheckoutService.php b/app/Services/PredefinedKitCheckoutService.php index decdb1db1..096d80686 100644 --- a/app/Services/PredefinedKitCheckoutService.php +++ b/app/Services/PredefinedKitCheckoutService.php @@ -12,12 +12,18 @@ use Illuminate\Support\Facades\DB; use App\Events\CheckoutableCheckedOut; - +/** + * Class incapsulates checkout logic for reuse in different controllers + * @author [D. Minaev.] [] + */ class PredefinedKitCheckoutService { use AuthorizesRequests; /** - * @return array [string_error1, string_error2...] + * @param Request $request, this function works with fields: checkout_at, expected_checkin, note + * @param PredefinedKit $kit kit for checkout + * @param User $user checkout target + * @return array Empty array if all ok, else [string_error1, string_error2...] */ public function checkout(Request $request, PredefinedKit $kit, User $user) { try { diff --git a/database/migrations/2018_10_18_191228_add_kits_licenses_table.php b/database/migrations/2018_10_18_191228_add_kits_licenses_table.php index b600cad3a..44ca2c0a2 100644 --- a/database/migrations/2018_10_18_191228_add_kits_licenses_table.php +++ b/database/migrations/2018_10_18_191228_add_kits_licenses_table.php @@ -20,8 +20,6 @@ class AddKitsLicensesTable extends Migration { $table->integer('quantity')->default(1); $table->timestamps(); }); - - } /** From 16bb784e7890748ebad8cb8030a682e550afd09e Mon Sep 17 00:00:00 2001 From: Dmitrii Minaev Date: Thu, 28 Feb 2019 01:37:58 +0300 Subject: [PATCH 14/14] Codestyle & bug fixes --- .../Api/PredefinedKitsController.php | 32 +-- .../Kits/PredefinedKitsController.php | 6 +- app/Models/PredefinedKit.php | 8 +- app/Services/PredefinedKitCheckoutService.php | 188 ++++++++++-------- resources/views/kits/accessory-edit.blade.php | 37 +--- .../views/kits/consumable-edit.blade.php | 36 +--- resources/views/kits/license-edit.blade.php | 35 ---- resources/views/kits/model-edit.blade.php | 35 ---- .../forms/edit/accessory-select.blade.php | 2 +- .../forms/edit/consumable-select.blade.php | 4 +- 10 files changed, 129 insertions(+), 254 deletions(-) diff --git a/app/Http/Controllers/Api/PredefinedKitsController.php b/app/Http/Controllers/Api/PredefinedKitsController.php index f84c86845..6cf0f7bca 100644 --- a/app/Http/Controllers/Api/PredefinedKitsController.php +++ b/app/Http/Controllers/Api/PredefinedKitsController.php @@ -186,13 +186,13 @@ class PredefinedKitsController extends Controller * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request - * @param int $id + * @param int $kit_id * @return \Illuminate\Http\Response */ public function updateLicense(Request $request, $kit_id, $license_id) { $this->authorize('update', PredefinedKit::class); - $kit = PredefinedKit::findOrFail($id); + $kit = PredefinedKit::findOrFail($kit_id); $quantity = $request->input('quantity', 1); if( $quantity < 1) { $quantity = 1; @@ -211,7 +211,7 @@ class PredefinedKitsController extends Controller public function detachLicense($kit_id, $license_id) { $this->authorize('update', PredefinedKit::class); - $kit = PredefinedKit::findOrFail($id); + $kit = PredefinedKit::findOrFail($kit_id); $kit->licenses()->detach($license_id); return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Delete was successfull')); // TODO: trans @@ -220,7 +220,7 @@ class PredefinedKitsController extends Controller /** * Display the specified resource. * - * @param int $id + * @param int $kit_id * @return \Illuminate\Http\Response */ public function indexModels($kit_id) { @@ -263,13 +263,13 @@ class PredefinedKitsController extends Controller * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request - * @param int $id + * @param int $kit_id * @return \Illuminate\Http\Response */ public function updateModel(Request $request, $kit_id, $model_id) { $this->authorize('update', PredefinedKit::class); - $kit = PredefinedKit::findOrFail($id); + $kit = PredefinedKit::findOrFail($kit_id); $quantity = $request->input('quantity', 1); if( $quantity < 1) { $quantity = 1; @@ -288,7 +288,7 @@ class PredefinedKitsController extends Controller public function detachModel($kit_id, $model_id) { $this->authorize('update', PredefinedKit::class); - $kit = PredefinedKit::findOrFail($id); + $kit = PredefinedKit::findOrFail($kit_id); $kit->models()->detach($model_id); return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Delete was successfull')); // TODO: trans @@ -299,7 +299,7 @@ class PredefinedKitsController extends Controller /** * Display the specified resource. * - * @param int $id + * @param int $kit_id * @return \Illuminate\Http\Response */ public function indexConsumables($kit_id) { @@ -340,13 +340,13 @@ class PredefinedKitsController extends Controller * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request - * @param int $id + * @param int $kit_id * @return \Illuminate\Http\Response */ public function updateConsumable(Request $request, $kit_id, $consumable_id) { $this->authorize('update', PredefinedKit::class); - $kit = PredefinedKit::findOrFail($id); + $kit = PredefinedKit::findOrFail($kit_id); $quantity = $request->input('quantity', 1); if( $quantity < 1) { $quantity = 1; @@ -365,7 +365,7 @@ class PredefinedKitsController extends Controller public function detachConsumable($kit_id, $consumable_id) { $this->authorize('update', PredefinedKit::class); - $kit = PredefinedKit::findOrFail($id); + $kit = PredefinedKit::findOrFail($kit_id); $kit->consumables()->detach($consumable_id); return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Delete was successfull')); // TODO: trans @@ -375,7 +375,7 @@ class PredefinedKitsController extends Controller /** * Display the specified resource. * - * @param int $id + * @param int $kit_id * @return \Illuminate\Http\Response */ public function indexAccessories($kit_id) { @@ -389,7 +389,7 @@ class PredefinedKitsController extends Controller /** * Store the specified resource. * - * @param int $id + * @param int $kit_id * @return \Illuminate\Http\Response */ public function storeAccessory(Request $request, $kit_id) @@ -416,13 +416,13 @@ class PredefinedKitsController extends Controller * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request - * @param int $id + * @param int $kit_id * @return \Illuminate\Http\Response */ public function updateAccessory(Request $request, $kit_id, $accessory_id) { $this->authorize('update', PredefinedKit::class); - $kit = PredefinedKit::findOrFail($id); + $kit = PredefinedKit::findOrFail($kit_id); $quantity = $request->input('quantity', 1); if( $quantity < 1) { $quantity = 1; @@ -441,7 +441,7 @@ class PredefinedKitsController extends Controller public function detachAccessory($kit_id, $accessory_id) { $this->authorize('update', PredefinedKit::class); - $kit = PredefinedKit::findOrFail($id); + $kit = PredefinedKit::findOrFail($kit_id); $kit->accessories()->detach($accessory_id); return response()->json(Helper::formatStandardApiResponse('success', $kit, 'Delete was successfull')); // TODO: trans diff --git a/app/Http/Controllers/Kits/PredefinedKitsController.php b/app/Http/Controllers/Kits/PredefinedKitsController.php index 533d6d2cb..2ae5ca011 100644 --- a/app/Http/Controllers/Kits/PredefinedKitsController.php +++ b/app/Http/Controllers/Kits/PredefinedKitsController.php @@ -76,7 +76,7 @@ class PredefinedKitsController extends Controller * @param int $kit_id * @return View */ - public function edit($kit_id = null) + public function edit($kit_id=null) { $this->authorize('update', PredefinedKit::class); if ($kit = PredefinedKit::find($kit_id)) { @@ -98,7 +98,7 @@ class PredefinedKitsController extends Controller * @param int $kit_id * @return Redirect */ - public function update(ImageUploadRequest $request, $kit_id = null) + public function update(ImageUploadRequest $request, $kit_id=null) { $this->authorize('update', PredefinedKit::class); // Check if the kit exists @@ -152,7 +152,7 @@ class PredefinedKitsController extends Controller * @param int $modelId * @return View */ - public function show($kit_id = null) + public function show($kit_id=null) { return $this->edit($kit_id); } diff --git a/app/Models/PredefinedKit.php b/app/Models/PredefinedKit.php index 81169aa75..71b7340d3 100644 --- a/app/Models/PredefinedKit.php +++ b/app/Models/PredefinedKit.php @@ -43,7 +43,7 @@ class PredefinedKit extends SnipeModel * @param int $model_id * @param bool $new = true if append a new element to kit */ - public function makeModelRules($model_id, $new = false) + public function makeModelRules($model_id, $new=false) { return $this->_makeRuleHelper('models', 'kits_models', 'model_id', $model_id, $new); } @@ -54,7 +54,7 @@ class PredefinedKit extends SnipeModel * @param int $license_id * @param bool $new = true if append a new element to kit */ - public function makeLicenseRules($license_id, $new = false) + public function makeLicenseRules($license_id, $new=false) { return $this->_makeRuleHelper('licenses', 'kits_licenses', 'license_id', $license_id, $new); } @@ -65,7 +65,7 @@ class PredefinedKit extends SnipeModel * @param int $accessoriy_id * @param bool $new = true if append a new element to kit */ - public function makeAccessoriesRules($accessory_id, $new = false) + public function makeAccessoryRules($accessory_id, $new=false) { return $this->_makeRuleHelper('accessories', 'kits_accessories', 'accessory_id', $accessory_id, $new); } @@ -76,7 +76,7 @@ class PredefinedKit extends SnipeModel * @param int $consumable_id * @param bool $new = true if append a new element to kit */ - public function makeConsumablesRules($consumable_id, $new = false) + public function makeConsumableRules($consumable_id, $new=false) { return $this->_makeRuleHelper('consumables', 'kits_consumables', 'consumable_id', $consumable_id, $new); } diff --git a/app/Services/PredefinedKitCheckoutService.php b/app/Services/PredefinedKitCheckoutService.php index 096d80686..abc95b31a 100644 --- a/app/Services/PredefinedKitCheckoutService.php +++ b/app/Services/PredefinedKitCheckoutService.php @@ -25,27 +25,28 @@ class PredefinedKitCheckoutService * @param User $user checkout target * @return array Empty array if all ok, else [string_error1, string_error2...] */ - public function checkout(Request $request, PredefinedKit $kit, User $user) { + public function checkout(Request $request, PredefinedKit $kit, User $user) + { try { // Check if the user exists - if (is_null($user) ) { + if (is_null($user)) { return [trans('admin/users/message.user_not_found')]; } $errors = []; $assets_to_add = $this->getAssetsToAdd($kit, $user, $errors); - $license_seats_to_add = $this->getLicenseSeatsToAdd($kit, $user, $errors); - $consumables_to_add = $this->getConsumablesToAdd($kit, $user, $errors); - $accessories_to_add = $this->getAccessoriesToAdd($kit, $user, $errors); + $license_seats_to_add = $this->getLicenseSeatsToAdd($kit, $errors); + $consumables_to_add = $this->getConsumablesToAdd($kit, $errors); + $accessories_to_add = $this->getAccessoriesToAdd($kit, $errors); - if( count($errors) > 0 ) { + if (count($errors) > 0) { return $errors; } $checkout_at = date("Y-m-d H:i:s"); - if (($request->filled('checkout_at')) && ($request->get('checkout_at')!= date("Y-m-d"))) { + if (($request->filled('checkout_at')) && ($request->get('checkout_at') != date("Y-m-d"))) { $checkout_at = $request->get('checkout_at'); } @@ -58,7 +59,93 @@ class PredefinedKitCheckoutService $note = e($request->get('note')); - $errors = DB::transaction( + $errors = $this->saveToDb($user, $admin, $checkout_at, $expected_checkin, $errors, $assets_to_add, $license_seats_to_add, $consumables_to_add, $accessories_to_add, $note); + return $errors; + } catch (ModelNotFoundException $e) { + return [$e->getMessage()]; + } catch (CheckoutNotAllowed $e) { + return [$e->getMessage()]; + } + } + + protected function getAssetsToAdd($kit, $user, &$errors) + { + $models = $kit->models() + ->with(['assets' => function ($hasMany) { + $hasMany->RTD(); + }]) + ->get(); + $assets_to_add = []; + foreach ($models as $model) { + $assets = $model->assets; + $quantity = $model->pivot->quantity; + foreach ($assets as $asset) { + + if ( + $asset->availableForCheckout() + && !$asset->is($user) + ) { + + $this->authorize('checkout', $asset); + $quantity -= 1; + $assets_to_add[] = $asset; + if ($quantity <= 0) { + break; + } + } + } + if ($quantity > 0) { + $errors[] = "Don't have available assets for model " . $model->name . '. Need ' . $model->pivot->quantity . ' assets.'; // TODO: trans + } + } + + return $assets_to_add; + } + + protected function getLicenseSeatsToAdd($kit, &$errors) + { + $seats_to_add = []; + $licenses = $kit->licenses() + ->with('freeSeats') + ->get(); + foreach ($licenses as $license) { + $quantity = $license->pivot->quantity; + if ($quantity > count($license->freeSeats)) { + $errors[] = "Don't have free seats for license " . $license->name . '. Need ' . $quantity . ' seats.'; // TODO: trans + } + for ($i = 0; $i < $quantity; $i++) { + $seats_to_add[] = $license->freeSeats[$i]; + } + } + return $seats_to_add; + } + + protected function getConsumablesToAdd($kit, &$errors) + { + // $consumables = $kit->consumables()->withCount('consumableAssignments as consumable_assignments_count')->get(); + $consumables = $kit->consumables()->with('users')->get(); + foreach ($consumables as $consumable) { + if ($consumable->numRemaining() < $consumable->pivot->quantity) { + $errors[] = "Don't have available consumable " . $consumable->name . '. Need ' . $consumable->pivot->quantity; // TODO: trans + } + } + return $consumables; + } + + protected function getAccessoriesToAdd($kit, &$errors) + { + $accessories = $kit->accessories()->with('users')->get(); + foreach ($accessories as $accossory) { + if ($accossory->numRemaining() < $accossory->pivot->quantity) { + $errors[] = "Don't have available accossory " . $accossory->name . '. Need ' . $accossory->pivot->quantity; // TODO: trans + } + } + return $accessories; + } + + protected function saveToDb($user, $admin, $checkout_at, $expected_checkin, $errors, $assets_to_add, $license_seats_to_add, $consumables_to_add, $accessories_to_add, $note) + { + $errors = DB::transaction( function () use ($user, $admin, $checkout_at, $expected_checkin, $errors, $assets_to_add, $license_seats_to_add, $consumables_to_add, $accessories_to_add, $note) { // assets foreach ($assets_to_add as $asset) { @@ -74,13 +161,12 @@ class PredefinedKitCheckoutService $licenseSeat->assigned_to = $user->id; if ($licenseSeat->save()) { event(new CheckoutableCheckedOut($licenseSeat, $user, $admin, $note)); - } - else { - $errors []= 'Something went wrong saving a license seat'; + } else { + $errors[] = 'Something went wrong saving a license seat'; } } // consumables - foreach($consumables_to_add as $consumable) { + foreach ($consumables_to_add as $consumable) { $consumable->assigned_to = $user->id; $consumable->users()->attach($consumable->id, [ 'consumable_id' => $consumable->id, @@ -90,7 +176,7 @@ class PredefinedKitCheckoutService event(new CheckoutableCheckedOut($consumable, $user, $admin, $note)); } //accessories - foreach($accessories_to_add as $accessory) { + foreach ($accessories_to_add as $accessory) { $accessory->assigned_to = $user->id; $accessory->users()->attach($accessory->id, [ 'accessory_id' => $accessory->id, @@ -100,81 +186,9 @@ class PredefinedKitCheckoutService event(new CheckoutableCheckedOut($accessory, $user, $admin, $note)); } return $errors; - }); - - return $errors; - - } catch (ModelNotFoundException $e) { - return [$e->getMessage()]; - } catch (CheckoutNotAllowed $e) { - return [$e->getMessage()]; - } - } - - protected function getAssetsToAdd($kit, $user, &$errors) { - $models = $kit->models() - ->with( ['assets' => function($hasMany) { $hasMany->RTD(); }] ) - ->get(); - $assets_to_add = []; - foreach($models as $model) { - $assets = $model->assets; - $quantity = $model->pivot->quantity; - foreach($assets as $asset) { - - if ($asset->availableForCheckout() - && !$asset->is($user)) { - - $this->authorize('checkout', $asset); - $quantity -= 1; - $assets_to_add []= $asset; - if($quantity <= 0) { - break; - } - } } - if($quantity > 0) { - $errors []= "Don't have available assets for model " . $model->name . '. Need ' . $model->pivot->quantity . ' assets.'; // TODO: trans - } - } + ); - return $assets_to_add; - } - - protected function getLicenseSeatsToAdd($kit, $user, &$errors) { - $seats_to_add = []; - $licenses = $kit->licenses() - ->with('freeSeats') - ->get(); - foreach($licenses as $license) { - $quantity = $license->pivot->quantity; - if( $quantity > count($license->freeSeats) ) { - $errors []= "Don't have free seats for license " . $license->name . '. Need ' . $quantity . ' seats.'; // TODO: trans - } - for($i=0; $i < $quantity; $i++) { - $seats_to_add []= $license->freeSeats[$i]; - } - } - return $seats_to_add; - } - - protected function getConsumablesToAdd($kit, $user, &$errors) { - // $consumables = $kit->consumables()->withCount('consumableAssignments as consumable_assignments_count')->get(); - $consumables = $kit->consumables()->with('users')->get(); - foreach($consumables as $consumable) { - if( $consumable->numRemaining() < $consumable->pivot->quantity ) { - $errors []= "Don't have available consumable " . $consumable->name . '. Need ' . $consumable->pivot->quantity; // TODO: trans - } - } - return $consumables; - } - - protected function getAccessoriesToAdd($kit, $user, &$errors) { - $accessories = $kit->accessories()->with('users')->get(); - foreach($accessories as $accossory) { - if( $accossory->numRemaining() < $accossory->pivot->quantity ) { - $errors []= "Don't have available accossory " . $accossory->name . '. Need ' . $accossory->pivot->quantity; // TODO: trans - } - } - return $accessories; + return $errors; } } diff --git a/resources/views/kits/accessory-edit.blade.php b/resources/views/kits/accessory-edit.blade.php index 807cd7fa7..e25966f7f 100644 --- a/resources/views/kits/accessory-edit.blade.php +++ b/resources/views/kits/accessory-edit.blade.php @@ -6,42 +6,7 @@ {{-- Page content --}} @section('inputFields') -{{--
- -
- - @if ($accessory_id = Input::old('accessory_id', (isset($item)) ? $item->accessory_id : '')) - - @else - - @endif - - -
-
- @can('create', \App\Accessories\Accessory::class) - @if ((!isset($hide_new)) || ($hide_new!='true')) - New - - @endif - @endcan -
- - {!! $errors->first('accessory_id', '
:message
') !!} -
--}} +@include ('partials.forms.edit.accessory-select', ['translated_name' => 'Accessory', 'fieldname' => 'accessory_id', 'required' => 'true']){{-- TODO: trans --}}
diff --git a/resources/views/kits/consumable-edit.blade.php b/resources/views/kits/consumable-edit.blade.php index 857850e8b..896b8c37d 100644 --- a/resources/views/kits/consumable-edit.blade.php +++ b/resources/views/kits/consumable-edit.blade.php @@ -6,42 +6,8 @@ {{-- Page content --}} @section('inputFields') -{{--
- -
- - @if ($consumable_id = Input::old('consumable_id', (isset($item)) ? $item->consumable_id : '')) - - @else - - @endif - - -
-
- @can('create', \App\Consumables\Consumable::class) - @if ((!isset($hide_new)) || ($hide_new!='true')) - New - - @endif - @endcan -
- - {!! $errors->first('consumable_id', '
:message
') !!} -
--}}
diff --git a/resources/views/kits/license-edit.blade.php b/resources/views/kits/license-edit.blade.php index 5a5e6858d..f64678d9d 100644 --- a/resources/views/kits/license-edit.blade.php +++ b/resources/views/kits/license-edit.blade.php @@ -6,42 +6,7 @@ {{-- Page content --}} @section('inputFields') -{{--
- -
- - @if ($license_id = Input::old('license_id', (isset($item)) ? $item->license_id : '')) - - @else - - @endif - - -
-
- @can('create', \App\Licenses\License::class) - @if ((!isset($hide_new)) || ($hide_new!='true')) - New - - @endif - @endcan -
- - {!! $errors->first('license_id', '
:message
') !!} -
--}}
diff --git a/resources/views/kits/model-edit.blade.php b/resources/views/kits/model-edit.blade.php index 7a283c580..61a419c95 100644 --- a/resources/views/kits/model-edit.blade.php +++ b/resources/views/kits/model-edit.blade.php @@ -6,42 +6,7 @@ {{-- Page content --}} @section('inputFields') -{{--
- -
- - @if ($model_id = Input::old('model_id', (isset($item)) ? $item->model_id : '')) - - @else - - @endif - - -
-
- @can('create', \App\Models\AssetModel::class) - @if ((!isset($hide_new)) || ($hide_new!='true')) - New - - @endif - @endcan -
- - {!! $errors->first('model_id', '
:message
') !!} -
--}}
diff --git a/resources/views/partials/forms/edit/accessory-select.blade.php b/resources/views/partials/forms/edit/accessory-select.blade.php index d8c919c0f..e786717ed 100644 --- a/resources/views/partials/forms/edit/accessory-select.blade.php +++ b/resources/views/partials/forms/edit/accessory-select.blade.php @@ -6,7 +6,7 @@ @if ((!isset($unselect)) && ($accessory_id = Input::old($fieldname, (isset($accessory) ? $accessory->id : (isset($item) ? $item->{$fieldname} : ''))))) @else @if(!isset($multiple)) diff --git a/resources/views/partials/forms/edit/consumable-select.blade.php b/resources/views/partials/forms/edit/consumable-select.blade.php index 82fb54f53..28cc56415 100644 --- a/resources/views/partials/forms/edit/consumable-select.blade.php +++ b/resources/views/partials/forms/edit/consumable-select.blade.php @@ -3,10 +3,10 @@ {{ Form::label($fieldname, $translated_name, array('class' => 'col-md-3 control-label')) }}