diff --git a/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/CreateServiceRequestController.php b/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/CreateServiceRequestController.php index 1d4c79454..d8a6d54b8 100644 --- a/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/CreateServiceRequestController.php +++ b/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/CreateServiceRequestController.php @@ -36,25 +36,31 @@ namespace AidingApp\Portal\Http\Controllers\KnowledgeManagementPortal; +use App\Enums\Feature; +use Illuminate\Support\Arr; use Illuminate\Support\Str; use Illuminate\Http\Request; use Illuminate\Http\JsonResponse; +use Illuminate\Support\Facades\DB; use App\Http\Controllers\Controller; +use Illuminate\Support\Facades\Gate; use Illuminate\Support\Facades\Validator; use Symfony\Component\HttpFoundation\Response; use AidingApp\Form\Actions\GenerateFormKitSchema; +use AidingApp\ServiceManagement\Models\ServiceRequest; use AidingApp\Form\Actions\GenerateSubmissibleValidation; use AidingApp\ServiceManagement\Models\ServiceRequestType; use AidingApp\Form\Actions\ResolveSubmissionAuthorFromEmail; use AidingApp\Form\Filament\Blocks\EducatableEmailFormFieldBlock; +use AidingApp\ServiceManagement\Models\ServiceRequestFormSubmission; class CreateServiceRequestController extends Controller { public function create(GenerateFormKitSchema $generateSchema, ServiceRequestType $type): JsonResponse { return response()->json([ - 'schema' => $generateSchema($type->form), - 'priorities' => $type->priorities()->orderBy('order', 'desc')->get()->pluck('name', 'id')->map(fn ($name, $id) => ['id' => $id, 'name' => $name]), + 'schema' => $type->form && Gate::check(Feature::OnlineForms->getGateName()) ? $generateSchema($type->form) : [], + 'priorities' => $type->priorities()->orderBy('order', 'desc')->pluck('name', 'id'), ]); } @@ -64,117 +70,143 @@ public function store( ResolveSubmissionAuthorFromEmail $resolveSubmissionAuthorFromEmail, ServiceRequestType $type, ): JsonResponse { - $contact = auth('contact')->user() ?? $request->user(); + $contact = auth('contact')->user(); - $serviceRequestForm = $type->form; + abort_if(is_null($contact), Response::HTTP_UNAUTHORIZED); - if ( - is_null($contact) - ) { - abort(Response::HTTP_UNAUTHORIZED); - } + $serviceRequestForm = $type->form; - $validator = Validator::make( - $request->all(), - $generateValidation($serviceRequestForm) - ); + $validator = Validator::make($request->all(), [ + 'priority' => ['required', 'exists:service_request_priorities,id'], + 'description' => ['required', 'string', 'max:65535'], + ...$serviceRequestForm + ? Arr::prependKeysWith($generateValidation($serviceRequestForm), 'extra.') + : [], + ]); if ($validator->fails()) { - return response()->json( - [ - 'errors' => (object) $validator->errors(), - ], - Response::HTTP_UNPROCESSABLE_ENTITY - ); + return response()->json([ + 'errors' => (object) $validator->errors(), + ], Response::HTTP_UNPROCESSABLE_ENTITY); } - $submission = $serviceRequestForm->submissions()->make(); - - $submission - ->priority() - ->associate( - $serviceRequestForm - ->type - ->priorities() - ->findOrFail( - $request->input('priority') - ) - ); + $data = $validator->validated(); - if ($contact) { - $submission->author()->associate($contact); - } + $priority = $type->priorities()->findOrFail($data['priority']); - $submission->submitted_at = now(); + return DB::transaction(function () use ( + $resolveSubmissionAuthorFromEmail, + $serviceRequestForm, + $priority, + $contact, + $data, + $type + ) { + $serviceRequest = new ServiceRequest([ + 'title' => $type->name, + 'close_details' => $data['description'], + ]); - $submission->description = $request->input('description'); + $serviceRequest->respondent()->associate($contact); + $serviceRequest->priority()->associate($priority); - $submission->save(); + $serviceRequest->save(); - $data = $validator->validated(); + if (! $serviceRequestForm) { + return response()->json([ + 'message' => 'Service Request Form submitted successfully.', + ]); + } - unset($data['recaptcha-token']); + unset( + $data['description'], + $data['priority'], + ); - if ($serviceRequestForm->is_wizard) { - foreach ($serviceRequestForm->steps as $step) { - $stepFields = $step->fields()->pluck('type', 'id')->all(); + $submission = $serviceRequestForm->submissions() + ->make([ + 'submitted_at' => now(), + ]); - foreach ($data[$step->label] as $fieldId => $response) { - $submission->fields()->attach( - $fieldId, - ['id' => Str::orderedUuid(), 'response' => $response], - ); + $submission->priority()->associate($priority); - if ($submission->author) { - continue; - } + $submission->save(); - if ($stepFields[$fieldId] !== EducatableEmailFormFieldBlock::type()) { - continue; - } + unset($data['recaptcha-token']); + + $data = data_get($data, 'extra', []); - $author = $resolveSubmissionAuthorFromEmail($response); + if ($serviceRequestForm->is_wizard) { + foreach ($serviceRequestForm->steps as $step) { + $fields = $step->fields()->pluck('type', 'id')->all(); - if (! $author) { - continue; + foreach ($data[$step->label] as $fieldId => $response) { + $this->processSubmissionField( + $submission, + $fieldId, + $response, + $fields, + $resolveSubmissionAuthorFromEmail + ); } + } + } else { + $fields = $serviceRequestForm->fields()->pluck('type', 'id')->all(); - $submission->author()->associate($author); + foreach ($data as $fieldId => $response) { + $this->processSubmissionField( + $submission, + $fieldId, + $response, + $fields, + $resolveSubmissionAuthorFromEmail + ); } } - } else { - $formFields = $serviceRequestForm->fields()->pluck('type', 'id')->all(); - foreach ($data as $fieldId => $response) { - $submission->fields()->attach( - $fieldId, - ['id' => Str::orderedUuid(), 'response' => $response], - ); + $submission->save(); - if ($submission->author) { - continue; - } + $serviceRequest->title = $serviceRequestForm->name; + $serviceRequest->serviceRequestFormSubmission()->associate($submission); - if ($formFields[$fieldId] !== EducatableEmailFormFieldBlock::type()) { - continue; - } + if ($submission->author) { + $serviceRequest->respondent()->associate($submission->author); + } - $author = $resolveSubmissionAuthorFromEmail($response); + $serviceRequest->save(); - if (! $author) { - continue; - } + return response()->json([ + 'message' => 'Service Request Form submitted successfully.', + ]); + }); + } - $submission->author()->associate($author); - } + private function processSubmissionField( + ServiceRequestFormSubmission $submission, + string $fieldId, + mixed $response, + array $fields, + ResolveSubmissionAuthorFromEmail $resolveSubmissionAuthorFromEmail + ) { + $submission->fields()->attach($fieldId, [ + 'id' => Str::orderedUuid(), + 'response' => $response, + ]); + + if ($submission->author) { + return; + } + + if ($fields[$fieldId] !== EducatableEmailFormFieldBlock::type()) { + return; } - $submission->save(); + $author = $resolveSubmissionAuthorFromEmail($response); - return response()->json( - [ - 'message' => 'Service Request Form submitted successfully.', - ] - ); + if (! $author) { + return; + } + + $submission->author()->associate($author); } } diff --git a/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/ServiceRequestTypesController.php b/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/ServiceRequestTypesController.php index 1fcf05a66..1ce9a1baf 100644 --- a/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/ServiceRequestTypesController.php +++ b/app-modules/portal/src/Http/Controllers/KnowledgeManagementPortal/ServiceRequestTypesController.php @@ -46,7 +46,6 @@ public function index(): JsonResponse { return response()->json([ 'types' => ServiceRequestType::query() - ->whereHas('form') ->orderBy('name') ->get() ->map(function (ServiceRequestType $type) { diff --git a/app-modules/service-management/src/Actions/ServiceRequest/CreateServiceRequestFromSubmission.php b/app-modules/service-management/src/Actions/ServiceRequest/CreateServiceRequestFromSubmission.php deleted file mode 100644 index ac88bc7e7..000000000 --- a/app-modules/service-management/src/Actions/ServiceRequest/CreateServiceRequestFromSubmission.php +++ /dev/null @@ -1,52 +0,0 @@ - - - Copyright © 2016-2024, Canyon GBS LLC. All rights reserved. - - Aiding App™ is licensed under the Elastic License 2.0. For more details, - see - - Notice: - - - You may not provide the software to third parties as a hosted or managed - service, where the service provides users with access to any substantial set of - the features or functionality of the software. - - You may not move, change, disable, or circumvent the license key functionality - in the software, and you may not remove or obscure any functionality in the - software that is protected by the license key. - - You may not alter, remove, or obscure any licensing, copyright, or other notices - of the licensor in the software. Any use of the licensor’s trademarks is subject - to applicable law. - - Canyon GBS LLC respects the intellectual property rights of others and expects the - same in return. Canyon GBS™ and Aiding App™ are registered trademarks of - Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks - vigorously. - - The software solution, including services, infrastructure, and code, is offered as a - Software as a Service (SaaS) by Canyon GBS LLC. - - Use of this software implies agreement to the license terms and conditions as stated - in the Elastic License 2.0. - - For more information or inquiries please visit our website at - or contact us via email at legal@canyongbs.com. - - -*/ - -namespace AidingApp\ServiceManagement\Actions\ServiceRequest; - -use AidingApp\ServiceManagement\Models\ServiceRequestFormSubmission; - -class CreateServiceRequestFromSubmission -{ - public function handle(ServiceRequestFormSubmission $serviceRequestFormSubmission): void - { - $serviceRequestFormSubmission->serviceRequest()->create([ - 'title' => $serviceRequestFormSubmission->submissible->name, - 'respondent_type' => $serviceRequestFormSubmission->author->getMorphClass(), - 'respondent_id' => $serviceRequestFormSubmission->author->getKey(), - 'priority_id' => $serviceRequestFormSubmission->service_request_priority_id, - ]); - } -} diff --git a/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/RelationManagers/ServiceRequestFormSubmissionRelationManager.php b/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/RelationManagers/ServiceRequestFormSubmissionRelationManager.php index 7118f849b..91f6d262a 100644 --- a/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/RelationManagers/ServiceRequestFormSubmissionRelationManager.php +++ b/app-modules/service-management/src/Filament/Resources/ServiceRequestResource/RelationManagers/ServiceRequestFormSubmissionRelationManager.php @@ -58,7 +58,11 @@ public function table(Table $table): Table ->dateTime(), TextColumn::make('author.email') ->label('Submitted By') - ->url(fn (ServiceRequestFormSubmission $record) => resolve($record->author::filamentResource())->getUrl('view', ['record' => $record->author])) + ->url( + fn (ServiceRequestFormSubmission $record) => $record->author + ? resolve($record->author::filamentResource())->getUrl('view', ['record' => $record->author]) + : null + ) ->color('primary'), TextColumn::make('author_type') ->label('Submitted By Type') diff --git a/app-modules/service-management/src/Observers/ServiceRequestFormSubmissionObserver.php b/app-modules/service-management/src/Observers/ServiceRequestFormSubmissionObserver.php deleted file mode 100644 index ba299251b..000000000 --- a/app-modules/service-management/src/Observers/ServiceRequestFormSubmissionObserver.php +++ /dev/null @@ -1,48 +0,0 @@ - - - Copyright © 2016-2024, Canyon GBS LLC. All rights reserved. - - Aiding App™ is licensed under the Elastic License 2.0. For more details, - see - - Notice: - - - You may not provide the software to third parties as a hosted or managed - service, where the service provides users with access to any substantial set of - the features or functionality of the software. - - You may not move, change, disable, or circumvent the license key functionality - in the software, and you may not remove or obscure any functionality in the - software that is protected by the license key. - - You may not alter, remove, or obscure any licensing, copyright, or other notices - of the licensor in the software. Any use of the licensor’s trademarks is subject - to applicable law. - - Canyon GBS LLC respects the intellectual property rights of others and expects the - same in return. Canyon GBS™ and Aiding App™ are registered trademarks of - Canyon GBS LLC, and we are committed to enforcing and protecting our trademarks - vigorously. - - The software solution, including services, infrastructure, and code, is offered as a - Software as a Service (SaaS) by Canyon GBS LLC. - - Use of this software implies agreement to the license terms and conditions as stated - in the Elastic License 2.0. - - For more information or inquiries please visit our website at - or contact us via email at legal@canyongbs.com. - - -*/ - -namespace AidingApp\ServiceManagement\Observers; - -use AidingApp\ServiceManagement\Models\ServiceRequestFormSubmission; -use AidingApp\ServiceManagement\Actions\ServiceRequest\CreateServiceRequestFromSubmission; - -class ServiceRequestFormSubmissionObserver -{ - public function created(ServiceRequestFormSubmission $serviceRequestFormSubmission): void - { - resolve(CreateServiceRequestFromSubmission::class)->handle($serviceRequestFormSubmission); - } -} diff --git a/app-modules/service-management/src/Policies/ServiceRequestFormPolicy.php b/app-modules/service-management/src/Policies/ServiceRequestFormPolicy.php index 6808a134a..fa15cc352 100644 --- a/app-modules/service-management/src/Policies/ServiceRequestFormPolicy.php +++ b/app-modules/service-management/src/Policies/ServiceRequestFormPolicy.php @@ -121,6 +121,9 @@ public function forceDelete(Authenticatable $authenticatable, ServiceRequestForm protected function requiredFeatures(): array { - return [Feature::ServiceManagement]; + return [ + Feature::ServiceManagement, + Feature::OnlineForms, + ]; } } diff --git a/app-modules/service-management/src/Providers/ServiceManagementServiceProvider.php b/app-modules/service-management/src/Providers/ServiceManagementServiceProvider.php index d66949516..de4cbad8f 100644 --- a/app-modules/service-management/src/Providers/ServiceManagementServiceProvider.php +++ b/app-modules/service-management/src/Providers/ServiceManagementServiceProvider.php @@ -65,7 +65,6 @@ use AidingApp\ServiceManagement\Observers\ServiceRequestHistoryObserver; use AidingApp\ServiceManagement\Registries\ServiceManagementRbacRegistry; use AidingApp\ServiceManagement\Observers\ServiceRequestAssignmentObserver; -use AidingApp\ServiceManagement\Observers\ServiceRequestFormSubmissionObserver; use AidingApp\ServiceManagement\Services\ServiceRequestNumber\Contracts\ServiceRequestNumberGenerator; use AidingApp\ServiceManagement\Services\ServiceRequestNumber\SqidPlusSixServiceRequestNumberGenerator; @@ -114,7 +113,6 @@ protected function registerObservers(): void ChangeRequest::observe(ChangeRequestObserver::class); ServiceRequest::observe(ServiceRequestObserver::class); ServiceRequestAssignment::observe(ServiceRequestAssignmentObserver::class); - ServiceRequestFormSubmission::observe(ServiceRequestFormSubmissionObserver::class); ServiceRequestHistory::observe(ServiceRequestHistoryObserver::class); ServiceRequestUpdate::observe(ServiceRequestUpdateObserver::class); } diff --git a/app/Filament/Pages/ManageLicenseSettings.php b/app/Filament/Pages/ManageLicenseSettings.php index 1b1a6117d..29e315c1e 100644 --- a/app/Filament/Pages/ManageLicenseSettings.php +++ b/app/Filament/Pages/ManageLicenseSettings.php @@ -129,7 +129,7 @@ public function form(Form $form): Form ->schema( [ Toggle::make('data.addons.onlineForms') - ->label('Online Forms'), + ->label('Custom Forms'), Toggle::make('data.addons.serviceManagement') ->label('Service Management'), Toggle::make('data.addons.knowledgeManagement') diff --git a/portals/knowledge-management/src/Pages/CreateServiceRequest.vue b/portals/knowledge-management/src/Pages/CreateServiceRequest.vue index b6f95a468..01c1ff3d2 100644 --- a/portals/knowledge-management/src/Pages/CreateServiceRequest.vue +++ b/portals/knowledge-management/src/Pages/CreateServiceRequest.vue @@ -55,11 +55,9 @@ }); const loadingResults = ref(true); - const description = ref(''); const user = ref(null); const schema = ref([]); const priorities = ref(null); - const priority = ref(null); const submittedSuccess = ref(false); watch( @@ -98,36 +96,31 @@ return steps[stepName].valid && steps[stepName].errorCount === 0; }, stringify: (value) => JSON.stringify(value, null, 2), - submitForm: async (data, node) => { - node.clearErrors(); - - const { post } = consumer(); + }); - const { getToken } = useTokenStore(); - let token = await getToken(); + async function submit(data, node) { + node.clearErrors(); - data.description = description.value; - data.priority = priority.value; + // let recaptchaToken = null; - // let recaptchaToken = null; + // if (formRecaptchaEnabled.value === true) { + // recaptchaToken = await getRecaptchaToken(formRecaptchaKey.value); + // } - // if (formRecaptchaEnabled.value === true) { - // recaptchaToken = await getRecaptchaToken(formRecaptchaKey.value); - // } + // if (recaptchaToken !== null) { + // data['recaptcha-token'] = recaptchaToken; + // } - // if (recaptchaToken !== null) { - // data['recaptcha-token'] = recaptchaToken; - // } + const { post } = consumer(); - post(props.apiUrl + '/service-request/create/' + route.params.typeId, data) - .then((response) => { - submittedSuccess.value = true; - }) - .catch((error) => { - node.setErrors([error]); - }); - }, - }); + post(props.apiUrl + '/service-request/create/' + route.params.typeId, data) + .then((response) => { + submittedSuccess.value = true; + }) + .catch((error) => { + node.setErrors([error]); + }); + } async function getData() { loadingResults.value = true; @@ -138,19 +131,17 @@ user.value = authUser; }); - const { getToken } = useTokenStore(); - let token = await getToken(); + const { get } = consumer(); - axios - .get(props.apiUrl + '/service-request/create/' + route.params.typeId, { - headers: { Authorization: `Bearer ${token}` }, - }) - .then((response) => { - loadingResults.value = false; + get(props.apiUrl + '/service-request/create/' + route.params.typeId).then((response) => { + loadingResults.value = false; - schema.value = response.data.schema; - priorities.value = response.data.priorities; - }); + response.data.schema.children = + response.data.schema.children?.filter((element) => element.$formkit !== 'submit') ?? []; + + schema.value = response.data.schema; + priorities.value = response.data.priorities; + }); } @@ -196,29 +187,31 @@
Thank you for submitting a new request.
- - - - - - -

Additional Form Information

- + + + + + +

Additional Form Information

+ + + + +