Form_Processor::changeVisitValidationStatus()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 15
nc 3
nop 2
dl 0
loc 21
rs 9.7666
c 0
b 0
f 0
1
<?php
2
/**
3
 Copyright (C) 2018-2020 KANOUN Salim
4
 This program is free software; you can redistribute it and/or modify
5
 it under the terms of the Affero GNU General Public v.3 License as published by
6
 the Free Software Foundation;
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
 Affero GNU General Public Public for more details.
11
 You should have received a copy of the Affero GNU General Public Public along
12
 with this program; if not, write to the Free Software Foundation, Inc.,
13
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14
 */
15
16
/**
17
 * Abstract class to handle review in the system
18
 * Each Study-Visit should extend this abstract class and redifine the two abstract methods
19
 * - saveSpecificForm : Which recieve the raw form and should write data to the specific table of database
20
 * - setVisitValidation : Which should define the rules to change status of review's visit (ex : Wait Adjudication or Done)
21
 * 
22
 * These two methodes will be launched for each new review recieved by the system
23
 * 
24
 * The makeReviewUnavailable() can be overrided to let the visit available for review even if Review status "Done" is reached 
25
 * (by default it will no longer accept new review after reaching this status)
26
 * @author salim
27
 *
28
 */
29
30
abstract class Form_Processor {
31
	
32
	protected $linkpdo;
33
	protected $visitObject;
34
	protected $study;
35
	protected $id_visit;
36
	protected $specificTable;
37
	protected $local;
38
	private $username;
39
	protected $reviewStatus;
40
	protected $reviewAvailable;
41
	public $reviewObject;
42
	protected $rawDataForm;
43
	
44
	function __construct(Visit $visitObject, bool $local, string $username, PDO $linkpdo) {
45
		$this->linkpdo=$linkpdo;
46
		$this->local=$local;
47
		$this->username=$username;
48
		
49
		$this->visitObject=$visitObject;
50
		$this->id_visit=$visitObject->id_visit;
51
		$visitCharacteristics=$visitObject->getVisitCharacteristics();
52
		
53
		//Store the table specific name and the current study
54
		$this->specificTable=$visitCharacteristics->tableReviewSpecificName;
55
		$this->study=$visitObject->study;
56
		//Store the review status
57
		$this->reviewStatus=$visitObject->reviewStatus;
58
		$this->reviewAvailable=$visitObject->reviewAvailable;
59
60
		$this->loadSavedForm();
61
	}
62
	
63
	/**
64
	 * Save the  form in the specific table as specified in the child dedicated objet who will extend this class
65
	 * @param $data :Post data from the dedicated from
0 ignored issues
show
Documentation Bug introduced by
The doc comment :Post at position 0 could not be parsed: Unknown type name ':' at position 0 in :Post.
Loading history...
66
	 * @param $id_Review : current Id review
67
	 * @param $specificTable : name of the specific table for the study-visit
68
	 * @param $update : if review already exists (draft), value is true (if true make update, if false make insert)
69
	 */
70
	abstract protected function saveSpecificForm($data, $id_review, $update);
71
	
72
	/**
73
	 * Set the visit status after review (Not Done, adjudication, Done), need to be redifined in the child object
74
	 */
75
	abstract public function setVisitValidation();
76
	
77
	/*
78
	 * Create new entry in review table
79
	 */
80
	protected function createReview() {
81
		$this->reviewObject=Review::createReview($this->id_visit, $this->username, $this->local,
82
			($this->reviewStatus == Visit::REVIEW_WAIT_ADJUDICATION), $this->linkpdo);
83
	}
84
	
85
	/**
86
	 * Set review status as draft (validate = false) or validated (validate=true)
87
	 * This methods is triggered by the system at form submission and call the save specific form
88
	 * to define which value need to be written in the specific table
89
	 */
90
	public function saveForm($data, bool $validate) {
91
	    
92
		$this->rawDataForm=$data;
93
	    
94
		//If reviewer check that review is available before saving process
95
		if (!$this->local && !$this->reviewAvailable) {
96
			return;
97
		}
98
		
99
		//Get saved form, return either local form or reviewer's users form if exist
100
		//or null if not existing
101
		
102
		if (empty($this->reviewObject)) {
103
			$this->createReview();
104
			$update=false;       
105
		}else {
106
			$update=true;
107
			//If already existing validated review, exit without modifying anything
108
			if ($this->reviewObject->validated) {
109
				return;
110
			}
111
	       
112
		}
113
	    
114
		//Call the child redifined save specific form to save the specific data of the form
115
		try {
116
			$this->saveSpecificForm($data, $this->reviewObject->id_review, $update);
117
		}catch (Exception $e) {
118
			error_log($e->getMessage());
119
			if (!$update) {
120
				$this->reviewObject->hardDeleteReview();
121
			}
122
			throw new Exception("Error during save");
123
		}
124
125
		if($update){
126
			$this->reviewObject->updateReviewDate();
127
		}
128
		
129
		if ($validate) {
130
			$this->reviewObject->changeReviewValidationStatus($validate);
131
		}
132
		//update the visit status if we are processing a local form
133
		if ($this->local) {
134
			if ($validate) {
135
				$this->visitObject->changeVisitStateInvestigatorForm(Visit::LOCAL_FORM_DONE);
136
			}else {
137
				$this->visitObject->changeVisitStateInvestigatorForm(Visit::LOCAL_FORM_DRAFT);
138
			}
139
		}
140
		
141
		//Log Activity
142
		if ($this->local) {
143
			$role="Investigator";
144
		}else {
145
			$role="Reviewer";
146
		}
147
		$actionDetails['patient_code']=$this->visitObject->patientCode;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$actionDetails was never initialized. Although not strictly required by PHP, it is generally a good practice to add $actionDetails = array(); before regardless.
Loading history...
148
		$actionDetails['type_visit']=$this->visitObject->visitType;
149
		$actionDetails['modality_visit']=$this->visitObject->visitGroupObject->groupModality;
150
		$actionDetails['id_review']=$this->reviewObject->id_review;
151
		$actionDetails['associated_files']=$this->reviewObject->associatedFiles;
152
		$actionDetails['local_review']=intval($this->local);
153
		$actionDetails['adjudication']=intval($this->reviewStatus == Visit::REVIEW_WAIT_ADJUDICATION);
154
		$actionDetails['create']=!$update;
155
		$actionDetails['raw_data']=$data;
156
		
157
		Tracker::logActivity($this->username, $role, $this->study, $this->id_visit, "Save Form", $actionDetails);
158
		
159
		//If central review still not at "Done" status Check if validation is reached
160
		if ($validate && !$this->local && $this->reviewStatus != Visit::REVIEW_DONE) {
161
			$this->setVisitValidation();
162
		}
163
		
164
	}
165
	
166
	/**
167
	 * update the review conclusion of the visit, pass decision in argument
168
	 * and trigger the review availability decision method
169
	 * @param $reviewConclusion : constant value from this clas
0 ignored issues
show
Documentation Bug introduced by
The doc comment : constant at position 0 could not be parsed: Unknown type name ':' at position 0 in : constant.
Loading history...
170
	 * @param string $reviewStatus
171
	 * @param $conclusionValue
172
	 */
173
	protected function changeVisitValidationStatus(string $reviewStatus, $conclusionValue="N/A") {
174
		$this->visitObject->changeVisitValidationStatus($reviewStatus, $conclusionValue);
175
		$this->reviewAvailabilityDecision($reviewStatus);
176
177
		//Send Notification emails
178
		if ($reviewStatus == Visit::REVIEW_WAIT_ADJUDICATION) {
179
180
			$email=new Send_Email($this->linkpdo);
181
			$email->addEmailsReviewerWithNoReview($this->visitObject->study, $this->id_visit)
182
					->addGroupEmails($this->visitObject->study, User::SUPERVISOR);
183
			$email->sendAwaitingAdjudicationMessage($this->visitObject->study, $this->visitObject->patientCode, $this->visitObject->visitType);
184
185
		}else if ($reviewStatus == Visit::REVIEW_DONE) {
186
187
			$email=new Send_Email($this->linkpdo);
188
			$uploaderUserObject=new User($this->visitObject->uploaderUsername, $this->linkpdo);
189
			$uploaderEmail=$uploaderUserObject->userEmail;
190
			$email->addGroupEmails($this->visitObject->study, User::MONITOR)
191
					->addGroupEmails($this->visitObject->study, User::SUPERVISOR)
192
					->addEmail($uploaderEmail);
193
			$email->sendVisitConcludedMessage($this->visitObject->study, $this->visitObject->patientCode, $this->visitObject->visitType, $conclusionValue);
194
195
		}
196
	}
197
	
198
	/**
199
	 * Return the saved form of the current user.
200
	 * Used to fill the form at display
201
	 * @return array of the general and specific table
202
	 */
203
	public function loadSavedForm() {
204
		try {
205
			if ($this->local) {
206
				$this->reviewObject=$this->visitObject->getReviewsObject(true);
207
			}else {
208
				$this->reviewObject=$this->visitObject->queryExistingReviewForReviewer($this->username);
209
			}
210
211
		}catch (Exception $e) { }
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
212
	    
213
		return $this->reviewObject;
214
		
215
	}
216
	
217
	/**
218
	 * return all reviews (local and reviewer) of the current visit
219
	 * Usefull to determine visit conclusion status
220
	 */
221
	public function getAllValidatedFormsOfVisit() {
222
	    
223
		$query=$this->linkpdo->prepare('SELECT * FROM reviews,'.$this->specificTable.' WHERE reviews.id_review='.$this->specificTable.'.id_review AND reviews.id_visit=:idVisit AND reviews.validated=1 AND reviews.deleted=0');
224
		$query->execute(array(
225
			'idVisit'=>$this->id_visit
226
		));
227
		$datas=$query->fetchAll(PDO::FETCH_ASSOC);
228
		return $datas;
229
	}
230
231
	/**
232
	 * Return of validated review object (no local form)
233
	 */
234
	public function getValidatedReviewObjects() : array {
235
		$reviewsObject=$this->visitObject->getReviewsObject(false);
236
		//Filter only validated review that will be analyzed
237
		$validatedReviewObjects=array_filter($reviewsObject, function($review) {
238
			if ($review->validated) {
239
				return true;
240
			}else {
241
				return false;
242
			}
243
		});
244
		//Reindex results from index zero
245
		$validatedReviewObjects=array_values($validatedReviewObjects);
246
247
		return $validatedReviewObjects;
248
	}
249
	
250
	/**
251
	 * Get existing form for current user
252
	 * can be overrided to add additional data such as investigator form data
253
	 */
254
	public function getExistingFormData() {
255
		if( ! empty($this->reviewObject)){
256
			return ($this->reviewObject->getSpecificData());
257
		}else{
258
			return [];
259
		}
260
		
261
	}
262
	
263
	/**
264
	 * When Review conclusion "Done" reached Will make review unavailable for new review
265
	 * Can be overided if needed different condition
266
	 * @param string $reviewConclusion
267
	 */
268
	protected function reviewAvailabilityDecision(string $reviewConclusion) {
269
		//If Done reached make the review unavailable for review
270
		if ($reviewConclusion == Visit::REVIEW_DONE) {
271
			$this->visitObject->changeReviewAvailability(false);
272
		}
273
		//Needed in case of deletion of a review (even if true by default initialy, need to come back if deletion)
274
		else {
275
			$this->visitObject->changeReviewAvailability(true);
276
		}
277
	}
278
	
279
}