hasOne(Pro::class, 'id', 'created_by_pro_id'); } public function childReviews() { return $this->hasMany(Point::class, 'parent_point_id', 'id') ->where('category', 'REVIEW') ->orderBy('created_at', 'DESC'); } public function childReviewAddedInNote($_note) { $review = Point::where('added_in_note_id', $_note->id) ->where('category', 'REVIEW') ->where('parent_point_id', $this->id) ->orderBy('created_at', 'DESC') ->first(); if(!!$review) { $review->data = json_decode($review->data); } return $review; } public function childPlanAddedInNote($_note) { $review = Point::where('added_in_note_id', $_note->id) ->where('category', 'PLAN') ->where('parent_point_id', $this->id) ->orderBy('created_at', 'DESC') ->first(); if(!!$review) { $review->data = json_decode($review->data); } return $review; } public function lastChildReview() { return $this->hasOne(Point::class, 'id', 'last_child_review_point_id'); } public function lastChildReviewNote() { return $this->hasOne(Note::class, 'id', 'last_child_review_point_scoped_note_id'); } public function childPlans() { return $this->hasMany(Point::class, 'parent_point_id', 'id') ->where('category', 'PLAN') ->orderBy('created_at', 'DESC'); } public function lastChildPlan() { return $this->hasOne(Point::class, 'id', 'last_child_plan_point_id'); } public function lastChildPlanNote() { return $this->hasOne(Note::class, 'id', 'last_child_plan_point_scoped_note_id'); } public function coreChildReview() { return $this->hasOne(Point::class, 'id', 'core_child_review_point_id'); } public function coreChildPlan() { return $this->hasOne(Point::class, 'id', 'core_child_plan_point_id'); } public function parentPoint() { return $this->hasOne(Point::class, 'id', 'parent_point_id'); } public function client() { return $this->hasOne(Client::class, 'id', 'client_id'); } public function note() { return $this->hasOne(Note::class, 'id', 'added_in_note_id'); } public function relevanceToNote($_note) { return NotePoint ::where('is_active', true) ->where('note_id', $_note->id) ->where('point_id', $this->id) ->first(); } // NOTE: $point is not a point instance - but a raw object containing point data public static function getCurrentAndPreviousChildReviews($point, $note) { $current = null; $previous = null; $point = Point::where('id', $point->id)->first(); if ($point->lastChildReview) { if ($point->last_child_review_point_scoped_note_id === $note->id) { if($point->lastChildReview->data) { $current = $point->lastChildReview; $current->data = json_decode($current->data); } $previous = \App\Models\Point::where('id', '<', $point->lastChildReview->id) ->where('category', 'REVIEW') ->where('parent_point_id', $point->id) ->orderBy('id', 'DESC') ->first(); if($previous && $previous->data) { $previous->data = json_decode($previous->data); } } else { if($point->lastChildReview->data) { $previous = $point->lastChildReview; $previous->data = json_decode($previous->data); } } } return [$current, $previous]; } // NOTE: $point is not a point instance - but a raw object containing point data public static function getCurrentAndPreviousChildPlans($point, $note) { $current = null; $previous = null; $point = Point::where('id', $point->id)->first(); if ($point->lastChildPlan) { if ($point->last_child_plan_point_scoped_note_id === $note->id) { if($point->lastChildPlan->data) { $current = $point->lastChildPlan; $current->data = json_decode($current->data); } $previous = \App\Models\Point::where('id', '<', $point->lastChildPlan->id) ->where('category', 'PLAN') ->where('parent_point_id', $point->id) ->orderBy('id', 'DESC') ->first(); if($previous && $previous->data) { $previous->data = json_decode($previous->data); } } else { if($point->lastChildPlan->data) { $previous = $point->lastChildPlan; $previous->data = json_decode($previous->data); } } } return [$current, $previous]; } public static function getGlobalSingletonOfCategory(Client $_patient, String $_category, $_assoc = false) { $point = Point ::where('client_id', $_patient->id) ->where('category', $_category) ->orderBy('created_at', 'DESC') ->first(); if ($point && @$point->data) { $point->data = json_decode($point->data, $_assoc); } return $point; } public static function getIntakePointsOfCategory(Client $_patient, String $_category, Note $_note, $_assoc = false) { $points = Point ::where('client_id', $_patient->id) ->where('category', $_category) ->where('is_removed_due_to_entry_error', false) ->whereRaw("(is_removed = TRUE OR addition_reason_category != 'DURING_VISIT' OR added_in_note_id != {$_note->id})") ->where(function ($query1) use ($_note) { $query1 ->where(function ($query2) use ($_note) { $query2->where('is_removed', false) ->where('addition_reason_category', 'ON_INTAKE') ->where('added_in_note_id', $_note->id); }) ->orWhere(function ($query2) use ($_note) { $query2->where('is_removed', true) ->where('removal_reason_category', 'ON_INTAKE') ->where('removed_in_note_id', $_note->id); }) ->orWhere('last_child_review_point_scoped_note_id', $_note->id) ->orWhereRaw("(SELECT count(id) from note_point WHERE is_active Is TRUE AND note_id = {$_note->id} AND point_id = point.id) > 0"); }) ->orderBy('created_at') ->get(); foreach ($points as $point) { if ($point->data) { $point->data = json_decode($point->data, $_assoc); } } return $points; } public static function getIntakePoints(Client $_patient, Note $_note, $_assoc = false) { $points = Point ::where('client_id', $_patient->id) ->where('is_removed_due_to_entry_error', false) ->whereRaw("(is_removed = TRUE OR addition_reason_category != 'DURING_VISIT' OR added_in_note_id != {$_note->id})") ->where(function ($query1) use ($_note) { $query1 ->where(function ($query2) use ($_note) { $query2->where('is_removed', false) ->where('addition_reason_category', 'ON_INTAKE') ->where('added_in_note_id', $_note->id); }) ->orWhere(function ($query2) use ($_note) { $query2->where('is_removed', true) ->where('removal_reason_category', 'ON_INTAKE') ->where('removed_in_note_id', $_note->id); }) ->orWhere('last_child_review_point_scoped_note_id', $_note->id) ->orWhereRaw("(SELECT count(id) from note_point WHERE is_active Is TRUE AND note_id = {$_note->id} AND point_id = point.id) > 0"); }) ->orderBy('created_at') ->get(); foreach ($points as $point) { if ($point->data) { $point->data = json_decode($point->data, $_assoc); } } return $points; } public static function getIntakePointsWithChildReview(Client $_patient, Note $_note, $_assoc = false) { $points = Point ::where('client_id', $_patient->id) ->where('is_removed_due_to_entry_error', false) ->whereRaw("(is_removed = TRUE OR addition_reason_category != 'DURING_VISIT' OR added_in_note_id != {$_note->id})") ->where(function ($query1) use ($_note) { $query1 ->where('last_child_review_point_scoped_note_id', $_note->id) ->orWhereRaw("(SELECT count(id) from note_point WHERE is_active IS TRUE AND note_id = {$_note->id} AND point_id = point.id) > 0"); }) ->orderBy('created_at') ->get(); foreach ($points as $point) { if ($point->data) { $point->data = json_decode($point->data, $_assoc); } } return $points; } public static function getPlanPointsOfCategory(Client $_patient, String $_category, Note $_note, $_assoc = false) { $points = Point ::where('client_id', $_patient->id) ->where('category', $_category) ->where('is_removed_due_to_entry_error', false) ->where(function ($query1) use ($_note) { $query1 ->where(function ($query2) use ($_note) { $query2->where('is_removed', false) ->where('addition_reason_category', 'DURING_VISIT') ->where('added_in_note_id', $_note->id); }) ->orWhere(function ($query2) use ($_note) { $query2->where('is_removed', true) ->where('removal_reason_category', 'DURING_VISIT') ->where('removed_in_note_id', $_note->id); }) ->orWhere('last_child_plan_point_scoped_note_id', $_note->id) ->orWhereRaw("(SELECT count(id) from note_point WHERE is_active IS TRUE AND note_id = {$_note->id} AND point_id = point.id) > 0"); }) ->orderBy('created_at') ->get(); foreach ($points as $point) { if ($point->data) { $point->data = json_decode($point->data, $_assoc); } } return $points; } public static function getPlanPoints(Client $_patient, Note $_note, $_assoc = false) { $points = Point ::where('client_id', $_patient->id) ->where('is_removed_due_to_entry_error', false) ->where(function ($query1) use ($_note) { $query1 ->where(function ($query2) use ($_note) { $query2->where('is_removed', false) ->where('addition_reason_category', 'DURING_VISIT') ->where('added_in_note_id', $_note->id); }) ->orWhere(function ($query2) use ($_note) { $query2->where('is_removed', true) ->where('removal_reason_category', 'DURING_VISIT') ->where('removed_in_note_id', $_note->id); }) ->orWhere('last_child_plan_point_scoped_note_id', $_note->id) ->orWhereIn('category', ['WEIGHT_LOSS_INTAKE']); }) ->orderBy('created_at') ->get(); foreach ($points as $point) { if ($point->data) { $point->data = json_decode($point->data, $_assoc); } } return $points; } public static function getUnifiedPointsOfCategory(Client $_patient, String $_category, Note $_note, $_assoc = false) { $points = Point ::where('client_id', $_patient->id) ->where('category', $_category) ->where('is_removed_due_to_entry_error', false) ->where(function ($query1) use ($_note) { $query1 ->where(function ($query2) use ($_note) { // added on_intake on this note $query2->where('is_removed', false) ->where('addition_reason_category', 'ON_INTAKE') ->where('added_in_note_id', $_note->id); }) ->orWhere(function ($query2) use ($_note) { // removed on_intake on this note $query2->where('is_removed', true) ->where('removal_reason_category', 'ON_INTAKE') ->where('removed_in_note_id', $_note->id); }) ->orWhere('last_child_review_point_scoped_note_id', $_note->id) // review added during this note ->orWhere(function ($query2) use ($_note) { // added during_visit on this note $query2->where('is_removed', false) ->where('addition_reason_category', 'DURING_VISIT') ->where('added_in_note_id', $_note->id); }) ->orWhere(function ($query2) use ($_note) { // removed during_visit on this note $query2->where('is_removed', true) ->where('removal_reason_category', 'DURING_VISIT') ->where('removed_in_note_id', $_note->id); }) ->orWhere('last_child_plan_point_scoped_note_id', $_note->id) // plan added during this note // marked relevant to this note ->orWhereRaw("(SELECT count(id) from note_point WHERE is_active IS TRUE AND note_id = {$_note->id} AND point_id = point.id) > 0"); }) ->orderBy('created_at') ->get(); foreach ($points as $point) { if ($point->data) { $point->data = json_decode($point->data, $_assoc); } } return $points; } public static function getPointsOfCategory(Client $_patient, String $_category, $_assoc = false) { $points = Point ::where('client_id', $_patient->id) ->where('category', $_category) ->where('is_removed', false) ->orderBy('created_at') ->get(); foreach ($points as $point) { if ($point->data) { $point->data = json_decode($point->data, $_assoc); } } return $points; } public static function getPointsOfCategoryExceptEntryError(Client $_patient, Note $_note, String $_category, $_assoc = false) { $points = Point ::where('client_id', $_patient->id) ->where('category', $_category) ->where(function ($query2) use ($_note) { $query2->where('is_removed', false) ->orWhereRaw("(is_removed_due_to_entry_error IS NOT TRUE AND ((SELECT count(id) from note_point WHERE is_active IS TRUE AND note_id = {$_note->id} AND point_id = point.id) > 0))"); }) ->orderBy('created_at') ->get(); foreach ($points as $point) { if ($point->data) { $point->data = json_decode($point->data, $_assoc); } } return $points; } public static function getNumPointsOfCategory(Client $_patient, String $_category) { return Point ::where('client_id', $_patient->id) ->where('category', $_category) ->where('is_removed', false) ->count(); } public static function getPointsOfCategoryExtended(Client $_patient, String $_category, Note $_note, $excludeEntryError = false) { $points = Point ::where('client_id', $_patient->id) ->where('category', $_category); if($excludeEntryError) { $points = $points->where('is_removed_due_to_entry_error', FALSE); } if($_category !== 'GOAL') { $points = $points->orderByRaw("((data)::json->'name')::text ASC"); } else { $points = $points->orderByRaw("((data)::json->'goal')::text ASC"); } $points = $points->get(); $pointsByType = [ "ACTIVE" => [], "HISTORIC" => [], "ENTRY_ERROR" => [], ]; foreach ($points as $point) { if ($point->data) { $point->data = json_decode($point->data); } if(!$point->is_removed) { $point->state = "ACTIVE"; $pointsByType["ACTIVE"][] = $point; } elseif($point->is_removed) { if(!$point->is_removed_due_to_entry_error) { $point->state = "HISTORIC"; $pointsByType["HISTORIC"][] = $point; } else { $point->state = "ENTRY_ERROR"; $pointsByType["ENTRY_ERROR"][] = $point; } } } $points = array_merge($pointsByType["ACTIVE"], $pointsByType["HISTORIC"], $pointsByType["ENTRY_ERROR"]); return [ $points, [ "ACTIVE" => count($pointsByType["ACTIVE"]), "HISTORIC" => count($pointsByType["HISTORIC"]), "ENTRY_ERROR" => count($pointsByType["ENTRY_ERROR"]), ] ]; } public static function getOnlyPointOfCategory(Client $_patient, String $_category) { $point = Point ::where('client_id', $_patient->id) ->where('category', $_category) ->first(); if ($point && $point->data) { $point->data = json_decode($point->data); } return $point; } public static function getOnlyTopLevelPointOfCategory(Note $_note, String $_category, $_assoc = false) { $point = Point ::where('client_id', $_note->client_id) ->where('category', $_category) ->where('intention', 'TOP_LEVEL') ->first(); if ($point && $point->data) { $point->data = json_decode($point->data, $_assoc); } return $point; } public static function getOrCreateOnlyTopLevelPointOfCategory(Note $_note, String $_category, $_sessionKey, $_assoc = false) { $point = Point ::where('client_id', $_note->client_id) ->where('category', $_category) ->where('intention', 'TOP_LEVEL') ->first(); if(!$point) { $response = callJava('/visitPoint/addTopLevel', [ "category" => $_category, "data" => '{}', "noteUid" => $_note->uid, "additionReasonCategory" => 'ON_INTAKE', ], $_sessionKey); // TODO: dont assume success $point = Point ::where('client_id', $_note->client_id) ->where('category', $_category) ->where('intention', 'TOP_LEVEL') ->first(); } if ($point && $point->data) { $point->data = json_decode($point->data, $_assoc); } return $point; } public static function fillPointStateAndBadge(Point $point, Note $note) { // state if (!$point->is_removed) { $point->state = "ACTIVE"; } elseif ($point->is_removed) { if (!$point->is_removed_due_to_entry_error) { $point->state = "HISTORIC"; } else { $point->state = "ENTRY_ERROR"; } } // added/removed info if ($point->state === 'ACTIVE') { if ($point->added_in_note_id === $note->id && $point->addition_reason_category === 'DURING_VISIT') { $point->badge = 'Added During Visit'; } elseif ($point->added_in_note_id === $note->id && $point->addition_reason_category === 'ON_INTAKE') { $point->badge = 'New Record - Pre-existing'; } elseif ($point->added_in_note_id !== $note->id) { $point->badge = 'Record Present Before Visit'; } } elseif ($point->state === 'HISTORIC') { if ($point->removed_in_note_id === $note->id && $point->removal_reason_category === 'DURING_VISIT') { $point->badge = 'Removed During Visit'; } elseif ($point->removed_in_note_id === $note->id && $point->removal_reason_category === 'ON_INTAKE') { $point->badge = 'Marked Historic'; } elseif ($point->removed_in_note_id !== $note->id) { $point->badge = 'Historic Record Removed in a Previous Visit'; } } elseif ($point->state === 'ENTRY_ERROR') { if ($point->removed_in_note_id === $note->id) { $point->badge = 'Marked as Entry Error During Visit'; } } return $point; } }