610 lines
24 KiB
PHP
Executable File
610 lines
24 KiB
PHP
Executable File
<?php
|
||
|
||
namespace App\Http\Controllers;
|
||
|
||
|
||
use App\HealthCareSheetType;
|
||
use App\InsuranceState;
|
||
use App\InsuranceSubscriptionState;
|
||
use App\Models\AgentPlus;
|
||
use App\Models\NhAct;
|
||
use App\Models\NhDrugsAndDevice;
|
||
use App\Models\NhExam;
|
||
use App\Models\NhHealthCareSheet;
|
||
use App\Models\NhHealthCareSheetsExam;
|
||
use App\Models\NhHealthCareSheetsHistory;
|
||
use App\Models\NhHealthCareSheetsPerformance;
|
||
use App\Models\NhHealthCareSheetsPrescription;
|
||
use App\Models\NhInsurance;
|
||
use App\Models\NhInsurancesSubscription;
|
||
use App\Models\NhMedicalPrescription;
|
||
use App\Models\NhNetworksConfig;
|
||
use App\Models\NhPerformance;
|
||
use App\Models\NhProviderClass;
|
||
use App\Traits\ApiResponser;
|
||
use App\Traits\Helper;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Illuminate\Support\Facades\Log;
|
||
use Throwable;
|
||
|
||
class HealthCareSheetController extends Controller
|
||
{
|
||
use ApiResponser;
|
||
use Helper;
|
||
|
||
/**
|
||
* @OA\Get(
|
||
* path="/drugs-and-devices",
|
||
* summary="Rechercher les medicaments / appareillaages ( par reseau et par nom)",
|
||
* tags={"Médicaments / Appareillages"},
|
||
* security={{"api_key":{}}},
|
||
* @OA\Parameter(
|
||
* parameter="network_id",
|
||
* name="network_id",
|
||
* description="ID du reseau",
|
||
* @OA\Schema(
|
||
* type="integer",
|
||
* default = 250
|
||
* ),
|
||
* in="query",
|
||
* required=true
|
||
* ),
|
||
* @OA\Parameter(
|
||
* parameter="name",
|
||
* name="name",
|
||
* description="Nom du médicament / appareillage",
|
||
* @OA\Schema(
|
||
* type="string"
|
||
* ),
|
||
* in="query",
|
||
* required=true
|
||
* ),
|
||
* @OA\Response(
|
||
* response=200,
|
||
* description="OK",
|
||
* @OA\JsonContent(
|
||
* ref="#/components/schemas/ApiResponse",
|
||
* example = {
|
||
* "status" : 200,
|
||
* "response" : {{"id":2,"network_id":250,"code":"ABD","name":"Nivaquine","type":"Comprimé",
|
||
* "on_prescription":false,"created_at":"2021-11-16T09:13:30.000000Z","updated_at":"2021-11-16T09:13:30.000000Z"}},
|
||
* "error":null
|
||
* }
|
||
* )
|
||
* )
|
||
* )
|
||
*/
|
||
public function getDrugsAndDevices(Request $request)
|
||
{
|
||
$this->validate($request, [
|
||
'network_id' => 'required|integer',
|
||
'name' => 'required|string'
|
||
]);
|
||
|
||
$drugs = NhDrugsAndDevice::where('network_id', $request->input('network_id'))
|
||
->where('name', 'like', '%' . $request->input('name') . '%')->get();
|
||
return $this->successResponse($drugs);
|
||
}
|
||
|
||
/**
|
||
* @OA\Post(
|
||
* path="/drugs-and-devices",
|
||
* summary="Ajouter les medicaments / appareillages",
|
||
* tags={"Médicaments / Appareillages"},
|
||
* security={{"api_key":{}}},
|
||
* @OA\RequestBody(
|
||
* description="Corps de la requete",
|
||
* required=true,
|
||
* @OA\MediaType(
|
||
* mediaType="application/json",
|
||
* @OA\Schema(
|
||
* @OA\Property(
|
||
* property="network_id",
|
||
* description = "ID du reseau",
|
||
* type="integer",
|
||
* example= 250
|
||
* ),
|
||
* @OA\Property(
|
||
* property="code",
|
||
* description = "Code du médicament / appareillage",
|
||
* type="string",
|
||
* example= "ABD"
|
||
* ),
|
||
* @OA\Property(
|
||
* property="name",
|
||
* description = "Nom du médicament / appareillage",
|
||
* type="string",
|
||
* example= "Nivaquine"
|
||
* ),
|
||
* @OA\Property(
|
||
* property="type",
|
||
* description = "Type de médicament / appareillage",
|
||
* type="string",
|
||
* enum={"COMPRESSED","SYRUP","SOLUTION","SUPPOSITORY","DEVICE"},
|
||
* example= "COMPRESSED"
|
||
* ),
|
||
* @OA\Property(
|
||
* property="on_prescription",
|
||
* description = "Sous ordornance ou pas",
|
||
* type="bool",
|
||
* example= "false"
|
||
* )
|
||
* ),
|
||
* ),
|
||
* ),
|
||
* @OA\Response(
|
||
* response=200,
|
||
* description="OK",
|
||
* @OA\JsonContent(
|
||
* ref="#/components/schemas/ApiResponse",
|
||
* example = {
|
||
* "status" : 200,
|
||
* "response" : "Médicament / Appareillage enregistré",
|
||
* "error":null
|
||
* }
|
||
* )
|
||
* )
|
||
* )
|
||
*/
|
||
public function storeDrugsAndDevices(Request $request)
|
||
{
|
||
$this->validate($request, [
|
||
'network_id' => 'required|integer|exists:networks,id',
|
||
'name' => 'required|string',
|
||
'code' => 'required|string',
|
||
'type' => 'required|string|in:COMPRESSED,SYRUP,SOLUTION,SUPPOSITORY,DEVICE',
|
||
'on_prescription' => 'required|boolean'
|
||
]);
|
||
|
||
$drug = NhDrugsAndDevice::where('network_id', $request->input('network_id'))
|
||
->where('code', $request->input('code'))->first();
|
||
if (isset($drug)) {
|
||
return $this->errorResponse(trans('errors.drug_device_already_exists'));
|
||
}
|
||
NhDrugsAndDevice::create($request->all());
|
||
|
||
return $this->successResponse(trans('messages.drug_device_saved'));
|
||
}
|
||
|
||
/**
|
||
* @OA\Get(
|
||
* path="/provider-classes",
|
||
* summary="Obtenir toutes les classes de prestataires d'un reseau",
|
||
* tags={"Classes de prestataires"},
|
||
* security={{"api_key":{}}},
|
||
* @OA\Parameter(
|
||
* parameter="network_id",
|
||
* name="network_id",
|
||
* description="ID du reseau",
|
||
* @OA\Schema(
|
||
* type="integer",
|
||
* default = 250
|
||
* ),
|
||
* in="query",
|
||
* required=true
|
||
* ),
|
||
* @OA\Response(
|
||
* response=200,
|
||
* description="OK",
|
||
* @OA\JsonContent(
|
||
* ref="#/components/schemas/ApiResponse",
|
||
* example = {
|
||
* "status" : 200,
|
||
* "response" : {{"id":2,"name":"Pharmacien"}},
|
||
* "error":null
|
||
* }
|
||
* )
|
||
* )
|
||
* )
|
||
*/
|
||
public function getNetworkProviderClasses(Request $request)
|
||
{
|
||
$this->validate($request, [
|
||
'network_id' => 'required|integer|exists:networks,id',
|
||
]);
|
||
|
||
$network_id = $request->input('network_id');
|
||
|
||
$classes = NhProviderClass::whereHas('network_config', function ($query) use ($network_id) {
|
||
return $query->where('network_id', $network_id);
|
||
})->get(['id', 'name']);
|
||
|
||
return $this->successResponse($classes);
|
||
}
|
||
|
||
/**
|
||
* @OA\Get(
|
||
* path="/acts",
|
||
* summary="Obtenir ou rechercher par code tous les actes d'un reseau",
|
||
* tags={"Actes"},
|
||
* security={{"api_key":{}}},
|
||
* @OA\Parameter(
|
||
* parameter="network_id",
|
||
* name="network_id",
|
||
* description="ID du reseau",
|
||
* @OA\Schema(
|
||
* type="integer",
|
||
* default = 250
|
||
* ),
|
||
* in="query",
|
||
* required=true
|
||
* ),
|
||
* @OA\Parameter(
|
||
* parameter="code",
|
||
* name="code",
|
||
* description="Code de l'acte",
|
||
* @OA\Schema(
|
||
* type="string",
|
||
* default = "CODE1"
|
||
* ),
|
||
* in="query",
|
||
* required=false
|
||
* ),
|
||
* @OA\Response(
|
||
* response=200,
|
||
* description="OK",
|
||
* @OA\JsonContent(
|
||
* ref="#/components/schemas/ApiResponse",
|
||
* example = {
|
||
* "status" : 200,
|
||
* "response" : {{"id":2,"code": "CODE2", "name":"Les actes infirmiers"}},
|
||
* "error":null
|
||
* }
|
||
* )
|
||
* )
|
||
* )
|
||
*/
|
||
public function getNetworkActs(Request $request)
|
||
{
|
||
$this->validate($request, [
|
||
'network_id' => 'required|integer|exists:networks,id',
|
||
'code' => 'nullable|string',
|
||
]);
|
||
|
||
$network_id = $request->input('network_id');
|
||
|
||
$query = NhAct::whereHas('network_config', function ($query) use ($network_id) {
|
||
return $query->where('network_id', $network_id);
|
||
});
|
||
|
||
if ($request->has('code')) {
|
||
$code = $request->input('code');
|
||
$query = $query->where('code', 'like', '%' . $code . '%');
|
||
}
|
||
|
||
$classes = $query->get(['id', 'code', 'name']);
|
||
|
||
return $this->successResponse($classes);
|
||
}
|
||
|
||
/**
|
||
* @OA\Post(
|
||
* path="/health-care-sheets/consultation",
|
||
* summary="Consulter ou prescrire une feuille de soins",
|
||
* tags={"Feuilles de soins"},
|
||
* security={{"api_key":{}}},
|
||
* @OA\RequestBody(
|
||
* description="Corps de la requete",
|
||
* required=true,
|
||
* @OA\MediaType(
|
||
* mediaType="application/json",
|
||
* @OA\Schema(
|
||
* schema="consult_health_care_sheet",
|
||
* title = "Consulter ou prescrire une feuille de soins",
|
||
* required={"insured_id", "network_agent_id", "password", "practitioner_lastname", "practitioner_provider_class_id", "care_condition"},
|
||
* @OA\Property(
|
||
* property="insured_id",
|
||
* description = "Numéro immatriculation de l’assuré",
|
||
* type="string",
|
||
* example= "INSUF45548"
|
||
* ),
|
||
* @OA\Property(
|
||
* property="network_agent_id",
|
||
* description = "ID de l'agent qui saisit la feuille de soin dans le reseau",
|
||
* type="integer",
|
||
* example= 4325
|
||
* ),
|
||
* @OA\Property(
|
||
* property="password",
|
||
* description = "Mot de passe de l'agent",
|
||
* type="string",
|
||
* example= "password"
|
||
* ),
|
||
* @OA\Property(
|
||
* property="beneficiary_id",
|
||
* description = "ID du beneficiaire , s'il s'agit d'une feuille de soins pour beneficiaire",
|
||
* type="integer",
|
||
* example= 4
|
||
* ),
|
||
* @OA\Property(
|
||
* property="practitioner_lastname",
|
||
* description = "Nom du pratricien",
|
||
* type="string",
|
||
* example= "Dr DIETCHI"
|
||
* ),
|
||
* @OA\Property(
|
||
* property="practitioner_firstname",
|
||
* description = "Prenom du pratricien",
|
||
* type="string",
|
||
* example= "Djery"
|
||
* ),
|
||
* @OA\Property(
|
||
* property="practitioner_provider_class_id",
|
||
* description = "ID de la classe de prestataire du praticien",
|
||
* type="integer",
|
||
* example= 12
|
||
* ),
|
||
* @OA\Property(
|
||
* property="care_condition",
|
||
* description = "Condition de prise en charge",
|
||
* type="string",
|
||
* enum={"CURRENT_AFFECTION","LONG_TERM_AFFECTION","EXONERATION"},
|
||
* example= "CURRENT_AFFECTION"
|
||
* ),
|
||
* @OA\Property(
|
||
* property="accident_date",
|
||
* description = "Date de l'accident en cas d'accident",
|
||
* type="string",
|
||
* example= "2021-10-01"
|
||
* ),
|
||
* @OA\Property(
|
||
* property="pregnancy_start_at",
|
||
* description = "Date de début de la grossesse (si grossesse)",
|
||
* type="string",
|
||
* example= "2021-01-01"
|
||
* ),
|
||
* @OA\Property(
|
||
* property="pregnancy_end_at",
|
||
* description = "Date de fin de la grossese (si grossesse)",
|
||
* type="string",
|
||
* example= "2021-09-01"
|
||
* ),
|
||
* @OA\Property(property="performances",
|
||
* type="array",
|
||
* description="Listes des prestations",
|
||
* @OA\Items(ref="#/components/schemas/add_performance")
|
||
* ),
|
||
* @OA\Property(property="prescriptions",
|
||
* type="array",
|
||
* description="Listes des prescriptions medicales",
|
||
* @OA\Items(ref="#/components/schemas/add_prescription")
|
||
* ),
|
||
* @OA\Property(property="exams",
|
||
* type="array",
|
||
* description="Listes des examens",
|
||
* @OA\Items(ref="#/components/schemas/add_exam")
|
||
* )
|
||
* ),
|
||
* ),
|
||
* ),
|
||
* @OA\Response(
|
||
* response=200,
|
||
* description="OK",
|
||
* @OA\JsonContent(
|
||
* ref="#/components/schemas/ApiResponse",
|
||
* example = {
|
||
* "status" : 200,
|
||
* "response" : "Médicament / Appareillage enregistré",
|
||
* "error":null
|
||
* }
|
||
* )
|
||
* )
|
||
* )
|
||
*/
|
||
public function storeHealthCareSheetConsultation(Request $request)
|
||
{
|
||
/**
|
||
* @OA\Schema(
|
||
* schema="add_performance",
|
||
* title = "Ajouter une prestation",
|
||
* required={"act_id", "amount"},
|
||
* @OA\Property(property="act_id",
|
||
* type="integer",
|
||
* example = 2,
|
||
* description="ID de l'acte "
|
||
* ),
|
||
* @OA\Property(property="amount",
|
||
* type="number",
|
||
* example=30000,
|
||
* description="Montant de la prestation"
|
||
* ),
|
||
* @OA\Property(property="home_visit_fees",
|
||
* type="number",
|
||
* example=5000,
|
||
* description="Frais de deplacement pour visiste à domicile "
|
||
* )
|
||
* )
|
||
*
|
||
* @OA\Schema(
|
||
* schema="add_prescription",
|
||
* title = "Ajouter une prescription medicale",
|
||
* required={"drug_or_device_id", "dosage", "quantity"},
|
||
* @OA\Property(property="drug_or_device_id",
|
||
* type="integer",
|
||
* example = 2,
|
||
* description="ID du medicament ou appareillage"
|
||
* ),
|
||
* @OA\Property(property="dosage",
|
||
* type="string",
|
||
* example="3 fois / jour pendant 1e semaine",
|
||
* description="Posologie ou frequence de consommation"
|
||
* ),
|
||
* @OA\Property(property="quantity",
|
||
* type="int",
|
||
* example=5,
|
||
* description="Quantité"
|
||
* )
|
||
* )
|
||
*
|
||
* @OA\Schema(
|
||
* schema="add_exam",
|
||
* title = "Ajouter un examen",
|
||
* required={"act_id", "description", "quantity"},
|
||
* @OA\Property(property="act_id",
|
||
* type="integer",
|
||
* example = 2,
|
||
* description="ID de l'acte"
|
||
* ),
|
||
* @OA\Property(property="description",
|
||
* type="string",
|
||
* example="Une descrition de l'examen",
|
||
* description="Description de l'examene"
|
||
* ),
|
||
* @OA\Property(property="quantity",
|
||
* type="int",
|
||
* example=5,
|
||
* description="Quantité"
|
||
* )
|
||
* )
|
||
*/
|
||
$this->validate($request, [
|
||
'insured_id' => 'required|string',
|
||
'network_agent_id' => 'required|integer|exists:networks_agents,id',
|
||
'password' => 'required|string',
|
||
'beneficiary_id' => 'nullable|int|exists:nh_having_rights,id',
|
||
'practitioner_lastname' => 'required|string',
|
||
'practitioner_firstname' => 'nullable|string',
|
||
'practitioner_provider_class_id' => 'required|integer',
|
||
'care_condition' => 'required|in:CURRENT_AFFECTION,LONG_TERM_AFFECTION,EXONERATION',
|
||
'accident_date' => 'nullable|date_format:Y-m-d|before:today',
|
||
'pregnancy_start_at' => 'nullable|date_format:Y-m-d|before:today',
|
||
'pregnancy_end_at' => 'required_with:pregnancy_start_at|date_format:Y-m-d|after:pregnancy_start_at',
|
||
'performances' => 'nullable|array',
|
||
'performances.*.act_id' => 'required|integer|exists:nh_acts,id',
|
||
'performances.*.amount' => 'required|numeric',
|
||
'performances.*.home_visit_fees' => 'nullable|numeric',
|
||
'prescriptions' => 'nullable|array',
|
||
'prescriptions.*.drug_or_device_id' => 'required|integer|exists:nh_drugs_and_devices,id',
|
||
'prescriptions.*.dosage' => 'required|string',
|
||
'prescriptions.*.quantity' => 'required|integer',
|
||
'exams' => 'nullable|array',
|
||
'exams.*.act_id' => 'required|integer|exists:nh_acts,id',
|
||
'exams.*.description' => 'required|string',
|
||
'exams.*.quantity' => 'required|integer',
|
||
]);
|
||
|
||
$insurance = NhInsurance::where('insured_id', $request->input('insured_id'))->where('state', InsuranceState::PAID)->first();
|
||
if (!isset($insurance)) {
|
||
return $this->errorResponse(trans('errors.not_insured'));
|
||
}
|
||
|
||
$agent = AgentPlus::where('network_agent_id', $request->input('network_agent_id'))->first();
|
||
if (!checkPassword($request->input('password'), $agent->encrypted_password, $agent->salt))
|
||
return $this->errorResponse(trans('messages.incorrect_user_password'));
|
||
|
||
if ($request->has('beneficiary_id')) {
|
||
$beneficiary = $insurance->beneficiaries()->where('nh_having_rights.id', $request->input('beneficiary_id'))->first();
|
||
if (!isset($beneficiary)) {
|
||
return $this->errorResponse(trans('errors.beneficiary_not_found'));
|
||
}
|
||
}
|
||
|
||
$nhConfig = NhNetworksConfig::where('network_id', $insurance->network_id)->first();
|
||
if (!isset($nhConfig)) {
|
||
return $this->errorResponse(trans('errors.nano_health_not_activated'));
|
||
}
|
||
|
||
$insuredPart = 0;
|
||
$insurerPart = 0;
|
||
switch ($request->input('care_condition')) {
|
||
case 'CURRENT_AFFECTION':
|
||
$insurerPart = $nhConfig->current_affection_percentage_insurer / 100;
|
||
$insuredPart = $nhConfig->current_affection_percentage_insured / 100;
|
||
break;
|
||
case 'LONG_TERM_AFFECTION':
|
||
$insurerPart = $nhConfig->long_term_affection_percentage_insurer / 100;
|
||
$insuredPart = $nhConfig->long_term_affection_percentage_insured / 100;
|
||
break;
|
||
case 'EXONERATION':
|
||
$insurerPart = $nhConfig->exoneration_percentage_insurer / 100;
|
||
$insuredPart = $nhConfig->exoneration_percentage_insured / 100;
|
||
break;
|
||
}
|
||
|
||
|
||
try {
|
||
DB::beginTransaction();
|
||
|
||
$datetime = $this->getCurrentTimeByCountryCode($insurance->network->country->code_country);
|
||
|
||
$healthCareSheet = NhHealthCareSheet::create(array_merge($request->all(), [
|
||
'health_care_sheet_id' => $this->generateSheetID(),
|
||
'insurance_id' => $insurance->id,
|
||
'patient_lastname' => isset($beneficiary) ? $beneficiary->lastname : $insurance->user->lastname,
|
||
'patient_firstname' => isset($beneficiary) ? $beneficiary->firstname : $insurance->user->firstname,
|
||
'patient_situation' => isset($beneficiary) ? 'HAVING_RIGHT' : 'INSURED',
|
||
'type' => HealthCareSheetType::CONSULTATION,
|
||
'state' => InsuranceSubscriptionState::UNDER_VALIDATION
|
||
]));
|
||
|
||
foreach ($request->input('performances', []) as $p) {
|
||
$performance = NhPerformance::create([
|
||
'act_id' => $p['act_id'],
|
||
'amount' => $p['amount'],
|
||
'home_visit_fees' => $p['home_visit_fees'] ?? null,
|
||
'moderator_ticket' => $insuredPart * $p['amount'], // to calculate,
|
||
'insurance_amount' => $insurerPart * $p['amount'], // to calculate, montant de l'assurance
|
||
'created_at' => $datetime, 'updated_at' => $datetime,
|
||
]);
|
||
|
||
NhHealthCareSheetsPerformance::create([
|
||
'sheet_id' => $healthCareSheet->id,
|
||
'performance_id' => $performance->id,
|
||
'created_at' => $datetime, 'updated_at' => $datetime,
|
||
]);
|
||
}
|
||
|
||
foreach ($request->input('prescriptions', []) as $p) {
|
||
$prescription = NhMedicalPrescription::create(array_merge($p, [
|
||
'created_at' => $datetime, 'updated_at' => $datetime,
|
||
]));
|
||
|
||
NhHealthCareSheetsPrescription::create([
|
||
'sheet_id' => $healthCareSheet->id,
|
||
'prescription_id' => $prescription->id,
|
||
'created_at' => $datetime, 'updated_at' => $datetime,
|
||
]);
|
||
}
|
||
|
||
foreach ($request->input('exams', []) as $e) {
|
||
$exam = NhExam::create([
|
||
'act_id' => $e['act_id'],
|
||
'description' => $e['description'],
|
||
'quantity' => $e['quantity'] ?? null,
|
||
'created_at' => $datetime, 'updated_at' => $datetime,
|
||
]);
|
||
|
||
NhHealthCareSheetsExam::create([
|
||
'sheet_id' => $healthCareSheet->id,
|
||
'exam_id' => $exam->id,
|
||
'created_at' => $datetime, 'updated_at' => $datetime,
|
||
]);
|
||
}
|
||
|
||
NhHealthCareSheetsHistory::create([
|
||
'action' => 'ADD',
|
||
'health_care_sheet_id' => $healthCareSheet->health_care_sheet_id,
|
||
'state' => $healthCareSheet->state,
|
||
'created_at' => $datetime, 'updated_at' => $datetime,
|
||
]);
|
||
|
||
DB::commit();
|
||
return $this->successResponse(trans('messages.consultation_or_prescription_carried_out'));
|
||
} catch (Throwable $e) {
|
||
Log::error($e->getMessage() . '\n' . $e->getTraceAsString());
|
||
DB::rollBack();
|
||
return $this->errorResponse(trans('errors.unexpected_error'), 500);
|
||
}
|
||
}
|
||
|
||
public function generateSheetID(): string
|
||
{
|
||
do {
|
||
$code = generateTransactionCode();
|
||
$codeCorrect = NhHealthCareSheet::where('health_care_sheet_id', $code)->count() < 0;
|
||
} while ($codeCorrect);
|
||
return $code;
|
||
}
|
||
}
|