diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 5594d8e6b..37e749597 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -41,7 +41,9 @@ class Handler extends ExceptionHandler public function report(Throwable $exception) { if ($this->shouldReport($exception)) { - \Log::error($exception); + if (class_exists(\Log::class)) { + \Log::error($exception); + } return parent::report($exception); } } diff --git a/app/Http/Controllers/Api/SettingsController.php b/app/Http/Controllers/Api/SettingsController.php index 62380b221..d0f7fea60 100644 --- a/app/Http/Controllers/Api/SettingsController.php +++ b/app/Http/Controllers/Api/SettingsController.php @@ -143,47 +143,6 @@ class SettingsController extends Controller } - public function slacktest(SlackSettingsRequest $request) - { - - $validator = Validator::make($request->all(), [ - 'slack_endpoint' => 'url|required_with:slack_channel|starts_with:https://hooks.slack.com/|nullable', - 'slack_channel' => 'required_with:slack_endpoint|starts_with:#|nullable', - ]); - - if ($validator->fails()) { - return response()->json(['message' => 'Validation failed', 'errors' => $validator->errors()], 422); - } - - // If validation passes, continue to the curl request - $slack = new Client([ - 'base_url' => e($request->input('slack_endpoint')), - 'defaults' => [ - 'exceptions' => false, - ], - ]); - - $payload = json_encode( - [ - 'channel' => e($request->input('slack_channel')), - 'text' => trans('general.slack_test_msg'), - 'username' => e($request->input('slack_botname')), - 'icon_emoji' => ':heart:', - ]); - - try { - $slack->post($request->input('slack_endpoint'), ['body' => $payload]); - return response()->json(['message' => 'Success'], 200); - - } catch (\Exception $e) { - return response()->json(['message' => 'Please check the channel name and webhook endpoint URL ('.e($request->input('slack_endpoint')).'). Slack responded with: '.$e->getMessage()], 400); - } - - //} - return response()->json(['message' => 'Something went wrong :( '], 400); - } - - /** * Test the email configuration * diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php index d8f7ee3b6..b04c692ac 100755 --- a/app/Http/Controllers/SettingsController.php +++ b/app/Http/Controllers/SettingsController.php @@ -679,33 +679,6 @@ class SettingsController extends Controller return view('settings.slack', compact('setting')); } - /** - * Return a form to allow a super admin to update settings. - * - * @author [A. Gianotto] [] - * - * @since [v1.0] - * - * @return View - */ - public function postSlack(SlackSettingsRequest $request) - { - if (is_null($setting = Setting::getSettings())) { - return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error')); - } - - $setting->slack_endpoint = $request->input('slack_endpoint'); - $setting->slack_channel = $request->input('slack_channel'); - $setting->slack_botname = $request->input('slack_botname'); - - if ($setting->save()) { - return redirect()->route('settings.index') - ->with('success', trans('admin/settings/message.update.success')); - } - - return redirect()->back()->withInput()->withErrors($setting->getErrors()); - } - /** * Return a form to allow a super admin to update settings. * diff --git a/app/Http/Livewire/SlackSettingsForm.php b/app/Http/Livewire/SlackSettingsForm.php new file mode 100644 index 000000000..1fda9a118 --- /dev/null +++ b/app/Http/Livewire/SlackSettingsForm.php @@ -0,0 +1,92 @@ + 'url|required_with:slack_channel|starts_with:https://hooks.slack.com/|nullable', + 'slack_channel' => 'required_with:slack_endpoint|starts_with:#|nullable', + 'slack_botname' => 'string|nullable', + ]; + + public function mount(){ + + $this->setting = Setting::getSettings(); + $this->slack_endpoint = $this->setting->slack_endpoint; + $this->slack_channel = $this->setting->slack_channel; + $this->slack_botname = $this->setting->slack_botname; + + } + public function updated($field){ + + $this->validateOnly($field ,$this->rules); + } + + public function render() + { + if(empty($this->slack_channel || $this->slack_endpoint)){ + $this->isDisabled= 'disabled'; + } + return view('livewire.slack-settings-form'); + } + + public function testSlack(){ + + $slack = new Client([ + 'base_url' => e($this->slack_endpoint), + 'defaults' => [ + 'exceptions' => false, + ], + ]); + + $payload = json_encode( + [ + 'channel' => e($this->slack_channel), + 'text' => trans('general.slack_test_msg'), + 'username' => e($this->slack_botname), + 'icon_emoji' => ':heart:', + ]); + + try { + $slack->post($this->slack_endpoint, ['body' => $payload]); + $this->isDisabled=''; + return session()->flash('success' , 'Your Slack Integration works!'); + + } catch (\Exception $e) { + $this->isDisabled= 'disabled'; + return session()->flash('error' , trans('admin/settings/message.slack.error', ['error_message' => $e->getMessage()])); + } + + //} + return session()->flash('message' , trans('admin/settings/message.slack.error_misc')); + + + + } + public function submit() + { + $this->validate($this->rules); + + $this->setting->slack_endpoint = $this->slack_endpoint; + $this->setting->slack_channel = $this->slack_channel; + $this->setting->slack_botname = $this->slack_botname; + + $this->setting->save(); + + session()->flash('save',trans('admin/settings/message.update.success')); + + + } +} diff --git a/app/Http/Requests/SlackSettingsRequest.php b/app/Http/Requests/SlackSettingsRequest.php deleted file mode 100644 index 1f4421519..000000000 --- a/app/Http/Requests/SlackSettingsRequest.php +++ /dev/null @@ -1,33 +0,0 @@ - 'url|required_with:slack_channel|starts_with:"https://hooks.slack.com"|nullable', - 'slack_channel' => 'required_with:slack_endpoint|starts_with:#|nullable', - 'slack_botname' => 'string|nullable', - - ]; - } - - -} diff --git a/app/Http/Transformers/ActionlogsTransformer.php b/app/Http/Transformers/ActionlogsTransformer.php index c58760d4d..cd2ce586d 100644 --- a/app/Http/Transformers/ActionlogsTransformer.php +++ b/app/Http/Transformers/ActionlogsTransformer.php @@ -60,12 +60,14 @@ class ActionlogsTransformer if ($actionlog->action_type == 'accepted') { $file_url = route('log.storedeula.download', ['filename' => $actionlog->filename]); } else { - if ($actionlog->itemType() == 'asset') { - $file_url = route('show/assetfile', ['assetId' => $actionlog->item->id, 'fileId' => $actionlog->id]); - } elseif ($actionlog->itemType() == 'license') { - $file_url = route('show.licensefile', ['licenseId' => $actionlog->item->id, 'fileId' => $actionlog->id]); - } elseif ($actionlog->itemType() == 'user') { - $file_url = route('show/userfile', ['userId' => $actionlog->item->id, 'fileId' => $actionlog->id]); + if ($actionlog->item) { + if ($actionlog->itemType() == 'asset') { + $file_url = route('show/assetfile', ['assetId' => $actionlog->item->id, 'fileId' => $actionlog->id]); + } elseif ($actionlog->itemType() == 'license') { + $file_url = route('show.licensefile', ['licenseId' => $actionlog->item->id, 'fileId' => $actionlog->id]); + } elseif ($actionlog->itemType() == 'user') { + $file_url = route('show/userfile', ['userId' => $actionlog->item->id, 'fileId' => $actionlog->id]); + } } } } diff --git a/app/Importer/LicenseImporter.php b/app/Importer/LicenseImporter.php index 894c50bbf..3bfbf1ee2 100644 --- a/app/Importer/LicenseImporter.php +++ b/app/Importer/LicenseImporter.php @@ -80,6 +80,11 @@ class LicenseImporter extends ItemImporter $checkout_target = $this->item['checkout_target']; $asset = Asset::where('asset_tag', $asset_tag)->first(); $targetLicense = $license->freeSeat(); + + if (is_null($targetLicense)){ + return; + } + if ($checkout_target) { $targetLicense->assigned_to = $checkout_target->id; $targetLicense->user_id = Auth::id(); diff --git a/app/Models/Accessory.php b/app/Models/Accessory.php index d39d65338..0457cf253 100755 --- a/app/Models/Accessory.php +++ b/app/Models/Accessory.php @@ -63,6 +63,7 @@ class Accessory extends SnipeModel 'company_id' => 'integer|nullable', 'min_amt' => 'integer|min:0|nullable', 'purchase_cost' => 'numeric|nullable|gte:0', + 'purchase_date' => 'date_format:Y-m-d|nullable', ]; diff --git a/app/Models/Asset.php b/app/Models/Asset.php index 68b3845f6..e0908c089 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -84,11 +84,11 @@ class Asset extends Depreciable protected $casts = [ - 'purchase_date' => 'datetime', + 'purchase_date' => 'date', 'last_checkout' => 'datetime', - 'expected_checkin' => 'datetime', + 'expected_checkin' => 'date', 'last_audit_date' => 'datetime', - 'next_audit_date' => 'datetime', + 'next_audit_date' => 'date', 'model_id' => 'integer', 'status_id' => 'integer', 'company_id' => 'integer', @@ -105,16 +105,14 @@ class Asset extends Depreciable 'company_id' => 'integer|nullable', 'warranty_months' => 'numeric|nullable|digits_between:0,240', 'physical' => 'numeric|max:1|nullable', - 'checkout_date' => 'date|max:10|min:10|nullable', - 'checkin_date' => 'date|max:10|min:10|nullable', + 'last_checkout' => 'date_format:Y-m-d H:i:s|nullable', + 'expected_checkin' => 'date_format:Y-m-d|nullable', 'location_id' => 'exists:locations,id|nullable', 'rtd_location_id' => 'exists:locations,id|nullable', 'asset_tag' => 'required|min:1|max:255|unique_undeleted', - 'status' => 'integer', + 'purchase_date' => 'date|date_format:Y-m-d|nullable', 'serial' => 'unique_serial|nullable', 'purchase_cost' => 'numeric|nullable|gte:0', - 'next_audit_date' => 'date|nullable', - 'last_audit_date' => 'date|nullable', 'supplier_id' => 'exists:suppliers,id|nullable', ]; @@ -145,6 +143,9 @@ class Asset extends Depreciable 'last_checkout', 'expected_checkin', 'byod', + 'last_audit_date', + 'next_audit_date', + ]; use Searchable; diff --git a/app/Models/Component.php b/app/Models/Component.php index dc353d288..98230132b 100644 --- a/app/Models/Component.php +++ b/app/Models/Component.php @@ -35,7 +35,7 @@ class Component extends SnipeModel 'category_id' => 'required|integer|exists:categories,id', 'company_id' => 'integer|nullable', 'min_amt' => 'integer|min:0|nullable', - 'purchase_date' => 'date|nullable', + 'purchase_date' => 'date_format:Y-m-d|nullable', 'purchase_cost' => 'numeric|nullable|gte:0', ]; diff --git a/app/Models/Consumable.php b/app/Models/Consumable.php index c04c9b53d..ea4ac6086 100644 --- a/app/Models/Consumable.php +++ b/app/Models/Consumable.php @@ -41,6 +41,7 @@ class Consumable extends SnipeModel 'company_id' => 'integer|nullable', 'min_amt' => 'integer|min:0|nullable', 'purchase_cost' => 'numeric|nullable|gte:0', + 'purchase_date' => 'date_format:Y-m-d|nullable', ]; /** diff --git a/app/Models/License.php b/app/Models/License.php index b59387a42..d3c4d8a1c 100755 --- a/app/Models/License.php +++ b/app/Models/License.php @@ -50,6 +50,9 @@ class License extends Depreciable 'category_id' => 'required|exists:categories,id', 'company_id' => 'integer|nullable', 'purchase_cost'=> 'numeric|nullable|gte:0', + 'purchase_date' => 'date_format:Y-m-d|nullable', + 'expiration_date' => 'date_format:Y-m-d|nullable', + 'termination_date' => 'date_format:Y-m-d|nullable', ]; /** diff --git a/app/Models/Setting.php b/app/Models/Setting.php index 8f1f65201..fd02992f7 100755 --- a/app/Models/Setting.php +++ b/app/Models/Setting.php @@ -83,6 +83,9 @@ class Setting extends Model 'email_domain', 'email_format', 'username_format', + 'slack_endpoint', + 'slack_channel', + 'slack_botname', ]; /** diff --git a/app/Models/User.php b/app/Models/User.php index 71025eaef..1f57f9190 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -98,8 +98,8 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo 'website' => 'url|nullable|max:191', 'manager_id' => 'nullable|exists:users,id|cant_manage_self', 'location_id' => 'exists:locations,id|nullable', - 'start_date' => 'nullable|date', - 'end_date' => 'nullable|date|after_or_equal:start_date', + 'start_date' => 'nullable|date_format:Y-m-d', + 'end_date' => 'nullable|date_format:Y-m-d|after_or_equal:start_date', ]; /** diff --git a/config/logging.php b/config/logging.php index cdd0bbcbd..94495a2a3 100644 --- a/config/logging.php +++ b/config/logging.php @@ -1,5 +1,4 @@ \Rollbar\Laravel\MonologHandler::class, 'access_token' => env('ROLLBAR_TOKEN'), 'level' => env('ROLLBAR_LEVEL', 'error'), + 'check_ignore' => function($isUncaught, $args, $payload) { + if (App::environment('production') && is_object($args) && get_class($args) == Rollbar\ErrorWrapper::class && $args->errorLevel == E_WARNING ) { + \Log::info("IGNORING E_WARNING in production mode: ".$args->getMessage()); + return true; // "TRUE - you should ignore it!" + } + return false; + }, ], ], diff --git a/resources/lang/en/admin/settings/message.php b/resources/lang/en/admin/settings/message.php index 174a15fbd..b0648d1c1 100644 --- a/resources/lang/en/admin/settings/message.php +++ b/resources/lang/en/admin/settings/message.php @@ -38,6 +38,7 @@ return [ 'success_pt1' => 'Success! Check the ', 'success_pt2' => ' channel for your test message, and be sure to click SAVE below to store your settings.', '500' => '500 Server Error.', - 'error' => 'Something went wrong.', + 'error' => 'Something went wrong. Slack responded with: :error_message', + 'error_misc' => 'Something went wrong. :( ', ] ]; diff --git a/resources/lang/en/validation.php b/resources/lang/en/validation.php index 04f8d6530..31c9dcd85 100644 --- a/resources/lang/en/validation.php +++ b/resources/lang/en/validation.php @@ -103,17 +103,6 @@ return [ ], - /* - |-------------------------------------------------------------------------- - | Custom Validation Language Lines - |-------------------------------------------------------------------------- - | - | Here you may specify custom validation messages for attributes using the - | convention "attribute.rule" to name the lines. This makes it quick to - | specify a specific custom language line for a given attribute rule. - | - */ - /* |-------------------------------------------------------------------------- | Custom Validation Language Lines @@ -131,6 +120,18 @@ return [ 'hashed_pass' => 'Your current password is incorrect', 'dumbpwd' => 'That password is too common.', 'statuslabel_type' => 'You must select a valid status label type', + + // date_format validation with slightly less stupid messages. It duplicates a lot, but it gets the job done :( + // We use this because the default error message for date_format is reflects php Y-m-d, which non-PHP + // people won't know how to format. + 'purchase_date.date_format' => 'The :attribute must be a valid date in YYYY-MM-DD format', + 'last_audit_date.date_format' => 'The :attribute must be a valid date in YYYY-MM-DD hh:mm:ss format', + 'expiration_date.date_format' => 'The :attribute must be a valid date in YYYY-MM-DD format', + 'termination_date.date_format' => 'The :attribute must be a valid date in YYYY-MM-DD format', + 'expected_checkin.date_format' => 'The :attribute must be a valid date in YYYY-MM-DD format', + 'start_date.date_format' => 'The :attribute must be a valid date in YYYY-MM-DD format', + 'end_date.date_format' => 'The :attribute must be a valid date in YYYY-MM-DD format', + ], /* diff --git a/resources/views/layouts/edit-form.blade.php b/resources/views/layouts/edit-form.blade.php index cb1793103..791590141 100644 --- a/resources/views/layouts/edit-form.blade.php +++ b/resources/views/layouts/edit-form.blade.php @@ -31,35 +31,34 @@
-
+
+ + @if ((isset($topSubmit) && ($topSubmit=='true')) || (isset($item->id)))
- -
@if ($item->id) -

+

{{ $item->display_name }}

@endif
+ @if (isset($topSubmit) && ($topSubmit=='true'))
- - {{ trans('button.cancel') }} - -
-
+ @endif
-
+ @endif
+
@if ($item->id) {{ method_field('PUT') }} @endif @@ -68,6 +67,7 @@ {{ csrf_field() }} @yield('inputFields') @include('partials.forms.edit.submit') +
diff --git a/resources/views/livewire/slack-settings-form.blade.php b/resources/views/livewire/slack-settings-form.blade.php new file mode 100644 index 000000000..6d48220ca --- /dev/null +++ b/resources/views/livewire/slack-settings-form.blade.php @@ -0,0 +1,99 @@ + + +
+ @if (session()->has('save')) +
+ {{session('save')}} +
+ @endif + + @if(session()->has('success')) +
+ {{session('success')}} +
+ @endif + @if(session()->has('error')) +
+ {{session('error')}} +
+ @endif + @if(session()->has('message')) +
+ {{session('message')}} +
+ @endif + +
+ {{csrf_field()}} + + +
+
+ {{ Form::label('slack_endpoint', trans('admin/settings/general.slack_endpoint')) }} +
+
+ @if (config('app.lock_passwords')===true) +

{{ trans('general.feature_disabled') }}

+ + @else + + @endif + {!! $errors->first('slack_endpoint', '') !!} +
+
+ + +
+
+ {{ Form::label('slack_channel', trans('admin/settings/general.slack_channel')) }} +
+
+ @if (config('app.lock_passwords')===true) + +

{{ trans('general.feature_disabled') }}

+ + @else + + @endif + {!! $errors->first('slack_channel', '') !!} +
+
+ + +
+
+ {{ Form::label('slack_botname', trans('admin/settings/general.slack_botname')) }} +
+
+ @if (config('app.lock_passwords')===true) + +

{{ trans('general.feature_disabled') }}

+ + @else + + @endif + {!! $errors->first('slack_botname', '') !!} +
+
+ + + @if($slack_endpoint != null && $slack_channel != null) + + @endif + + +
+ +
+ + diff --git a/resources/views/partials/assets-assigned.blade.php b/resources/views/partials/assets-assigned.blade.php index f4a9f8bdb..6e3c0f9bf 100644 --- a/resources/views/partials/assets-assigned.blade.php +++ b/resources/views/partials/assets-assigned.blade.php @@ -60,7 +60,7 @@ table_html += ""; } } else { - table_html += 'No assets checked out to '+ $('.js-data-user-ajax').find('option:selected').text() + ' yet!'; + table_html += '{{ trans('admin/users/message.user_has_no_assets_assigned') }}'; } $('#current_assets_content').html(table_html + '
'); diff --git a/resources/views/partials/forms/edit/submit.blade.php b/resources/views/partials/forms/edit/submit.blade.php index 54f17e854..4c87c7bb2 100644 --- a/resources/views/partials/forms/edit/submit.blade.php +++ b/resources/views/partials/forms/edit/submit.blade.php @@ -1,7 +1,7 @@ -