From 57b2c3130f2ef20eebf63a9b4437c4bb9e651c2c Mon Sep 17 00:00:00 2001 From: celikerde Date: Mon, 13 Jul 2026 11:39:19 +0300 Subject: [PATCH 1/5] fix(Translations): add missing translation for company deletion restriction --- lang/en.json | 1 + lang/tr.json | 1 + 2 files changed, 2 insertions(+) diff --git a/lang/en.json b/lang/en.json index 27f78e0c6..f2e12c7c3 100755 --- a/lang/en.json +++ b/lang/en.json @@ -100,6 +100,7 @@ "Terms of Service": "Terms of Service", "Thank you for your support!": "Thank you for your support!", + "This company has registered users and cannot be deleted.": "This company has registered users and cannot be deleted.", "This password reset link will expire in :count minutes.": "This password reset link will expire in :count minutes.", "This verification link will expire in :count minutes.": "This verification link will expire in :count minutes.", "Total": "Total", diff --git a/lang/tr.json b/lang/tr.json index f89d2384c..cb3c88f18 100755 --- a/lang/tr.json +++ b/lang/tr.json @@ -99,6 +99,7 @@ "Terms of Service": "Hizmet Şartları", "Thank you for your support!": "Desteğiniz için teşekkür ederiz!", + "This company has registered users and cannot be deleted.": "Bu şirkete kayıtlı kullanıcılar olduğu için bu şirket silinemez.", "This password reset link will expire in :count minutes.": "Bu şifre oluşturma linki :count dakika içerisinde sonlanacak.", "This verification link will expire in :count minutes.": "Bu doğrulama linki :count dakika içerisinde sonlanacak.", "Total": "Toplam", From 222071df16aa4f2e428b19d0ac413d33272e597e Mon Sep 17 00:00:00 2001 From: celikerde Date: Mon, 13 Jul 2026 11:52:20 +0300 Subject: [PATCH 2/5] fix(Request): add DELETE method handling and validation response --- src/Http/Requests/Request.php | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/Http/Requests/Request.php b/src/Http/Requests/Request.php index f60b80cb3..944f4c28a 100755 --- a/src/Http/Requests/Request.php +++ b/src/Http/Requests/Request.php @@ -3,11 +3,14 @@ namespace Unusualify\Modularous\Http\Requests; use Closure; +use Illuminate\Contracts\Validation\Validator; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Str; use Illuminate\Validation\Rule; +use Illuminate\Validation\ValidationException; +use Unusualify\Modularity\Services\MessageStage; use Unusualify\Modularous\Traits\ManageTraits; abstract class Request extends FormRequest @@ -45,12 +48,48 @@ public function rules() case 'PUT': return $this->mergeRules(array_merge($this->rulesForAll(), $this->rulesForUpdate())); + case 'DELETE': + return $this->rulesForDelete(); + default:break; } return []; } + public function rulesForDelete() + { + return []; + } + + protected function prepareForValidation() + { + if ($this->method() === 'DELETE' && $this->route()) { + $parameters = $this->route()->parameters(); + + if (! empty($parameters) && ! $this->has('id')) { + $this->merge(['id' => last($parameters)]); + } + } + } + + + protected function failedValidation(Validator $validator) + { + if ($this->method() === 'DELETE') { + $response = response()->json([ + 'message' => $validator->errors()->first(), + 'errors' => $validator->errors(), + 'variant' => MessageStage::ERROR->value, + ], 422); + + throw new ValidationException($validator, $response); + } + + parent::failedValidation($validator); + } + + public function mergeRules($rules) { $locales = getLocales(); From 435c0132bbf0f2d164d98c1ce3d49797e88ed5f7 Mon Sep 17 00:00:00 2001 From: celikerde Date: Mon, 13 Jul 2026 11:53:50 +0300 Subject: [PATCH 3/5] fix(CompanyRequest): add validation rules for DELETE requests --- .../SystemUser/Http/Requests/CompanyRequest.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/modules/SystemUser/Http/Requests/CompanyRequest.php b/modules/SystemUser/Http/Requests/CompanyRequest.php index 91a782341..d2fb71b0c 100755 --- a/modules/SystemUser/Http/Requests/CompanyRequest.php +++ b/modules/SystemUser/Http/Requests/CompanyRequest.php @@ -45,6 +45,22 @@ public function rulesForUpdate() ]; } + public function rulesForDelete() + { + return [ + 'id' => [ + 'required', + function ($attribute, $value, $fail) { + $company = $this->model()->find($value); + + if ($company && $company->users()->exists()) { + $fail(__('This company has registered users and cannot be deleted.')); + } + }, + ], + ]; + } + public function messages() { return [ From b24fbba84f894046f69ce241771487a93e6512df Mon Sep 17 00:00:00 2001 From: celikerde Date: Mon, 13 Jul 2026 11:55:02 +0300 Subject: [PATCH 4/5] fix(BaseController): add form request class retrieval in destroy method --- src/Http/Controllers/BaseController.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Http/Controllers/BaseController.php b/src/Http/Controllers/BaseController.php index abca6ad3a..5b99358f2 100755 --- a/src/Http/Controllers/BaseController.php +++ b/src/Http/Controllers/BaseController.php @@ -388,6 +388,8 @@ public function update($id, $submoduleId = null) */ public function destroy($id, $submoduleId = null) { + $this->getFormRequestClass(); + $params = $this->request->route()->parameters(); $id = last($params); From 1d763b04a235a7616aa37270ef9ec073527366af Mon Sep 17 00:00:00 2001 From: celikerde Date: Mon, 13 Jul 2026 11:57:12 +0300 Subject: [PATCH 5/5] fix(useTable): handle 422 status response and update axios delete/put requests to validate status --- vue/src/js/hooks/useTable.js | 6 +++++- vue/src/js/store/api/datatable.js | 14 ++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/vue/src/js/hooks/useTable.js b/vue/src/js/hooks/useTable.js index 7b45023d5..712043610 100755 --- a/vue/src/js/hooks/useTable.js +++ b/vue/src/js/hooks/useTable.js @@ -847,7 +847,11 @@ export default function useTable (props, context) { } let successCallback = (res) => { - if(res.status === 200) { + if (res.status === 422) { + if (runAlert && res.data?.message) { + store.dispatch(ACTIONS.SHOW_ALERT, res.data) + } + } else if (res.status === 200) { if(runAlert && res.data.variant && res.data.message){ store.dispatch(ACTIONS.SHOW_ALERT, res.data) diff --git a/vue/src/js/store/api/datatable.js b/vue/src/js/store/api/datatable.js index 87625a6e3..2b3c96ec8 100755 --- a/vue/src/js/store/api/datatable.js +++ b/vue/src/js/store/api/datatable.js @@ -53,7 +53,10 @@ export default { // const url = window[import.meta.env.VUE_APP_NAME].ENDPOINTS.destroy.replace(':id', id) // var url = window[import.meta.env.VUE_APP_NAME].ENDPOINTS.index.replace(':id', item.id); url = url.replace(':id', id) - axios.delete(url).then(function (resp) { + console.log(url) + axios.delete(url, { + validateStatus: status => (status >= 200 && status < 300) || status === 422 + }).then(function (resp) { if (callback && typeof callback === 'function') callback(resp) }, function (resp) { const error = { @@ -68,7 +71,9 @@ export default { forceDelete (url, id, callback, errorCallback) { // const url = window[import.meta.env.VUE_APP_NAME].ENDPOINTS.forceDelete url = url.replace(':id', id) - axios.put(url, { id }).then(function (resp) { + axios.put(url, { id }, { + validateStatus: status => (status >= 200 && status < 300) || status === 422 + }).then(function (resp) { if (callback && typeof callback === 'function') callback(resp) }, function (resp) { const error = { @@ -83,7 +88,9 @@ export default { restore (url, id, callback) { // const url = window[import.meta.env.VUE_APP_NAME].ENDPOINTS.restore url = url.replace(':id', id) - axios.put(url, { id }).then(function (resp) { + axios.put(url, { id }, { + validateStatus: status => (status >= 200 && status < 300) || status === 422 + }).then(function (resp) { if (callback && typeof callback === 'function') callback(resp) }, function (resp) { const error = { @@ -121,7 +128,6 @@ export default { if (errorCallback && typeof errorCallback === 'function') errorCallback(error) }) }, - bulkPublish (url, params, callback) { // const url = window[import.meta.env.VUE_APP_NAME].CMS_URLS.bulkPublish axios.post(url, { ids: params.ids, publish: params.toPublish }).then(function (resp) {