Update endpoint to execute prescription

This commit is contained in:
Djery-Tom 2021-12-14 23:34:03 +01:00
parent dc7ea55260
commit 3c3d4c1d78
8 changed files with 283 additions and 75 deletions

View File

@ -18,7 +18,6 @@ use App\Models\NhHealthCareSheetsPerformance;
use App\Models\NhHealthCareSheetsPrescription; use App\Models\NhHealthCareSheetsPrescription;
use App\Models\NhInfosHealthCareSheets; use App\Models\NhInfosHealthCareSheets;
use App\Models\NhInsurance; use App\Models\NhInsurance;
use App\Models\NhInsurancesSubscription;
use App\Models\NhMedicalPrescription; use App\Models\NhMedicalPrescription;
use App\Models\NhNetworksConfig; use App\Models\NhNetworksConfig;
use App\Models\NhPerformance; use App\Models\NhPerformance;
@ -661,10 +660,106 @@ class HealthCareSheetController extends Controller
} }
} }
/**
* @OA\Post(
* path="/health-care-sheets/execution",
* summary="Execution de la prescription d'un assuré",
* tags={"Feuilles de soins"},
* security={{"api_key":{}}},
* @OA\RequestBody(
* description="Corps de la requete",
* required=true,
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* schema="execution_health_care_sheet",
* title = "Consulter ou prescrire une feuille de soins",
* required={"health_care_sheet_id", "network_agent_id", "password", "practitioner_lastname", "practitioner_provider_class_id",
* "prescriptions" , "exams"},
* @OA\Property(
* property="health_care_sheet_id",
* description = "ID de la feuille de soins",
* type="integer",
* example= 23
* ),
* @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="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="prescriptions",
* type="array",
* description="Listes des prescriptions medicales",
* @OA\Items(ref="#/components/schemas/execution_schema")
* ),
* @OA\Property(property="exams",
* type="array",
* description="Listes des examens",
* @OA\Items(ref="#/components/schemas/execution_schema")
* )
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {
* "status" : 200,
* "response" : "Execution de prescription effectuée",
* "error":null
* }
* )
* )
* )
*/
public function storeHealthCareSheetExecution(Request $request) public function storeHealthCareSheetExecution(Request $request)
{ {
/**
* @OA\Schema(
* schema="execution_schema",
* title = "Faire une execution de prescriton deja existance",
* required={"id", "unit_price"},
* @OA\Property(property="id",
* type="integer",
* example = 2,
* description="ID de l'operation"
* ),
* @OA\Property(property="unit_price",
* type="float",
* example= 5000,
* description="Prix unitaire"
* )
* )
*/
$this->validate($request, [ $this->validate($request, [
'health_care_sheet_id' => 'required|string', 'health_care_sheet_id' => 'required|integer|exists:nh_health_care_sheets,id',
'network_agent_id' => 'required|integer|exists:networks_agents,id', 'network_agent_id' => 'required|integer|exists:networks_agents,id',
'password' => 'required|string', 'password' => 'required|string',
'practitioner_lastname' => 'required|string', 'practitioner_lastname' => 'required|string',
@ -674,92 +769,127 @@ class HealthCareSheetController extends Controller
'prescriptions.*.id' => 'required|integer|exists:nh_drugs_and_devices,id', 'prescriptions.*.id' => 'required|integer|exists:nh_drugs_and_devices,id',
'prescriptions.*.unit_price' => 'required|numeric', 'prescriptions.*.unit_price' => 'required|numeric',
'exams' => 'nullable|array', 'exams' => 'nullable|array',
'exams.*.id' => 'required|integer|exists:nh_acts,id', 'exams.*.id' => 'nullable|integer|exists:nh_exams,id',
'exams.*.unit_price' => 'required|numeric', 'exams.*.unit_price' => 'required|numeric',
]); ]);
$sheet = NhHealthCareSheet::where('id', $request->input('health_care_sheet_id'))->where('state', InsuranceState::PAID)->first(); $prescriptions = $request->input('prescriptions', []);
if (!isset($insurance)) { $exams = $request->input('exams', []);
return $this->errorResponse(trans('errors.not_insured'));
$sheet = NhHealthCareSheet::findOrFail($request->input('health_care_sheet_id'));
if ($sheet->state != InsuranceSubscriptionState::ACCEPTED) {
return $this->errorResponse("Cette feuille de soin n'a pas été accepte");
}
if ($sheet->type != HealthCareSheetType::CONSULTATION) {
return $this->errorResponse("Cette feuille de soin ne provient pas d'une consultation");
} }
$agent = AgentPlus::where('network_agent_id', $request->input('network_agent_id'))->first(); $agent = AgentPlus::where('network_agent_id', $request->input('network_agent_id'))->first();
if (!checkPassword($request->input('password'), $agent->encrypted_password, $agent->salt)) if (!checkPassword($request->input('password'), $agent->encrypted_password, $agent->salt))
return $this->errorResponse(trans('messages.incorrect_user_password')); return $this->errorResponse(trans('messages.incorrect_user_password'));
$beneficiary_id = $request->input('beneficiary_id');
if (isset($beneficiary_id)) {
$beneficiary = $insurance->beneficiaries()->where('nh_having_rights.id', $beneficiary_id)->first();
if (!isset($beneficiary)) {
return $this->errorResponse(trans('errors.beneficiary_not_found'));
}
}
$nhConfig = NhNetworksConfig::where('network_id', $insurance->network_id)->first(); $nhConfig = NhNetworksConfig::where('network_id', $sheet->insurance->network_id)->first();
if (!isset($nhConfig)) { if (!isset($nhConfig)) {
return $this->errorResponse(trans('errors.nano_health_not_activated')); return $this->errorResponse(trans('errors.nano_health_not_activated'));
} }
$parts = $this->getConfigInsuranceParts($nhConfig, $request->input('care_condition')); $parts = $this->getConfigInsuranceParts($nhConfig, $sheet->care_condition);
$prescriptionsIds = array_map(function ($r) {
return $r['id'];
}, $prescriptions);
$examsIds = array_map(function ($r) {
return $r['id'];
}, $exams);
try { try {
DB::beginTransaction(); DB::beginTransaction();
$datetime = $this->getCurrentTimeByCountryCode($insurance->network->country->code_country); $datetime = $this->getCurrentTimeByCountryCode($sheet->insurance->network->country->code_country);
$healthCareSheet = NhHealthCareSheet::create(array_merge($request->all(), [ $healthCareSheet = $sheet->replicate();
'health_care_sheet_id' => $this->generateSheetID(), $healthCareSheet->health_care_sheet_id = $this->generateSheetID();
'insurance_id' => $insurance->id, $healthCareSheet->practitioner_lastname = $request->input('practitioner_lastname');
'patient_lastname' => isset($beneficiary) ? $beneficiary->lastname : $insurance->user->lastname, $healthCareSheet->practitioner_firstname = $request->input('practitioner_firstname');
'patient_firstname' => isset($beneficiary) ? $beneficiary->firstname : $insurance->user->firstname, $healthCareSheet->practitioner_provider_class_id = $request->input('practitioner_provider_class_id');
'patient_situation' => isset($beneficiary) ? 'HAVING_RIGHT' : 'INSURED', $healthCareSheet->type = HealthCareSheetType::EXECUTION;
'type' => HealthCareSheetType::CONSULTATION, $healthCareSheet->state = InsuranceSubscriptionState::UNDER_VALIDATION;
'state' => InsuranceSubscriptionState::UNDER_VALIDATION $healthCareSheet->prescription_sheet_id = $sheet->id;
])); $healthCareSheet->push();
foreach ($request->input('performances', []) as $p) { $insurance = $sheet->insurance;
$performance = NhPerformance::create([
'act_id' => $p['act_id'], #Clone relations
'amount' => $p['amount'], //reset relations on EXISTING MODEL (this way you can control which ones will be loaded
'home_visit_fees' => !empty($p['home_visit_fees']) ? $p['home_visit_fees'] : null, $sheet->setRelations([]);
'moderator_ticket' => $parts->insured_part * $p['amount'], // to calculate, //load relations on EXISTING MODEL
'insurance_amount' => $parts->insurer_part * $p['amount'], // to calculate, montant de l'assurance $sheet->load('prescriptions', 'exams'); // Cloner uniquement les prescriptions et les examens
'created_at' => $datetime, 'updated_at' => $datetime, //re-sync everything
]); // foreach ($sheet->relations as $relationName => $values){
// $healthCareSheet->{$relationName}()->sync($values);
// }
foreach ($sheet->getRelations() as $relation => $items) {
foreach ($items as $i) {
$item = $i->replicate();
if ($relation == 'prescriptions') {
if (!in_array($i->id, $prescriptionsIds)) {
continue;
}
$itemId = $i->id;
$item->unit_price = array_filter($prescriptions, function ($r) use ($itemId) {
return $r['id'] == $itemId;
})[0]['unit_price'];
NhHealthCareSheetsPerformance::create([
'sheet_id' => $healthCareSheet->id,
'performance_id' => $performance->id,
'created_at' => $datetime, 'updated_at' => $datetime,
]);
} }
foreach ($request->input('prescriptions', []) as $p) { if ($relation == 'exams') {
$prescription = NhMedicalPrescription::create(array_merge($p, [ if (!in_array($i->id, $examsIds)) {
'created_at' => $datetime, 'updated_at' => $datetime, continue;
])); }
$itemId = $i->id;
$item->unit_price = array_filter($exams, function ($r) use ($itemId) {
return $r['id'] == $itemId;
})[0]['unit_price'];
}
unset($item->laravel_through_key);
$item->insured_paid_amount = $parts->insured_part * $item->unit_price * ($item->quantity ?? 1);
$item->insurer_paid_amount = $parts->insurer_part * $item->unit_price * ($item->quantity ?? 1);
$item->created_at = $item->updated_at = $datetime;
$item->push();
if ($relation == 'prescriptions') {
NhHealthCareSheetsPrescription::create([ NhHealthCareSheetsPrescription::create([
'sheet_id' => $healthCareSheet->id, 'sheet_id' => $healthCareSheet->id,
'prescription_id' => $prescription->id, 'prescription_id' => $item->id,
'created_at' => $datetime, 'updated_at' => $datetime, 'created_at' => $datetime, 'updated_at' => $datetime,
]); ]);
} }
foreach ($request->input('exams', []) as $e) { if ($relation == 'exams') {
$exam = NhExam::create([
'act_id' => $e['act_id'],
'description' => $e['description'],
'quantity' => $e['quantity'] ?? null,
'created_at' => $datetime, 'updated_at' => $datetime,
]);
NhHealthCareSheetsExam::create([ NhHealthCareSheetsExam::create([
'sheet_id' => $healthCareSheet->id, 'sheet_id' => $healthCareSheet->id,
'exam_id' => $exam->id, 'exam_id' => $item->id,
'created_at' => $datetime, 'updated_at' => $datetime, 'created_at' => $datetime, 'updated_at' => $datetime,
]); ]);
} }
}
}
#Clone pivots
$performances = NhHealthCareSheetsPerformance::where('sheet_id', $sheet->id)->get();
foreach ($performances as $pf) {
$p = $pf->replicate();
$p->sheet_id = $healthCareSheet->id;
$p->push();
}
NhHealthCareSheetsHistory::create([ NhHealthCareSheetsHistory::create([
'action' => 'ADD', 'action' => 'ADD',
@ -769,13 +899,13 @@ class HealthCareSheetController extends Controller
]); ]);
$healthCareSheet->user = $insurance->user; $healthCareSheet->user = $insurance->user;
Event::dispatch(new InsuredConsultation($healthCareSheet, trans('messages.consultation_or_prescription_carried_out'), trans('messages.consultation_or_prescription_carried_out_mail', ['name' => $insurance->user->lastname, 'insured_id' => $insurance->insured_id, Event::dispatch(new InsuredConsultation($healthCareSheet, trans('messages.execution_carried_out'), trans('messages.execution_carried_out_mail', ['name' => $insurance->user->lastname, 'insured_id' => $insurance->insured_id,
'patient_name' => $healthCareSheet->patient_lastname . ' ' . $healthCareSheet->patient_firstname, 'patient_situation' => trans('states.' . $healthCareSheet->patient_situation), 'care_condition' => trans('states.' . $healthCareSheet->care_condition), 'patient_name' => $healthCareSheet->patient_lastname . ' ' . $healthCareSheet->patient_firstname, 'patient_situation' => trans('states.' . $healthCareSheet->patient_situation), 'care_condition' => trans('states.' . $healthCareSheet->care_condition),
'gender' => trans('states.' . $insurance->user->identification->gender), 'insurance_name' => $nhConfig->network->name, 'practitioner_name' => $healthCareSheet->practitioner_lastname . ' ' . $healthCareSheet->practitioner_firstname, 'institution_name' => $healthCareSheet->institution->lastname]), 'gender' => trans('states.' . $insurance->user->identification->gender), 'insurance_name' => $nhConfig->network->name, 'practitioner_name' => $healthCareSheet->practitioner_lastname . ' ' . $healthCareSheet->practitioner_firstname, 'institution_name' => $healthCareSheet->institution->lastname]),
trans('messages.consultation_or_prescription_carried_out_notification'))); trans('messages.execution_carried_out')));
DB::commit(); DB::commit();
return $this->successResponse(trans('messages.consultation_or_prescription_carried_out')); return $this->successResponse(trans('messages.execution_carried_out'));
} catch (Throwable $e) { } catch (Throwable $e) {
Log::error($e->getMessage() . '\n' . $e->getTraceAsString()); Log::error($e->getMessage() . '\n' . $e->getTraceAsString());
DB::rollBack(); DB::rollBack();

View File

@ -28,6 +28,7 @@ use Illuminate\Database\Eloquent\Model;
* @property Carbon|null $pregnancy_end_at * @property Carbon|null $pregnancy_end_at
* @property string $type * @property string $type
* @property string $state * @property string $state
* @property int $prescription_sheet_id
* @property Carbon $created_at * @property Carbon $created_at
* @property Carbon $updated_at * @property Carbon $updated_at
* *
@ -40,6 +41,7 @@ class NhHealthCareSheet extends Model
protected $casts = [ protected $casts = [
'insurance_id' => 'int', 'insurance_id' => 'int',
'network_agent_id' => 'int', 'network_agent_id' => 'int',
'prescription_sheet_id' => 'int'
]; ];
protected $dates = [ protected $dates = [
@ -63,7 +65,8 @@ class NhHealthCareSheet extends Model
'pregnancy_start_at', 'pregnancy_start_at',
'pregnancy_end_at', 'pregnancy_end_at',
'type', 'type',
'state' 'state',
'prescription_sheet_id'
]; ];
public function institution() public function institution()
@ -75,4 +78,22 @@ class NhHealthCareSheet extends Model
{ {
return $this->belongsTo(NhInsurance::class, 'insurance_id'); return $this->belongsTo(NhInsurance::class, 'insurance_id');
} }
public function performances()
{
return $this->hasManyThrough(NhPerformance::class, NhHealthCareSheetsPerformance::class,
'sheet_id', 'id', 'id', 'performance_id');
}
public function exams()
{
return $this->hasManyThrough(NhExam::class, NhHealthCareSheetsExam::class,
'sheet_id', 'id', 'id', 'exam_id');
}
public function prescriptions()
{
return $this->hasManyThrough(NhMedicalPrescription::class, NhHealthCareSheetsPrescription::class,
'sheet_id', 'id', 'id', 'prescription_id');
}
} }

View File

@ -8,6 +8,7 @@ namespace App\Models;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;
/** /**
* Class NhHealthCareSheetsExam * Class NhHealthCareSheetsExam
@ -20,7 +21,7 @@ use Illuminate\Database\Eloquent\Model;
* *
* @package App\Models * @package App\Models
*/ */
class NhHealthCareSheetsExam extends Model class NhHealthCareSheetsExam extends Pivot
{ {
protected $table = 'nh_health_care_sheets_exams'; protected $table = 'nh_health_care_sheets_exams';

View File

@ -8,6 +8,7 @@ namespace App\Models;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;
/** /**
* Class NhHealthCareSheetsPrescription * Class NhHealthCareSheetsPrescription
@ -20,7 +21,7 @@ use Illuminate\Database\Eloquent\Model;
* *
* @package App\Models * @package App\Models
*/ */
class NhHealthCareSheetsPrescription extends Model class NhHealthCareSheetsPrescription extends Pivot
{ {
protected $table = 'nh_health_care_sheets_prescriptions'; protected $table = 'nh_health_care_sheets_prescriptions';

View File

@ -31,9 +31,9 @@ class NhMedicalPrescription extends Model
protected $casts = [ protected $casts = [
'drug_or_device_id' => 'int', 'drug_or_device_id' => 'int',
'quantity' => 'int', 'quantity' => 'int',
'unit_price' => 'float', // 'unit_price' => 'float',
'insured_paid_amount' => 'float', // 'insured_paid_amount' => 'float',
'insurer_paid_amount' => 'float' // 'insurer_paid_amount' => 'float'
]; ];
protected $fillable = [ protected $fillable = [

View File

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class AddPrescriptionSheetIdToNhHealthCareSheetsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('nh_health_care_sheets', function (Blueprint $table) {
$table->integer('prescription_sheet_id')->nullable()->after('state')
->comment("The ID of prescriotion needed while making execution");
DB::statement("ALTER TABLE nh_health_care_sheets MODIFY type
ENUM('CONSULTATION', 'EXECUTION') DEFAULT 'CONSULTATION' NOT NULL;");
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('nh_health_care_sheets', function (Blueprint $table) {
$table->dropColumn('prescription_sheet_id');
});
}
}

View File

@ -111,5 +111,6 @@ A new consultation or prescription has been made with your insurance.
'consultation_or_prescription_carried_out_notification' => "A new consultation or prescription has just been made with your insurance", 'consultation_or_prescription_carried_out_notification' => "A new consultation or prescription has just been made with your insurance",
"care_sheet_accepted" => "The care sheet has been accepted", "care_sheet_accepted" => "The care sheet has been accepted",
"care_sheet_rejected" => "The care sheet has been rejected", "care_sheet_rejected" => "The care sheet has been rejected",
"care_sheet_resubmitted" => "The care sheet has been resubmitted" "care_sheet_resubmitted" => "The care sheet has been resubmitted",
'execution_carried_out' => "Execution of prescription carried out",
]; ];

View File

@ -111,5 +111,22 @@ Une nouvelle consultation ou prescription vient d'etre effectuée sur votre assu
'consultation_or_prescription_carried_out_notification' => "Une nouvelle consultation ou prescription vient d'etre effectuée sur votre assurance", 'consultation_or_prescription_carried_out_notification' => "Une nouvelle consultation ou prescription vient d'etre effectuée sur votre assurance",
"care_sheet_accepted" => "La feuille de soins a été acceptée", "care_sheet_accepted" => "La feuille de soins a été acceptée",
"care_sheet_rejected" => "La feuille de soins a été rejetée", "care_sheet_rejected" => "La feuille de soins a été rejetée",
"care_sheet_resubmitted" => "La feuille de soins a été re-soumise" "care_sheet_resubmitted" => "La feuille de soins a été re-soumise",
'execution_carried_out' => "Execution de prescription effectuée",
'execution_carried_out_mail' => ":gender :name ,
Une nouvelle execution de prescription vient d'etre effectuée sur votre assurance.
Informations de la consultation ou prescription :
- Numéro d'assuré : :insured_id
- Nom de l'assurance : :insurance_name
- Noms du patient : :patient_name
- Situation du patient : :patient_situation
- Nom de l'établissement : :institution_name
- Noms du praticien : :practitioner_name
- Condition de prise en charge : :care_condition
Connectez-vous à l'application pour avoir plus de details et valider cette opération.
",
]; ];