diff --git a/app/Classes/General/Eloquent/Filters/EndDate.php b/app/Classes/General/Eloquent/Filters/EndDate.php new file mode 100644 index 00000000..b6fb0d43 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/EndDate.php @@ -0,0 +1,20 @@ +whereDate('created_at', '<=', Carbon::parse($value)->format('Y-m-d')); + } +} diff --git a/app/Classes/General/Eloquent/Filters/HasQuestionnaire.php b/app/Classes/General/Eloquent/Filters/HasQuestionnaire.php new file mode 100644 index 00000000..ae4e6787 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/HasQuestionnaire.php @@ -0,0 +1,24 @@ +whereHas('question', function ($subquery) use($value){ + $subquery->whereHas('questionnaire', function ($subsubquery) use($value){ + $subsubquery->where('id', $value); + }); + }); + } +} diff --git a/app/Classes/General/Eloquent/Filters/IdAfter.php b/app/Classes/General/Eloquent/Filters/IdAfter.php new file mode 100644 index 00000000..55959e75 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/IdAfter.php @@ -0,0 +1,35 @@ +', $id) + ->whereIn('answer', $questionGroups) + ->orderBy('id', 'asc') + ->limit(1) + ->value('id'); + + if ($nextId) { + return $builder->where('id', '>', $id) + ->where('id', '<', $nextId); + } + + return $builder->where('id', '>', $id); + } + +} diff --git a/app/Classes/General/Eloquent/Filters/StartDate.php b/app/Classes/General/Eloquent/Filters/StartDate.php new file mode 100644 index 00000000..ce2281b8 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/StartDate.php @@ -0,0 +1,20 @@ +whereDate('created_at', '>=', Carbon::parse($value)->format('Y-m-d')); + } +} diff --git a/app/Classes/General/Eloquent/Filters/WithAnswers.php b/app/Classes/General/Eloquent/Filters/WithAnswers.php new file mode 100644 index 00000000..a8ff3bb9 --- /dev/null +++ b/app/Classes/General/Eloquent/Filters/WithAnswers.php @@ -0,0 +1,27 @@ +where(function ($query) use($value){ + if($value){ + $query->where('answer', '=', $value); + } + else{ + $query->whereIn('answer', QuestionGroup::QUESTION_GROUPS); + } + }); + } +} diff --git a/app/Classes/Modules/Exports/ControllersLogic/ExportQuestionsAnswersLogic.php b/app/Classes/Modules/Exports/ControllersLogic/ExportQuestionsAnswersLogic.php new file mode 100644 index 00000000..4c8c1500 --- /dev/null +++ b/app/Classes/Modules/Exports/ControllersLogic/ExportQuestionsAnswersLogic.php @@ -0,0 +1,65 @@ + 'Export Questions & Answers', + 'message' => 'You have successfully exported data' + ]; + } + + /** @var ExportsQuestionsAnswers */ + private $exportsQuestionsAnswers; + + /** @var CanExportQuestionsAnswers */ + private $canExport; + + /** + * ExportFeedbackDataLogic constructor. + * @param ExportsQuestionsAnswers $exportsQuestionsAnswers + * @param CanExportQuestionsAnswers $canExport + */ + public function __construct(ExportsQuestionsAnswers $exportsQuestionsAnswers, CanExportQuestionsAnswers $canExport) + { + $this->exportsQuestionsAnswers = $exportsQuestionsAnswers; + $this->canExport = $canExport; + } + + + /** + * @param Request $request + * @return Response + */ + public function logic(Request $request) : JsonResponse + { + $this->canExport->passes(); + + $this->exportsQuestionsAnswers->setFilters(Helper::deserializeFilters($request->input('filters'))); + + $exportFileName = 'qas.xls'; + $filesystemDriver = Storage::getDefaultDriver(); + if($filesystemDriver === 's3'){ + return $this->response([ 'src' => AWSS3Helper::S3Exportable($exportFileName, $this->exportsQuestionsAnswers) ]); + } + + return $this->response([ 'src' => null ]); + } + +} diff --git a/app/Classes/Modules/Exports/Services/ExportsQuestionsAnswers.php b/app/Classes/Modules/Exports/Services/ExportsQuestionsAnswers.php new file mode 100644 index 00000000..68b6f5da --- /dev/null +++ b/app/Classes/Modules/Exports/Services/ExportsQuestionsAnswers.php @@ -0,0 +1,114 @@ +filters = $filters; + } + + /** + * @return \Illuminate\Support\Collection|mixed + */ + public function query() + { + $data = (new ApplyFiltersToQuery())->execute(QAUserAnswerSelected::query(), $this->filters, true); + + return $data; + } + + /** + * @param QAUserAnswerSelected $userAnswer + * + * @return array + */ + public function map($userAnswer): array + { + $source = $userAnswer->userSource; + $user = $userAnswer->source_id === 0 ? $userAnswer->user : null; + $answer = $userAnswer->answer()->first(); + $rows = [[ + $userAnswer->id, + $userAnswer->question->questionnaire->version, + $userAnswer->question->questionnaire->description, + $userAnswer->question->question_title, + $answer ? $answer->display_text : null, + $answer ? $answer->value : null, + $user ? $user->email : $source->email, + $userAnswer->time_used_seconds, + Carbon::parse($userAnswer->created_at)->format('d-m-Y'), + "YES" + ]]; + + + $nextId = QAUserAnswerSelected::where('id', '>', $userAnswer->id) + ->whereIn('answer', QuestionGroup::QUESTION_GROUPS) + ->orderBy('id', 'asc') + ->limit(1) + ->value('id'); + + if ($nextId) { + $temp = QAUserAnswerSelected::where('reference', '=', $userAnswer->reference)->where('id', '>', $userAnswer->id) + ->where('id', '<', $nextId)->get(); + } + else{ + $temp = QAUserAnswerSelected::where('reference', '=', $userAnswer->reference)->where('id', '>', $userAnswer->id)->get(); + } + + foreach ($temp as $relatedAnswer) { + $source = $relatedAnswer->userSource; + $user = $relatedAnswer->source_id === 0 ? $relatedAnswer->user : null; + $answer = $relatedAnswer->answer()->first(); + + $rows[] = [ + $relatedAnswer->id, + $relatedAnswer->question->questionnaire->version, + $relatedAnswer->question->questionnaire->description, + $relatedAnswer->question->question_title, + $answer ? $answer->display_text : null, + $answer ? $answer->value : null, + $user ? $user->email : $source->email, + $relatedAnswer->time_used_seconds, + Carbon::parse($relatedAnswer->created_at)->format('d-m-Y'), + ]; + } + + return $rows; + } +} diff --git a/app/Classes/Modules/Exports/Standards/Rules/CanExportQuestionsAnswers.php b/app/Classes/Modules/Exports/Standards/Rules/CanExportQuestionsAnswers.php new file mode 100644 index 00000000..5072a6b3 --- /dev/null +++ b/app/Classes/Modules/Exports/Standards/Rules/CanExportQuestionsAnswers.php @@ -0,0 +1,48 @@ +user()){ + $roleToCheck = Auth()->user()->type; + if (in_array($roleToCheck, RoleTypes::ADMIN_ROLES)) { + return true; + } + else { + return false; + } + } + return false; + } + + /** + * @param $object + * @return bool + */ + protected function validators($object): bool + { + return true; + } + + + /** + * @param $object + * @return bool + */ + protected function criteria($object): bool + { + return true; + } + +} diff --git a/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionnaireSetLogic.php b/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionnaireSetLogic.php new file mode 100644 index 00000000..d8fe5667 --- /dev/null +++ b/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionnaireSetLogic.php @@ -0,0 +1,60 @@ + 'Retrieved Questionnaire Sets', + 'message' => 'You have successfully retrieved a list of questionnaire sets' + ]; + } + + /** @var CanListQuestions */ + private $canListQuestions; + + /** @var ListsQuestionnaireSet */ + private $listsQuestionnaireSet; + + /** + * ListQuestionnaireSetLogic constructor. + * @param CanListQuestions $canListQuestions + * @param ListsQuestionnaireSet $listsQuestionnaires + */ + public function __construct(CanListQuestions $canListQuestions, ListsQuestionnaireSet $listsQuestionnaireSet) + { + $this->canListQuestions = $canListQuestions; + $this->listsQuestionnaireSet = $listsQuestionnaireSet; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request) : JsonResponse + { + // $this->canListQuestions->passes(); //cief todo: 74 + + $query = $this->listsQuestionnaireSet->execute($this->listsQuestionnaireSet->deserializeFilters($request->input('filters'))); + + return $this->collectionResponse(QuestionnaireSetsResource::collection($query)); + } + +} diff --git a/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionsAnswersLogic.php b/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionsAnswersLogic.php new file mode 100644 index 00000000..bac51604 --- /dev/null +++ b/app/Classes/Modules/Questionnaires/ControllersLogic/ListQuestionsAnswersLogic.php @@ -0,0 +1,60 @@ + 'Retrieved Questions Answers', + 'message' => 'You have successfully retrieved a list of questions and answers' + ]; + } + + /** @var CanListQuestions */ + private $canListQuestions; + + /** @var ListsQuestionUserAnswerSelected */ + private $listsQuestionUserAnswerSelected; + + /** + * ListQuestionsAnswersQALogic constructor. + * @param CanListQuestions $canListQuestions + * @param ListsQuestionUserAnswerSelected $listsQuestionUserAnswerSelected + */ + public function __construct(CanListQuestions $canListQuestions, ListsQuestionUserAnswerSelected $listsQuestionUserAnswerSelected) + { + $this->canListQuestions = $canListQuestions; + $this->listsQuestionUserAnswerSelected = $listsQuestionUserAnswerSelected; + } + + + /** + * @param Request $request + * @return JsonResponse + * @throws \App\Classes\Exceptions\AccessForbiddenException + * @throws \App\Classes\Exceptions\MalformedRequestException + * @throws \App\Classes\Exceptions\RequestValidationException + */ + public function logic(Request $request) : JsonResponse + { + $this->canListQuestions->passes(); + + $query = $this->listsQuestionUserAnswerSelected->execute($this->listsQuestionUserAnswerSelected->deserializeFilters($request->input('filters'))); + + return $this->collectionResponse(QuestionsAnswersResource::collection($query)); + } + +} diff --git a/app/Classes/Modules/Questionnaires/ControllersLogic/UpdateNextQuestionV1AdminWFLogic.php b/app/Classes/Modules/Questionnaires/ControllersLogic/UpdateNextQuestionV1AdminWFLogic.php index b6cdb372..53b36cce 100644 --- a/app/Classes/Modules/Questionnaires/ControllersLogic/UpdateNextQuestionV1AdminWFLogic.php +++ b/app/Classes/Modules/Questionnaires/ControllersLogic/UpdateNextQuestionV1AdminWFLogic.php @@ -8,7 +8,7 @@ use App\Classes\Modules\Questionnaires\Standards\Rules\CanFetchQuestion; use App\Classes\Modules\Questionnaires\Processors\SaveAnswerV1AdminWFProcessor; use App\Classes\Modules\Questionnaires\Processors\FetchNextQuestionV1AdminWFProcessor; use App\Classes\Modules\Questionnaires\Processors\FetchFirstQuestionV1AdminWFProcessor; -use App\Classes\Modules\Questionnaires\Services\ListsUserAnswerSelected; +use App\Classes\Modules\Questionnaires\Services\ListsQuestionUserAnswerSelected; use App\Classes\Modules\Accounts\Services\CreatesKeyValuePair; use App\Classes\Modules\Accounts\DataTransferObjects\KeyValuePairObject; use Illuminate\Http\JsonResponse; @@ -43,7 +43,7 @@ class UpdateNextQuestionV1AdminWFLogic extends AbstractControllerLogic /** @var FetchFirstQuestionV1AdminWFProcessor */ private $fetchFirstQuestionQAProcessor; - /** @var ListsUserAnswerSelected */ + /** @var ListsQuestionUserAnswerSelected */ private $listsUserAnswerSelected; /** @var CreatesKeyValuePair */ @@ -55,10 +55,10 @@ class UpdateNextQuestionV1AdminWFLogic extends AbstractControllerLogic * @param SaveAnswerV1AdminWFProcessor $saveAnswerProcessor * @param FetchNextQuestionV1AdminWFProcessor $fetchNextQuestionQAProcessor * @param FetchFirstQuestionV1AdminWFProcessor $fetchFirstQuestionQAProcessor - * @param ListsUserAnswerSelected $listsUserAnswerSelected + * @param ListsQuestionUserAnswerSelected $listsUserAnswerSelected * @param CreatesKeyValuePair $createsKeyValuePair */ - public function __construct(CanFetchQuestion $canFetchQuestion, SaveAnswerV1AdminWFProcessor $saveAnswerProcessor, FetchNextQuestionV1AdminWFProcessor $fetchNextQuestionQAProcessor, FetchFirstQuestionV1AdminWFProcessor $fetchFirstQuestionQAProcessor, ListsUserAnswerSelected $listsUserAnswerSelected, CreatesKeyValuePair $createsKeyValuePair) + public function __construct(CanFetchQuestion $canFetchQuestion, SaveAnswerV1AdminWFProcessor $saveAnswerProcessor, FetchNextQuestionV1AdminWFProcessor $fetchNextQuestionQAProcessor, FetchFirstQuestionV1AdminWFProcessor $fetchFirstQuestionQAProcessor, ListsQuestionUserAnswerSelected $listsUserAnswerSelected, CreatesKeyValuePair $createsKeyValuePair) { $this->canFetchQuestion = $canFetchQuestion; $this->saveAnswerProcessor = $saveAnswerProcessor; diff --git a/app/Classes/Modules/Questionnaires/Services/ListsUserAnswerSelected.php b/app/Classes/Modules/Questionnaires/Services/ListsQuestionUserAnswerSelected.php similarity index 83% rename from app/Classes/Modules/Questionnaires/Services/ListsUserAnswerSelected.php rename to app/Classes/Modules/Questionnaires/Services/ListsQuestionUserAnswerSelected.php index 0dca07ac..358ab612 100644 --- a/app/Classes/Modules/Questionnaires/Services/ListsUserAnswerSelected.php +++ b/app/Classes/Modules/Questionnaires/Services/ListsQuestionUserAnswerSelected.php @@ -7,14 +7,14 @@ use App\Classes\General\Eloquent\AbstractListRecord; use Illuminate\Database\Eloquent\Builder; use App\Models\QAUserAnswerSelected; -class ListsUserAnswerSelected extends AbstractListRecord +class ListsQuestionUserAnswerSelected extends AbstractListRecord { /** @var QAUserAnswerSelected */ private $repository; /** - * ListsUserAnswerSelected constructor. + * ListsQuestionUserAnswerSelected constructor. * @param QAUserAnswerSelected $repository */ public function __construct(QAUserAnswerSelected $repository) diff --git a/app/Classes/Modules/Questionnaires/Services/ListsQuestionnaireSet.php b/app/Classes/Modules/Questionnaires/Services/ListsQuestionnaireSet.php new file mode 100644 index 00000000..fb58304b --- /dev/null +++ b/app/Classes/Modules/Questionnaires/Services/ListsQuestionnaireSet.php @@ -0,0 +1,33 @@ +repository = $repository; + } + + + /** + * @return Builder + */ + public function getRepository(): Builder + { + return $this->repository->newQuery(); + } +} diff --git a/app/Classes/Modules/Questionnaires/Standards/Rules/CanListHelpMenuQuestions.php b/app/Classes/Modules/Questionnaires/Standards/Rules/CanListQuestions.php similarity index 100% rename from app/Classes/Modules/Questionnaires/Standards/Rules/CanListHelpMenuQuestions.php rename to app/Classes/Modules/Questionnaires/Standards/Rules/CanListQuestions.php diff --git a/app/Classes/ValueObjects/Constants/QuestionGroup.php b/app/Classes/ValueObjects/Constants/QuestionGroup.php new file mode 100644 index 00000000..3491792d --- /dev/null +++ b/app/Classes/ValueObjects/Constants/QuestionGroup.php @@ -0,0 +1,22 @@ + '1688', 'id' => QuestionGroup::_1688], + ['text' => 'approve_po', 'id' => QuestionGroup::APPROVE_PO], + ['text' => 'fill_po', 'id' => QuestionGroup::FILL_PO], + ]; + + const QUESTION_GROUPS = [ + QuestionGroup::_1688, + QuestionGroup::APPROVE_PO, + QuestionGroup::FILL_PO, + ]; +} diff --git a/app/Http/Controllers/Exports/ExportQuestionsAnswersController.php b/app/Http/Controllers/Exports/ExportQuestionsAnswersController.php new file mode 100644 index 00000000..58c05a5d --- /dev/null +++ b/app/Http/Controllers/Exports/ExportQuestionsAnswersController.php @@ -0,0 +1,22 @@ +execute($request); + } +} diff --git a/app/Http/Controllers/AdminWorkflow/AdminWorkflowBaseController.php b/app/Http/Controllers/Questionnaires/AdminWorkflowBaseController.php similarity index 97% rename from app/Http/Controllers/AdminWorkflow/AdminWorkflowBaseController.php rename to app/Http/Controllers/Questionnaires/AdminWorkflowBaseController.php index 55e16882..068728a7 100644 --- a/app/Http/Controllers/AdminWorkflow/AdminWorkflowBaseController.php +++ b/app/Http/Controllers/Questionnaires/AdminWorkflowBaseController.php @@ -1,7 +1,7 @@ execute($request); + } + +} diff --git a/app/Http/Controllers/Questionnaires/ListQuestionsAnswersController.php b/app/Http/Controllers/Questionnaires/ListQuestionsAnswersController.php new file mode 100644 index 00000000..091eba5e --- /dev/null +++ b/app/Http/Controllers/Questionnaires/ListQuestionsAnswersController.php @@ -0,0 +1,21 @@ +execute($request); + } + +} diff --git a/app/Http/Resources/QuestionnaireSetsResource.php b/app/Http/Resources/QuestionnaireSetsResource.php index 8a2e39ec..5072a2a6 100644 --- a/app/Http/Resources/QuestionnaireSetsResource.php +++ b/app/Http/Resources/QuestionnaireSetsResource.php @@ -16,8 +16,9 @@ class QuestionnaireSetsResource extends JsonResource public function toArray($request) { return [ - // 'name' => $this->name, - // 'description' => $this->description, + 'id' => $this->id, + 'name' => $this->name, + 'description' => $this->description, 'group' => $this->group, 'version' => $this->version, ]; diff --git a/app/Http/Resources/QuestionsAnswersResource.php b/app/Http/Resources/QuestionsAnswersResource.php index 48599583..f5bf38f6 100644 --- a/app/Http/Resources/QuestionsAnswersResource.php +++ b/app/Http/Resources/QuestionsAnswersResource.php @@ -3,6 +3,8 @@ namespace App\Http\Resources; +use App\Classes\ValueObjects\Constants\DocumentType; +use App\Classes\ValueObjects\Constants\QuestionGroup; use Illuminate\Http\Resources\Json\JsonResource; use App\Models\QAAnswerOptions; use App\Models\QAQuestions; @@ -24,20 +26,27 @@ class QuestionsAnswersResource extends JsonResource $answerOption = QAAnswerOptions::where('id', $this->answer_option_id)->first(); $user_marking = ''; - if($user){ - $companyModule = $user->companyModule()->first(); - $user_marking = $companyModule ? $companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference : ""; - } + // if($user){ + // $companyModule = $user->companyModule()->first(); + // $user_marking = $companyModule ? $companyModule->inviters()->withPivot('invitee_reference')->first()->pivot->invitee_reference : ""; + // } return [ + 'id' => $this->id, 'question_id' => $this->question_id, + 'question_groups' => QuestionGroup::QUESTION_GROUPS, 'questionnaire' => new QuestionnaireSetsResource($this->question->questionnaire), 'question_title' => $question ? $question->question_title : null, + 'question_type' => $question ? $question->question_type : 0, + 'question_metadata' => $this->question_metadata, 'answer' => $answerOption ? $answerOption->display_text : null, - 'answer_value' => $answerOption ? $answerOption->value : null, + 'answer_value' => $this->answer, + 'documents' => new DocumentResource($this->documents->whereIn('document_type', DocumentType::ADMIN_WORK_FLOW)->first()), + 'reference' => $this->reference, 'source_system' => null, 'source_marking' => $user ? $user_marking : $source->marking, 'source_email' => $user ? $user->email : $source->email, + 'time' => $this->time_used_seconds, 'created_at' => Carbon::parse($this->created_at)->format('d-m-Y'), ]; } diff --git a/app/Models/QAQuestions.php b/app/Models/QAQuestions.php index dd01ee15..43c4cce7 100644 --- a/app/Models/QAQuestions.php +++ b/app/Models/QAQuestions.php @@ -16,4 +16,12 @@ class QAQuestions extends AbstractModel { return $this->BelongsTo(QAQuestionnaireSet::class, 'questionnaire_set_id', 'id'); } + + /** + * @return HasMany + */ + public function userAnswers() + { + return $this->hasMany(QAUserAnswerSelected::class, 'question_id', 'id'); + } } diff --git a/database/migrations/2024_12_28_142918_add_group_to_qa_questions_table.php b/database/migrations/2024_12_28_142918_add_group_to_qa_questions_table.php new file mode 100644 index 00000000..45cdc103 --- /dev/null +++ b/database/migrations/2024_12_28_142918_add_group_to_qa_questions_table.php @@ -0,0 +1,32 @@ +string('group')->after('questionnaire_set_id')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('questionnaire_set_id', function (Blueprint $table) { + $table->dropColumn('group'); + }); + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 03cb13d4..c46c7227 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -5,6 +5,7 @@ use Database\Seeders\CompaniesTableDevelopmentSeeder; use Database\Seeders\CurrenciesTableDevelopmentSeeder; use Database\Seeders\CurrencyRatesTableDevelopmentSeeder; use Database\Seeders\DummyDataSeeder; +use Database\Seeders\QAWorkFlowSeeder; use Database\Seeders\SegmentConstantsTableDevelopmentSeeder; use Database\Seeders\SegmentsTableDevelopmentSeeder; use Database\Seeders\ServiceTypesTableDevelopmentSeeder; @@ -20,7 +21,7 @@ class DatabaseSeeder extends Seeder */ public function run() { - DB::beginTransaction(); + DB::beginTransaction(); //General $this->call(CountriesTableSeeder::class); @@ -49,7 +50,7 @@ class DatabaseSeeder extends Seeder } // Admin Work Flow - // $this->call(QAWorkFlow2Seeder::class); + // $this->call(QAWorkFlowSeeder::class); // DB::commit(); } diff --git a/database/seeds/QAWorkFlow2Seeder.php b/database/seeds/QAWorkFlowSeeder.php similarity index 93% rename from database/seeds/QAWorkFlow2Seeder.php rename to database/seeds/QAWorkFlowSeeder.php index 0aace36b..47fadbed 100644 --- a/database/seeds/QAWorkFlow2Seeder.php +++ b/database/seeds/QAWorkFlowSeeder.php @@ -1,13 +1,21 @@ 'Yes', 'value' => 'start_work', 'next_question_number' => 'start_work'], ['display_text' => 'No', 'value' => 'no_work', 'next_question_number' => 'no_work'], ], + 'group' => '', ], [ 'question_number' => 'start_work', @@ -39,6 +48,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Approve PO', 'value' => 'approve_po', 'next_question_number' => 'approve_po'], ['display_text' => 'Fill PO', 'value' => 'fill_po', 'next_question_number' => 'fill_po'], ], + 'group' => '', ], [ 'question_number' => 'no_work', @@ -46,6 +56,7 @@ class QAWorkFlow2Seeder extends Seeder 'question_type' => QAType::DEFAULT, 'is_start' => false, 'is_end' => true, + 'group' => '', ], [ 'question_number' => '1688', @@ -58,6 +69,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Login Issue', 'value' => '1688_login_issue', 'btn_color' => 'warning', 'next_question_number' => '1688_login_issue'], ['display_text' => 'Login Successful', 'value' => '1688_login_successful', 'next_question_number' => '1688_login_successful'], ], + 'group' => '1688', ], [ 'question_number' => '1688_login_issue', @@ -71,6 +83,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Others', 'value' => '1688_login_issue_others', 'next_question_number' => '1688_login_issue_others'], ['display_text' => 'Order Cancelled', 'value' => '1688_refund_request', 'next_question_number' => '1688_refund_request'], ], + 'group' => '1688', ], [ 'question_number' => '1688_login_successful', @@ -83,6 +96,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => "Can't verify order?", 'value' => '1688_login_successful_cannot_verify', 'next_question_number' => '1688_login_successful_cannot_verify'], ['display_text' => 'Order Verified', 'value' => '1688_order_verify', 'next_question_number' => '1688_order_verify'], ], + 'group' => '1688', ], [ 'question_number' => '1688_login_successful_cannot_verify', @@ -97,6 +111,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Customer did not verify 1688 account', 'value' => 'Customer did not verify 1688 account', 'next_question_number' => '1688_issue_submit'], ['display_text' => 'WorldFirst account linked another account', 'value' => 'WorldFirst account linked another account', 'next_question_number' => '1688_issue_submit'], ], + 'group' => '1688', ], [ 'question_number' => '1688_login_successful_cannot_verify_others', @@ -105,6 +120,7 @@ class QAWorkFlow2Seeder extends Seeder 'next_nested_question' => '1688_issue_submit', 'is_start' => false, 'is_end' => false, + 'group' => '1688', ], [ 'question_number' => '1688_order_verify', @@ -118,6 +134,7 @@ class QAWorkFlow2Seeder extends Seeder 'answer_options' => [ ['display_text' => 'Yes', 'value' => '1688_order_verification', 'next_question_number' => '1688_order_verification'], ], + 'group' => '1688', ], [ 'question_number' => '1688_order_verification', @@ -129,6 +146,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Yes', 'value' => '1688_proceed_order', 'next_question_number' => '1688_proceed_order'], ['display_text' => 'No', 'value' => '1688_insufficient_order', 'next_question_number' => '1688_insufficient_order'], ], + 'group' => '1688', ], [ 'question_number' => '1688_proceed_order', @@ -140,6 +158,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Yes', 'value' => '1688_submit', 'next_question_number' => '1688_submit'], ['display_text' => 'Got Issue', 'value' => '1688_proceed_order_issue', 'next_question_number' => '1688_proceed_order_issue'], ], + 'group' => '1688', ], [ 'question_number' => '1688_proceed_order_issue', @@ -154,6 +173,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'No CrossBoarder', 'value' => 'No CrossBoarder', 'next_question_number' => '1688_issue_submit'], ['display_text' => 'AngPau', 'value' => 'AngPau', 'next_question_number' => '1688_issue_submit'], ], + 'group' => '1688', ], [ 'question_number' => '1688_proceed_order_issue_others', @@ -162,6 +182,7 @@ class QAWorkFlow2Seeder extends Seeder 'next_nested_question' => '1688_issue_submit', 'is_start' => false, 'is_end' => false, + 'group' => '1688', ], [ 'question_number' => '1688_login_issue_others', @@ -170,6 +191,7 @@ class QAWorkFlow2Seeder extends Seeder 'next_nested_question' => '1688_issue_submit', 'is_start' => false, 'is_end' => false, + 'group' => '1688', ], [ 'question_number' => '1688_submit', @@ -178,6 +200,7 @@ class QAWorkFlow2Seeder extends Seeder 'next_nested_question' => '1688_issue_submit', 'is_start' => false, 'is_end' => false, + 'group' => '1688', ], [ 'question_number' => '1688_issue_submit', @@ -189,6 +212,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'], ['display_text' => 'Next Order', 'value' => '1688', 'next_question_number' => '1688'], ], + 'group' => '1688', ], [ 'question_number' => '1688_refund_request', @@ -200,6 +224,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'], ['display_text' => 'Next Order', 'value' => '1688', 'next_question_number' => '1688'], ], + 'group' => '1688', ], [ 'question_number' => 'approve_po', @@ -213,6 +238,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Edit PO', 'value' => 'approve_po_edit', 'next_question_number' => 'approve_po_edit'], ['display_text' => 'Reject', 'value' => 'approve_po_reject', 'next_question_number' => 'approve_po_reject'], ], + 'group' => 'approve_po', ], [ 'question_number' => 'fill_po', @@ -224,6 +250,7 @@ class QAWorkFlow2Seeder extends Seeder 'answer_options' => [ ['display_text' => 'Edit PO', 'value' => 'fill_po_edit', 'next_question_number' => 'fill_po_edit'], ], + 'group' => 'fill_po', ], [ 'question_number' => 'approve_po_filled', @@ -236,6 +263,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Next PO (Fill)', 'value' => 'fill_po', 'next_question_number' => 'fill_po'], ['display_text' => 'Next PO (Approve)', 'value' => 'approve_po', 'next_question_number' => 'approve_po'], ], + 'group' => 'approve_po', ], [ 'question_number' => 'approve_po_approved', @@ -248,6 +276,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Next PO (Fill)', 'value' => 'fill_po', 'next_question_number' => 'fill_po'], ['display_text' => 'Next PO (Approve)', 'value' => 'approve_po', 'next_question_number' => 'approve_po'], ], + 'group' => 'approve_po', ], [ 'question_number' => 'approve_po_edit', @@ -260,6 +289,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Issue?', 'value' => 'approve_po_edit_po_issue', 'next_question_number' => 'approve_po_edit_po_issue'], ['display_text' => 'Done', 'value' => 'approve_po_filled', 'next_question_number' => 'approve_po_filled'], ], + 'group' => 'approve_po', ], [ 'question_number' => 'approve_po_reject', @@ -273,6 +303,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Stop Working', 'value' => 'stop_working', 'next_question_number' => 'stop_working'], ['display_text' => 'Next Order', 'value' => 'approve_po', 'next_question_number' => 'approve_po'], ], + 'group' => 'approve_po', ], [ 'question_number' => 'approve_po_reject_others', @@ -281,6 +312,7 @@ class QAWorkFlow2Seeder extends Seeder 'next_nested_question' => 'approve_po_reject_others_complete', 'is_start' => false, 'is_end' => false, + 'group' => 'approve_po', ], [ 'question_number' => 'approve_po_reject_others_complete', @@ -293,6 +325,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Next PO (Fill)', 'value' => 'fill_po', 'next_question_number' => 'fill_po'], ['display_text' => 'Next PO (Approve)', 'value' => 'approve_po', 'next_question_number' => 'approve_po'], ], + 'group' => 'approve_po', ], [ 'question_number' => 'approve_po_edit_po_issue', @@ -304,6 +337,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Sensitive Goods', 'value' => 'Sensitive Goods', 'next_question_number' => 'fill_po_issue_submit'], ['display_text' => 'Others', 'value' => 'fill_po_issue_others', 'next_question_number' => 'fill_po_issue_others'], ], + 'group' => 'approve_po', ], [ 'question_number' => 'fill_po_issue_others', @@ -312,6 +346,7 @@ class QAWorkFlow2Seeder extends Seeder 'next_nested_question' => 'fill_po_issue_submit', 'is_start' => false, 'is_end' => false, + 'group' => 'fill_po', ], [ 'question_number' => 'fill_po_issue_submit', @@ -324,6 +359,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Next PO (Fill)', 'value' => 'fill_po', 'next_question_number' => 'fill_po'], ['display_text' => 'Next PO (Approve)', 'value' => 'approve_po', 'next_question_number' => 'approve_po'], ], + 'group' => 'fill_po', ], [ 'question_number' => 'stop_working', @@ -331,6 +367,7 @@ class QAWorkFlow2Seeder extends Seeder 'question_type' => QAType::DEFAULT, 'is_start' => false, 'is_end' => true, + 'group' => '', ], [ 'question_number' => '1688_insufficient_order', @@ -343,6 +380,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Underpaid Order', 'value' => 'underpaird_order_2', 'next_question_number' => ''], ['display_text' => 'Overpaid Order', 'value' => 'underpaird_order_2', 'next_question_number' => ''], ], + 'group' => '1688', ], [ 'question_number' => 'fill_po_edit', @@ -355,6 +393,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Issue?', 'value' => 'fill_po_edit_issue', 'next_question_number' => 'fill_po_edit_issue'], ['display_text' => 'Done', 'value' => 'fill_po_edit_filled', 'next_question_number' => 'fill_po_edit_filled'], ], + 'group' => 'fill_po', ], [ 'question_number' => 'fill_po_edit_issue', @@ -366,6 +405,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Sensitive Goods', 'value' => 'Sensitive Goods', 'next_question_number' => 'fill_po_issue_submit'], ['display_text' => 'Others', 'value' => 'fill_po_issue_others', 'next_question_number' => 'fill_po_issue_others'], ], + 'group' => 'fill_po', ], [ 'question_number' => 'fill_po_edit_filled', @@ -378,6 +418,7 @@ class QAWorkFlow2Seeder extends Seeder ['display_text' => 'Next PO (Fill)', 'value' => 'fill_po', 'next_question_number' => 'fill_po'], ['display_text' => 'Next PO (Approve)', 'value' => 'approve_po', 'next_question_number' => 'approve_po'], ], + 'group' => 'fill_po', ], ] ], @@ -399,6 +440,9 @@ class QAWorkFlow2Seeder extends Seeder } $question->question_type = $questionData['question_type']; $question->questionnaire_set_id = $questionnaireSet->id; + if (isset($questionData['group']) && $questionData['group'] != '') { + $question->group = $questionData['group']; + } if (isset($questionData['next_nested_question'])) { $question->next_nested_question = $questionData['next_nested_question']; diff --git a/resources/assets/vue/components/admin-workflow/elements/QuestionAnswerComponent.vue b/resources/assets/vue/components/admin-workflow/elements/QuestionAnswerComponent.vue new file mode 100644 index 00000000..a5293588 --- /dev/null +++ b/resources/assets/vue/components/admin-workflow/elements/QuestionAnswerComponent.vue @@ -0,0 +1,144 @@ + + + diff --git a/resources/assets/vue/components/admin-workflow/elements/QuestionAnswerInnerComponent.vue b/resources/assets/vue/components/admin-workflow/elements/QuestionAnswerInnerComponent.vue new file mode 100644 index 00000000..fc3ca949 --- /dev/null +++ b/resources/assets/vue/components/admin-workflow/elements/QuestionAnswerInnerComponent.vue @@ -0,0 +1,40 @@ + + diff --git a/resources/assets/vue/components/admin-workflow/sections/QuestionAnswerSectionComponent.vue b/resources/assets/vue/components/admin-workflow/sections/QuestionAnswerSectionComponent.vue new file mode 100644 index 00000000..095d7492 --- /dev/null +++ b/resources/assets/vue/components/admin-workflow/sections/QuestionAnswerSectionComponent.vue @@ -0,0 +1,165 @@ + + + + diff --git a/resources/assets/vue/components/general/elements/OpenLinkInNewTabComponent.vue b/resources/assets/vue/components/general/elements/OpenLinkInNewTabComponent.vue index 145dd0f7..b7a92111 100644 --- a/resources/assets/vue/components/general/elements/OpenLinkInNewTabComponent.vue +++ b/resources/assets/vue/components/general/elements/OpenLinkInNewTabComponent.vue @@ -33,6 +33,10 @@ type: Boolean, default: true }, + onClick: { + type: Function, + default: null + } }, data() { return { @@ -75,6 +79,9 @@ }); }, handleClick(){ + if(this.onClick){ + this.url = this.onClick(); + } this.isDownloading = true; if(window.LARAVEL_VAPOR_ENABLED){ this.submit(this.url, 'get', this.section, false, false); diff --git a/resources/assets/vue/vuex/modules/loadRequestQueue.js b/resources/assets/vue/vuex/modules/loadRequestQueue.js index 3bb574c5..2bd794aa 100644 --- a/resources/assets/vue/vuex/modules/loadRequestQueue.js +++ b/resources/assets/vue/vuex/modules/loadRequestQueue.js @@ -14,8 +14,15 @@ export default { getListDetails: (state) => (name) => { return state.queue.find(list => list.name === name); }, + // getListData: (state, getters) => (name) => { + // return (!getters.isInCompleteQueue()) ? state.queue.find(list => list.name === name).data : []; + // }, getListData: (state, getters) => (name) => { - return (!getters.isInCompleteQueue()) ? state.queue.find(list => list.name === name).data : []; + if (!getters.isInCompleteQueue(name)) { + const list = state.queue.find(list => list.name === name); + return list ? list.data : []; + } + return []; }, getSelectableList: (state, getters) => (name) => { let list = state.queue.find(list => list.name === name); @@ -68,4 +75,4 @@ export default { store.commit('SET_LIST_COMPLETE', {name: payload.name, data: payload.data}); } } -} \ No newline at end of file +} diff --git a/resources/views/pages/admin-workflow/list-workflow.blade.php b/resources/views/pages/admin-workflow/list-workflow.blade.php new file mode 100644 index 00000000..d7f54663 --- /dev/null +++ b/resources/views/pages/admin-workflow/list-workflow.blade.php @@ -0,0 +1,14 @@ +@extends('layouts.base_portal') +@section('inner_content') + + +
+
+ +
+
+@endsection diff --git a/routes/admin_workflow.php b/routes/admin_workflow.php index 8c2f535d..13a1f5d7 100644 --- a/routes/admin_workflow.php +++ b/routes/admin_workflow.php @@ -5,7 +5,7 @@ use App\Classes\Modules\Accounts\Services\CreatesKeyValuePair; use App\Classes\ValueObjects\Constants\ApprovalStatus; use App\Classes\ValueObjects\Constants\TransactionType; use App\Classes\ValueObjects\Constants\BookingAttributeNames; -use App\Http\Controllers\AdminWorkflow\AdminWorkflowBaseController; +use App\Http\Controllers\Questionnaires\AdminWorkflowBaseController; use App\Http\Resources\BookingResource; use App\Models\Booking; use App\Models\KeyValuePair; @@ -44,12 +44,10 @@ if (!function_exists('markedProcessing')) { } } - Route::group(['prefix' => 'admin-work-flow', 'as' => 'admin_work_flow.', 'namespace' => 'AdminWorkFlow'], function () { - +Route::group(['prefix' => 'admin-work-flow', 'as' => 'admin_work_flow.', 'namespace' => 'Questionnaires'], function () { Route::get('/fetch-oldest-order', [AdminWorkflowBaseController::class, 'fetchOldestOrder'])->name('fetch_oldest_order'); - Route::get('/fetch-pending-approved-po', function () { $excludedBookingIds = KeyValuePair::where('owner_type', 'App\Models\Booking') ->where(function ($query) { diff --git a/routes/questionnaires.php b/routes/questionnaires.php index e3749d81..73b1f897 100644 --- a/routes/questionnaires.php +++ b/routes/questionnaires.php @@ -3,7 +3,12 @@ use Illuminate\Support\Facades\Route; Route::group(['prefix' => 'questionnaires', 'as' => 'questionnaires.', 'namespace' => 'Questionnaires'], function () { + Route::get('/list', 'ListQuestionnaireSetController@list')->name('list'); Route::get('/{set_id}', 'FetchQuestionV1AdminWFController@fetch')->name('first.question'); Route::post('/question', 'UpdateNextQuestionV1AdminWFController@fetch')->name('next.question'); - Route::get('/list', 'ListQuestionsAnswersQAController@list')->name('list.questions.answers'); + + Route::group(['prefix' => 'qa', 'as' => 'qa.'], function () { + Route::get('/list', 'ListQuestionsAnswersController@list')->name('list'); + Route::get('/export', '\\App\\Http\\Controllers\\Exports\\ExportQuestionsAnswersController@export')->name('export'); + }); }); diff --git a/routes/web.php b/routes/web.php index a7881fdc..cbb12f93 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1342,4 +1342,9 @@ Route::get('/site.webmanifest', function () { Route::get('/admin-workflow', function () { return view('pages.dashboards.admin_work_flow'); -})->name('admin-work-flow'); +})->name('admin-workflow'); + + +Route::get('/admin-workflow/list', function () { + return view('pages.admin-workflow.list-workflow'); +})->name('admin-workflow.list');