From 4ceddac73819840cd339a95483635d953fc02b20 Mon Sep 17 00:00:00 2001 From: Djery-Tom Date: Thu, 25 Nov 2021 07:59:44 +0100 Subject: [PATCH] Add endpoint to consult health care sheet --- app/HealthCareSheetType.php | 9 + .../Controllers/HealthCareSheetController.php | 331 +++++++++++++++++- app/Models/NhAct.php | 5 + app/Models/NhExam.php | 47 +++ app/Models/NhHealthCareSheet.php | 5 +- app/Models/NhHealthCareSheetsExam.php | 36 ++ app/Models/NhProviderClass.php | 5 + ...021_11_24_095023_create_nh_exams_table.php | 38 ++ ...dd_type_in_nh_health_care_sheets_table.php | 32 ++ ...eate_nh_health_care_sheets_exams_table.php | 34 ++ ...ounts_nullables_for_health_care_sheets.php | 32 ++ ...reate_nh_infos_health_care_sheets_view.php | 42 +++ resources/lang/en/errors.php | 1 + resources/lang/en/messages.php | 1 + resources/lang/en/states.php | 5 +- resources/lang/fr/errors.php | 1 + resources/lang/fr/messages.php | 1 + resources/lang/fr/states.php | 5 +- routes/web.php | 6 +- 19 files changed, 619 insertions(+), 17 deletions(-) create mode 100644 app/HealthCareSheetType.php create mode 100644 app/Models/NhExam.php create mode 100644 app/Models/NhHealthCareSheetsExam.php create mode 100644 database/migrations/2021_11_24_095023_create_nh_exams_table.php create mode 100644 database/migrations/2021_11_24_104024_add_type_in_nh_health_care_sheets_table.php create mode 100644 database/migrations/2021_11_24_111418_create_nh_health_care_sheets_exams_table.php create mode 100644 database/migrations/2021_11_24_120408_make_unit_price_and_insurance_amounts_nullables_for_health_care_sheets.php create mode 100644 database/migrations/2021_11_25_023106_create_nh_infos_health_care_sheets_view.php diff --git a/app/HealthCareSheetType.php b/app/HealthCareSheetType.php new file mode 100644 index 0000000..781fe65 --- /dev/null +++ b/app/HealthCareSheetType.php @@ -0,0 +1,9 @@ +successResponse(trans('messages.drug_device_saved')); } - public function storeHealthCareSheet(Request $request) + /** + * @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', @@ -177,14 +471,17 @@ class HealthCareSheetController extends Controller '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_code' => 'required|string', + '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', - 'prescriptions.*.unit_price' => 'required|numeric' + '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(); @@ -199,7 +496,7 @@ class HealthCareSheetController extends Controller if ($request->has('beneficiary_id')) { $beneficiary = $insurance->beneficiaries()->where('nh_having_rights.id', $request->input('beneficiary_id'))->first(); if (!isset($beneficiary)) { - return $this->errorResponse("Ce béneficiaire n'existe pas"); + return $this->errorResponse(trans('errors.beneficiary_not_found')); } } @@ -237,13 +534,13 @@ class HealthCareSheetController extends Controller '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) { - $act = NhAct::where('code', $p['act_code'])->first(); $performance = NhPerformance::create([ - 'act_id' => $act->id, + 'act_id' => $p['act_id'], 'amount' => $p['amount'], 'home_visit_fees' => $p['home_visit_fees'] ?? null, 'moderator_ticket' => $insuredPart * $p['amount'], // to calculate, @@ -259,10 +556,7 @@ class HealthCareSheetController extends Controller } foreach ($request->input('prescriptions', []) as $p) { - $amount = $p['unit_price'] * $p['quantity']; $prescription = NhMedicalPrescription::create(array_merge($p, [ - 'insured_paid_amount' => $insuredPart * $amount, // to calculate, - 'insurer_paid_amount' => $insurerPart * $amount, // to calculate, montant de l'assurance 'created_at' => $datetime, 'updated_at' => $datetime, ])); @@ -273,6 +567,21 @@ class HealthCareSheetController extends Controller ]); } + 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, @@ -281,7 +590,7 @@ class HealthCareSheetController extends Controller ]); DB::commit(); - return $this->successResponse(trans('messages.successful_transaction')); + return $this->successResponse(trans('messages.consultation_or_prescription_carried_out')); } catch (Throwable $e) { Log::error($e->getMessage() . '\n' . $e->getTraceAsString()); DB::rollBack(); diff --git a/app/Models/NhAct.php b/app/Models/NhAct.php index e235417..35f8868 100644 --- a/app/Models/NhAct.php +++ b/app/Models/NhAct.php @@ -38,4 +38,9 @@ class NhAct extends Model 'billing_type', 'authorization_type' ]; + + public function network_config() + { + return $this->belongsTo(NhNetworksConfig::class, 'nh_network_config_id'); + } } diff --git a/app/Models/NhExam.php b/app/Models/NhExam.php new file mode 100644 index 0000000..f1f15e1 --- /dev/null +++ b/app/Models/NhExam.php @@ -0,0 +1,47 @@ + 'int', + 'quantity' => 'int', + 'unit_price' => 'float', + 'insured_paid_amount' => 'float', + 'insurer_paid_amount' => 'float' + ]; + + protected $fillable = [ + 'act_id', + 'description', + 'quantity', + 'unit_price', + 'insured_paid_amount', + 'insurer_paid_amount' + ]; +} diff --git a/app/Models/NhHealthCareSheet.php b/app/Models/NhHealthCareSheet.php index fd9a3e1..39c6ca0 100644 --- a/app/Models/NhHealthCareSheet.php +++ b/app/Models/NhHealthCareSheet.php @@ -26,7 +26,7 @@ use Illuminate\Database\Eloquent\Model; * @property Carbon|null $accident_date * @property Carbon|null $pregnancy_start_at * @property Carbon|null $pregnancy_end_at - * @property float $amount + * @property string $type * @property string $state * @property Carbon $created_at * @property Carbon $updated_at @@ -40,7 +40,6 @@ class NhHealthCareSheet extends Model protected $casts = [ 'insurance_id' => 'int', 'network_agent_id' => 'int', - 'amount' => 'float' ]; protected $dates = [ @@ -63,7 +62,7 @@ class NhHealthCareSheet extends Model 'accident_date', 'pregnancy_start_at', 'pregnancy_end_at', - 'amount', + 'type', 'state' ]; } diff --git a/app/Models/NhHealthCareSheetsExam.php b/app/Models/NhHealthCareSheetsExam.php new file mode 100644 index 0000000..691be15 --- /dev/null +++ b/app/Models/NhHealthCareSheetsExam.php @@ -0,0 +1,36 @@ + 'int', + 'exam_id' => 'int' + ]; + + protected $fillable = [ + 'sheet_id', + 'exam_id' + ]; +} diff --git a/app/Models/NhProviderClass.php b/app/Models/NhProviderClass.php index db4d53c..0787ac9 100644 --- a/app/Models/NhProviderClass.php +++ b/app/Models/NhProviderClass.php @@ -32,4 +32,9 @@ class NhProviderClass extends Model 'nh_network_config_id', 'name' ]; + + public function network_config() + { + return $this->belongsTo(NhNetworksConfig::class, 'nh_network_config_id'); + } } diff --git a/database/migrations/2021_11_24_095023_create_nh_exams_table.php b/database/migrations/2021_11_24_095023_create_nh_exams_table.php new file mode 100644 index 0000000..c10cb1e --- /dev/null +++ b/database/migrations/2021_11_24_095023_create_nh_exams_table.php @@ -0,0 +1,38 @@ +id(); + $table->integer('act_id')->comment("Classe ou acte de l’examen"); + $table->text('description'); + $table->tinyInteger('quantity'); + $table->decimal('unit_price')->nullable(); + $table->decimal('insured_paid_amount')->nullable()->comment("Part à payer par assuré"); + $table->decimal('insurer_paid_amount')->nullable()->comment("Part à la charge assureur "); + $table->timestamp('created_at')->useCurrent(); + $table->timestamp('updated_at')->useCurrent(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('nh_exams'); + } +} diff --git a/database/migrations/2021_11_24_104024_add_type_in_nh_health_care_sheets_table.php b/database/migrations/2021_11_24_104024_add_type_in_nh_health_care_sheets_table.php new file mode 100644 index 0000000..d1e6631 --- /dev/null +++ b/database/migrations/2021_11_24_104024_add_type_in_nh_health_care_sheets_table.php @@ -0,0 +1,32 @@ +enum('type', ['CONSULTATION', 'PRESCRIPTION'])->default('CONSULTATION')->after('pregnancy_end_at'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('nh_health_care_sheets', function (Blueprint $table) { + $table->dropColumn('type'); + }); + } +} diff --git a/database/migrations/2021_11_24_111418_create_nh_health_care_sheets_exams_table.php b/database/migrations/2021_11_24_111418_create_nh_health_care_sheets_exams_table.php new file mode 100644 index 0000000..61e9633 --- /dev/null +++ b/database/migrations/2021_11_24_111418_create_nh_health_care_sheets_exams_table.php @@ -0,0 +1,34 @@ +id(); + $table->integer('sheet_id'); + $table->integer('exam_id'); + $table->timestamp('created_at')->useCurrent(); + $table->timestamp('updated_at')->useCurrent(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('nh_health_care_sheets_exams'); + } +} diff --git a/database/migrations/2021_11_24_120408_make_unit_price_and_insurance_amounts_nullables_for_health_care_sheets.php b/database/migrations/2021_11_24_120408_make_unit_price_and_insurance_amounts_nullables_for_health_care_sheets.php new file mode 100644 index 0000000..7db83de --- /dev/null +++ b/database/migrations/2021_11_24_120408_make_unit_price_and_insurance_amounts_nullables_for_health_care_sheets.php @@ -0,0 +1,32 @@ +decimal('unit_price')->nullable()->change(); + $table->decimal('insured_paid_amount')->nullable()->change(); + $table->decimal('insurer_paid_amount')->nullable()->change(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/database/migrations/2021_11_25_023106_create_nh_infos_health_care_sheets_view.php b/database/migrations/2021_11_25_023106_create_nh_infos_health_care_sheets_view.php new file mode 100644 index 0000000..16c9d7e --- /dev/null +++ b/database/migrations/2021_11_25_023106_create_nh_infos_health_care_sheets_view.php @@ -0,0 +1,42 @@ + "Your previous application :state . You cannot submit another one at this time", "not_insured" => "You are not insured", 'drug_device_already_exists' => "This drug / device code already exists", + "beneficiary_not_found" => "This beneficiary does not exist" ]; diff --git a/resources/lang/en/messages.php b/resources/lang/en/messages.php index 65448ec..3a30e7c 100755 --- a/resources/lang/en/messages.php +++ b/resources/lang/en/messages.php @@ -91,4 +91,5 @@ Your request to add a beneficiary to your insurance is being validated. - Number of beneficiaries : :number_of_beneficiaries ", 'drug_device_saved' => "Drug / Device registered", + 'consultation_or_prescription_carried_out' => "Consultation or prescription carried out" ]; diff --git a/resources/lang/en/states.php b/resources/lang/en/states.php index e7001e3..3ee09cb 100755 --- a/resources/lang/en/states.php +++ b/resources/lang/en/states.php @@ -19,5 +19,8 @@ return [ "SYRUP" => "Syrup", "SOLUTION" => "Solution", "SUPPOSITORY" => "Suppository", - "DEVICE" => "Device" + "DEVICE" => "Device", + 'CURRENT_AFFECTION' => "CURRENT AFFECTION", + 'LONG_TERM_AFFECTION' => "LONG TERM AFFECTION", + 'EXONERATION' => "EXONERATION" ]; diff --git a/resources/lang/fr/errors.php b/resources/lang/fr/errors.php index 32a0812..8a412d9 100755 --- a/resources/lang/fr/errors.php +++ b/resources/lang/fr/errors.php @@ -33,4 +33,5 @@ return [ "subscription_cannot_be_submitted" => "Votre demande précédente :state. Vous ne pouvez pas en soumettre une autre pour l'instant", "not_insured" => "Vous n'êtes pas assuré", 'drug_device_already_exists' => "Ce code médicament / appareillage existe deja", + "beneficiary_not_found" => "Ce bénéficiaire n'existe pas" ]; diff --git a/resources/lang/fr/messages.php b/resources/lang/fr/messages.php index b6aaa0f..e23e8aa 100755 --- a/resources/lang/fr/messages.php +++ b/resources/lang/fr/messages.php @@ -91,4 +91,5 @@ Votre demande d'ajout d'ayant droit à votre assurance est en cours de validatio - Nombre d'ayants droit : :number_of_beneficiaries ", 'drug_device_saved' => "Médicament / Appareillage enregistré", + 'consultation_or_prescription_carried_out' => "Consultation ou prescription effectuée" ]; diff --git a/resources/lang/fr/states.php b/resources/lang/fr/states.php index 80c4d27..62651d2 100755 --- a/resources/lang/fr/states.php +++ b/resources/lang/fr/states.php @@ -19,5 +19,8 @@ return [ "SYRUP" => "Sirop", "SOLUTION" => "Solution", "SUPPOSITORY" => "Suppositoire", - "DEVICE" => "Appareillage" + "DEVICE" => "Appareillage", + 'CURRENT_AFFECTION' => "AFFECTION COURANTE", + 'LONG_TERM_AFFECTION' => "AFFECTION LONGUE DURÉE", + 'EXONERATION' => "EXONERATION" ]; diff --git a/routes/web.php b/routes/web.php index 25b34a9..f4b6b85 100644 --- a/routes/web.php +++ b/routes/web.php @@ -39,7 +39,11 @@ $router->group(['prefix' => '', 'middleware' => 'auth'], function () use ($route $router->get('drugs-and-devices', 'HealthCareSheetController@getDrugsAndDevices'); $router->post('drugs-and-devices', 'HealthCareSheetController@storeDrugsAndDevices'); - $router->post('health-care-sheets', 'HealthCareSheetController@storeHealthCareSheet'); + $router->get('provider-classes', 'HealthCareSheetController@getNetworkProviderClasses'); + $router->get('acts', 'HealthCareSheetController@getNetworkActs'); + + $router->post('health-care-sheets/consultation', 'HealthCareSheetController@storeHealthCareSheetConsultation'); + $router->post('health-care-sheets/execution', 'HealthCareSheetController@storeHealthCareSheetExecution'); //QRCode for agents $router->get('qrcode/generate/{id_user}', 'QRCodeController@generate');