Files
exchange-2.0/app/Classes/Modules/Questionnaires/ControllersLogic/UpdateNextQuestionV1AdminWFLogic.php
T
2025-02-23 22:04:15 +08:00

186 lines
8.2 KiB
PHP

<?php
namespace App\Classes\Modules\Questionnaires\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
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\Processors\SaveAnswerActionV1AdminWFProcessor;
use App\Classes\Modules\Questionnaires\Processors\FetchNextQuestionMetadataV1AdminWFProcessor;
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;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Auth;
use App\Http\Resources\QuestionResource;
use App\Models\Booking;
use App\Models\QAQuestions;
class UpdateNextQuestionV1AdminWFLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Retrieved Admin Workflow Next Question',
'message' => 'You have successfully retrieved a Admin Workflow Next Question'
];
}
/** @var CanFetchQuestion */
private $canFetchQuestion;
/** @var SaveAnswerV1AdminWFProcessor */
private $saveAnswerProcessor;
/** @var SaveAnswerActionV1AdminWFProcessor */
private $saveAnswerActionProcessor;
/** @var FetchNextQuestionV1AdminWFProcessor */
private $fetchNextQuestionV1AdminWFProcessor;
/** @var FetchNextQuestionMetadataV1AdminWFProcessor */
private $fetchNextQuestionMetadataProcessor;
/** @var FetchFirstQuestionV1AdminWFProcessor */
private $fetchFirstQuestionQAProcessor;
/** @var ListsQuestionUserAnswerSelected */
private $listsUserAnswerSelected;
/** @var CreatesKeyValuePair */
private $createsKeyValuePair;
/**
* UpdateNextQuestionV1AdminWFLogic constructor.
* @param CanFetchQuestion $canFetchQuestion
* @param SaveAnswerV1AdminWFProcessor $saveAnswerProcessor
* @param FetchNextQuestionV1AdminWFProcessor $fetchNextQuestionV1AdminWFProcessor
* @param FetchFirstQuestionV1AdminWFProcessor $fetchFirstQuestionQAProcessor
* @param ListsQuestionUserAnswerSelected $listsUserAnswerSelected
* @param CreatesKeyValuePair $createsKeyValuePair
* @param SaveAnswerActionV1AdminWFProcessor $saveAnswerActionProcessor
* @param FetchNextQuestionMetadataV1AdminWFProcessor $fetchNextQuestionMetadataProcessor
*/
public function __construct(CanFetchQuestion $canFetchQuestion, SaveAnswerV1AdminWFProcessor $saveAnswerProcessor, FetchNextQuestionV1AdminWFProcessor $fetchNextQuestionV1AdminWFProcessor, FetchFirstQuestionV1AdminWFProcessor $fetchFirstQuestionQAProcessor, ListsQuestionUserAnswerSelected $listsUserAnswerSelected, CreatesKeyValuePair $createsKeyValuePair, SaveAnswerActionV1AdminWFProcessor $saveAnswerActionProcessor, FetchNextQuestionMetadataV1AdminWFProcessor $fetchNextQuestionMetadataProcessor)
{
$this->canFetchQuestion = $canFetchQuestion;
$this->saveAnswerProcessor = $saveAnswerProcessor;
$this->fetchNextQuestionV1AdminWFProcessor = $fetchNextQuestionV1AdminWFProcessor;
$this->fetchFirstQuestionQAProcessor = $fetchFirstQuestionQAProcessor;
$this->listsUserAnswerSelected = $listsUserAnswerSelected;
$this->createsKeyValuePair = $createsKeyValuePair;
$this->saveAnswerActionProcessor = $saveAnswerActionProcessor;
$this->fetchNextQuestionMetadataProcessor = $fetchNextQuestionMetadataProcessor;
}
/**
* @param Request $request
* @return JsonResponse
* @throws MalformedRequestException
* @throws ResourceNotFoundException
*/
public function logic(Request $request) : JsonResponse
{
$userId = Auth::user()->id;
$timeUsedSeconds = 0;
$reference = null;
$questionMetadata = null;
$booking = null;
$previousAnswer = null;
$this->canFetchQuestion->passes();
$currentQuestion = $request->question;
$filesUpload = $request->only(['files', 'filesA', 'filesB', 'filesC']);
if ($request->has('questionContext')) {
$questionMetadata = $request->questionContext['questionMetadata'] ?? null;
$timeUsedSeconds = intval($request->questionContext['timeUsedSeconds']) ?? 0;
$reference = $request->questionContext['session_id'];
$booking = $questionMetadata ? Booking::where('id', $questionMetadata['id'])->first() : null;
}
//Save answer given by user (both next and previous)
$answerOptionId = 0;
if ($request->has('answerObj')) {
$answerOptionId = intval($request->answerObj['id']);
}
$this->saveAnswerProcessor->execute($userId, 0, $currentQuestion, $questionMetadata, $request->answer, $answerOptionId, $filesUpload, $timeUsedSeconds, $request->has('isPrevious'), $reference);
if(!$request->has('isPrevious')){
$this->saveAnswerActionProcessor->execute($booking, $questionMetadata, $answerOptionId, $currentQuestion, $filesUpload);
}
if ($request->has('questionContext')) {
$previousAnswer = $this->listsUserAnswerSelected->execute(['user_id' => $userId, 'reference' => $reference, 'is_previous' => 0, 'order_by' => (object)['column' => 'id','DESC' => true]])[0];
}
if($booking){
$this->markBookingAsProcessed($booking, $request->has('isPrevious'), $currentQuestion);
}
//Get returned question (previous or next) and additional metadata if applicable
$returnQuestion = $this->fetchNextQuestionV1AdminWFProcessor->execute($currentQuestion, $request->answerObj, $request->questionContext, $previousAnswer, $booking, $request->has('isPrevious'));
$questionMetadata = $this->fetchNextQuestionMetadataProcessor->execute($returnQuestion, $questionMetadata);
//When a questionnaire ended, return back the first question
if(is_null($returnQuestion)){
$returnQuestion = $this->fetchFirstQuestionQAProcessor->execute($request);
}
return $this->resourceResponse(new QuestionResource($returnQuestion, $userId, $request->has('isPrevious'), $this->isNoGoingBack($returnQuestion), $previousAnswer, $questionMetadata));
}
private function markBookingAsProcessed(Booking $booking, bool $isPrevious, array $currentQuestion){
//Marked data that has already been processed so that it does not appear again
if($currentQuestion && $currentQuestion['is_end'] === 1 && !$isPrevious){
$key1 = "admin_workflow_processed";
$key2 = "admin_workflow_processing";
if (strpos($currentQuestion['question_number'], '1688') === 0) {
$key1 = '1688_'.$key1;
$key2 = '1688_'.$key2;
}
if (strpos($currentQuestion['question_number'], 'fill_po') === 0) {
$key1 = 'xfill_po_'.$key1;
$key2 = 'xfill_po_'.$key2;
}
if (strpos($currentQuestion['question_number'], 'approve_po') === 0) {
$key1 = 'xapprove_po_'.$key1;
$key2 = 'xapprove_po_'.$key2;
}
$processingRecord = $booking->attributesKVP()->where('key', $key2)->first();
if ($processingRecord) {
$processingRecord->delete();
}
$kvp = $booking->attributesKVP()->where('key', $key1)->first();
if(!$kvp){
$keyValuePairObject = new KeyValuePairObject($key1, true);
$this->createsKeyValuePair->execute($booking, $keyValuePairObject);
}
}
}
private function isNoGoingBack(QAQuestions $returnQuestion){
if($returnQuestion && ($returnQuestion->is_start || $returnQuestion->is_end)){
return 1;
}
else if($returnQuestion && $returnQuestion->is_start === 0 && $returnQuestion && $returnQuestion->is_end === 0){
return 0;
}
return 0;
}
}