diff --git a/app/Actions/Assets/UpdateAssetAction.php b/app/Actions/Assets/UpdateAssetAction.php index fc21731bae..6cd3fa71a9 100644 --- a/app/Actions/Assets/UpdateAssetAction.php +++ b/app/Actions/Assets/UpdateAssetAction.php @@ -3,9 +3,7 @@ namespace App\Actions\Assets; use App\Events\CheckoutableCheckedIn; -use App\Helpers\Helper; use App\Http\Requests\ImageUploadRequest; -use App\Http\Requests\Request; use App\Models\Asset; use App\Models\AssetModel; use App\Models\Company; @@ -32,16 +30,16 @@ class UpdateAssetAction $rtd_location_id = null, $byod = false, $image_delete = false, - $serials = null, + $serial = null, $name = null, $company_id = null, $model_id = null, $order_number = null, - $asset_tags = null, + $asset_tag = null, $notes = null, - ) - { + ): \App\Models\SnipeModel { + dump($purchase_date); $asset->status_id = $status_id; $asset->warranty_months = $warranty_months; $asset->purchase_cost = $purchase_cost; @@ -100,28 +98,14 @@ class UpdateAssetAction } } - // this is gonna be a whole issue with validation - i'm assuming it's because we're using the same blade - // to do both create (which allows multiple creates) and update. should be fixable. - // and why is the offset 1 and not 0? very confusing. - $serial = $serials; - $asset->serial = $serials; - - if (is_array($serials)) { - $asset->serial = $serial[1]; - } + $asset->serial = $serial; $asset->name = $name; $asset->company_id = Company::getIdForCurrentUser($company_id); $asset->model_id = $model_id; $asset->order_number = $order_number; - // same thing as serials above - $asset_tags = $asset_tags; - $asset->asset_tag = $asset_tags; - - if (is_array($asset_tags)) { - $asset->asset_tag = $asset_tags[1]; - } + $asset->asset_tag = $asset_tag; $asset->notes = $notes; @@ -156,11 +140,8 @@ class UpdateAssetAction session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]); - if ($asset->save()) { - return redirect()->to(Helper::getRedirectOption($request, $assetId, 'Assets')) - ->with('success', trans('admin/hardware/message.update.success')); - } + $asset->save(); - return redirect()->back()->withInput()->withErrors($asset->getErrors()); + return $asset; } } \ No newline at end of file diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index e28d66afbd..8b15edff79 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api; use App\Actions\Assets\DestroyAssetAction; use App\Actions\Assets\StoreAssetAction; +use App\Actions\Assets\UpdateAssetAction; use App\Events\CheckoutableCheckedIn; use App\Exceptions\CheckoutNotAllowed; use App\Http\Requests\Assets\StoreAssetRequest; @@ -650,6 +651,12 @@ class AssetsController extends Controller */ public function update(UpdateAssetRequest $request, Asset $asset): JsonResponse { + try { + UpdateAssetAction::run($asset, $request, ...$request->validated()); + } catch (CheckoutNotAllowed $e) { + return response()->json(Helper::formatStandardApiResponse('error', null, $e->getMessage()), 200); + } + $asset->fill($request->validated()); if ($request->has('model_id')) { @@ -675,8 +682,8 @@ class AssetsController extends Controller $asset = $request->handleImages($asset); $model = $asset->model; - - // Update custom fields + + // Update custom fields $problems_updating_encrypted_custom_fields = false; if (($model) && (isset($model->fieldset))) { foreach ($model->fieldset->fields as $field) { diff --git a/app/Http/Controllers/Assets/AssetsController.php b/app/Http/Controllers/Assets/AssetsController.php index f0599bab93..60b6d459bb 100755 --- a/app/Http/Controllers/Assets/AssetsController.php +++ b/app/Http/Controllers/Assets/AssetsController.php @@ -233,6 +233,15 @@ class AssetsController extends Controller public function update(UpdateAssetRequest $request, Asset $asset): RedirectResponse { try { + $serials = $request->input('serials'); + $asset_tags = $request->input('asset_tags'); + if (is_array($request->input('serials'))) { + $serial = $serials[1]; + } + if (is_array($request->input('asset_tags'))) { + $asset_tag = $asset_tags[1]; + } + $asset = UpdateAssetAction::run( asset: $asset, request: $request, @@ -248,75 +257,67 @@ class AssetsController extends Controller rtd_location_id: $request->validated('rtd_location_id'), byod: $request->validated('byod'), image_delete: $request->validated('image_delete'), - serials: null, // this needs to be set up in request somehow + serial: $serial, // this needs to be set up in request somehow name: $request->validated('name'), company_id: $request->validated('company_id'), model_id: $request->validated('model_id'), order_number: $request->validated('order_number'), - asset_tags: null, // same as serials + asset_tag: $asset_tag, // same as serials notes: $request->validated('notes'), ); - return redirect()->back()->with('success', trans('admin/hardware/message.update.success')); + return redirect()->to(Helper::getRedirectOption($request, $asset->id, 'Assets')) + ->with('success', trans('admin/hardware/message.update.success')); + } catch (\Watson\Validating\ValidationException $e) { + $errors = $e->getErrors(); + return redirect()->back()->withInput()->withErrors($errors); } catch (\Exception $e) { report($e); - return redirect()->back()->with('error', trans('admin/hardware/message.update.error')); + return redirect()->back()->with('error', trans('admin/hardware/message.update.error'), $asset); } // serials???? - $serial = $request->input('serials'); - $asset->serial = $request->input('serials'); - - if (is_array($request->input('serials'))) { - $asset->serial = $serial[1]; - } - - $asset->name = $request->input('name'); - $asset->company_id = Company::getIdForCurrentUser($request->input('company_id')); - $asset->model_id = $request->input('model_id'); - $asset->order_number = $request->input('order_number'); - - $asset_tags = $request->input('asset_tags'); - $asset->asset_tag = $request->input('asset_tags'); - - if (is_array($request->input('asset_tags'))) { - $asset->asset_tag = $asset_tags[1]; - } - - $asset->notes = $request->input('notes'); - - $asset = $request->handleImages($asset); - - // Update custom fields in the database. - $model = AssetModel::find($request->get('model_id')); - if (($model) && ($model->fieldset)) { - foreach ($model->fieldset->fields as $field) { - - if ($field->field_encrypted == '1') { - if (Gate::allows('assets.view.encrypted_custom_fields')) { - if (is_array($request->input($field->db_column))) { - $asset->{$field->db_column} = Crypt::encrypt(implode(', ', $request->input($field->db_column))); - } else { - $asset->{$field->db_column} = Crypt::encrypt($request->input($field->db_column)); - } - } - } else { - if (is_array($request->input($field->db_column))) { - $asset->{$field->db_column} = implode(', ', $request->input($field->db_column)); - } else { - $asset->{$field->db_column} = $request->input($field->db_column); - } - } - } - } - - session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]); - - if ($asset->save()) { - return redirect()->to(Helper::getRedirectOption($request, $assetId, 'Assets')) - ->with('success', trans('admin/hardware/message.update.success')); - } - - return redirect()->back()->withInput()->withErrors($asset->getErrors()); + //$asset->name = $request->input('name'); + //$asset->company_id = Company::getIdForCurrentUser($request->input('company_id')); + //$asset->model_id = $request->input('model_id'); + //$asset->order_number = $request->input('order_number'); + // + // + // + //$asset->notes = $request->input('notes'); + // + //$asset = $request->handleImages($asset); + // + //// Update custom fields in the database. + //$model = AssetModel::find($request->get('model_id')); + //if (($model) && ($model->fieldset)) { + // foreach ($model->fieldset->fields as $field) { + // + // if ($field->field_encrypted == '1') { + // if (Gate::allows('assets.view.encrypted_custom_fields')) { + // if (is_array($request->input($field->db_column))) { + // $asset->{$field->db_column} = Crypt::encrypt(implode(', ', $request->input($field->db_column))); + // } else { + // $asset->{$field->db_column} = Crypt::encrypt($request->input($field->db_column)); + // } + // } + // } else { + // if (is_array($request->input($field->db_column))) { + // $asset->{$field->db_column} = implode(', ', $request->input($field->db_column)); + // } else { + // $asset->{$field->db_column} = $request->input($field->db_column); + // } + // } + // } + //} + // + //session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]); + // + //if ($asset->save()) { + // return redirect()->to(Helper::getRedirectOption($request, $assetId, 'Assets')) + // ->with('success', trans('admin/hardware/message.update.success')); + //} + // + //return redirect()->back()->withInput()->withErrors($asset->getErrors()); } /** diff --git a/app/Http/Requests/Assets/UpdateAssetRequest.php b/app/Http/Requests/Assets/UpdateAssetRequest.php index 2046414b74..1732b75028 100644 --- a/app/Http/Requests/Assets/UpdateAssetRequest.php +++ b/app/Http/Requests/Assets/UpdateAssetRequest.php @@ -29,9 +29,19 @@ class UpdateAssetRequest extends ImageUploadRequest */ public function rules() { + $modelRules = (new Asset)->getRules(); + // TODO: make sure this actually works + if ((Setting::getSettings()->digit_separator === '1.234,56' || '1,234.56') && is_string($this->input('purchase_cost'))) { + // If purchase_cost was submitted as a string with a comma separator + // then we need to ignore the normal numeric rules. + // Since the original rules still live on the model they will be run + // right before saving (and after purchase_cost has been + // converted to a float via setPurchaseCostAttribute). + $modelRules = $this->removeNumericRulesFromPurchaseCost($modelRules); + } $rules = array_merge( parent::rules(), - (new Asset)->getRules(), + $modelRules, // this is to overwrite rulesets that include required, and rewrite unique_undeleted [ 'image_delete' => ['bool'], @@ -49,6 +59,21 @@ class UpdateAssetRequest extends ImageUploadRequest if (Setting::getSettings()->digit_separator === '1.234,56' && is_string($this->input('purchase_cost'))) { $rules['purchase_cost'] = ['nullable', 'string']; } + return $rules; + } + + private function removeNumericRulesFromPurchaseCost(array $rules): array + { + $purchaseCost = $rules['purchase_cost']; + + // If rule is in "|" format then turn it into an array + if (is_string($purchaseCost)) { + $purchaseCost = explode('|', $purchaseCost); + } + + $rules['purchase_cost'] = array_filter($purchaseCost, function ($rule) { + return $rule !== 'numeric' && $rule !== 'gte:0'; + }); return $rules; } diff --git a/app/Models/Asset.php b/app/Models/Asset.php index ce8b870eb2..3f53dda623 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -35,6 +35,8 @@ class Asset extends Depreciable use CompanyableTrait; use HasFactory, Loggable, Requestable, Presentable, SoftDeletes, ValidatingTrait, UniqueUndeletedTrait; + protected $throwValidationExceptions = true; + public const LOCATION = 'location'; public const ASSET = 'asset'; public const USER = 'user'; diff --git a/resources/views/hardware/edit.blade.php b/resources/views/hardware/edit.blade.php index efd5d24b9c..6e3dd3c54e 100755 --- a/resources/views/hardware/edit.blade.php +++ b/resources/views/hardware/edit.blade.php @@ -5,7 +5,7 @@ 'topSubmit' => true, 'helpText' => trans('help.assets'), 'helpPosition' => 'right', - 'formAction' => ($item->id) ? route('hardware.update', ['hardware' => $item->id]) : route('hardware.store'), + 'formAction' => ($item->id) ? route('hardware.update', ['asset' => $item->id]) : route('hardware.store'), 'index_route' => 'hardware.index', 'options' => [ 'index' => trans('admin/hardware/form.redirect_to_all', ['type' => 'assets']),