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\NhInfosHealthCareSheets;
use App\Models\NhInsurance;
use App\Models\NhInsurancesSubscription;
use App\Models\NhMedicalPrescription;
use App\Models\NhNetworksConfig;
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)
{
/**
* @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, [
'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',
'password' => '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.*.unit_price' => 'required|numeric',
'exams' => 'nullable|array',
'exams.*.id' => 'required|integer|exists:nh_acts,id',
'exams.*.id' => 'nullable|integer|exists:nh_exams,id',
'exams.*.unit_price' => 'required|numeric',
]);
$sheet = NhHealthCareSheet::where('id', $request->input('health_care_sheet_id'))->where('state', InsuranceState::PAID)->first();
if (!isset($insurance)) {
return $this->errorResponse(trans('errors.not_insured'));
$prescriptions = $request->input('prescriptions', []);
$exams = $request->input('exams', []);
$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();
if (!checkPassword($request->input('password'), $agent->encrypted_password, $agent->salt))
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)) {
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 {
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(), [
'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
]));
$healthCareSheet = $sheet->replicate();
$healthCareSheet->health_care_sheet_id = $this->generateSheetID();
$healthCareSheet->practitioner_lastname = $request->input('practitioner_lastname');
$healthCareSheet->practitioner_firstname = $request->input('practitioner_firstname');
$healthCareSheet->practitioner_provider_class_id = $request->input('practitioner_provider_class_id');
$healthCareSheet->type = HealthCareSheetType::EXECUTION;
$healthCareSheet->state = InsuranceSubscriptionState::UNDER_VALIDATION;
$healthCareSheet->prescription_sheet_id = $sheet->id;
$healthCareSheet->push();
foreach ($request->input('performances', []) as $p) {
$performance = NhPerformance::create([
'act_id' => $p['act_id'],
'amount' => $p['amount'],
'home_visit_fees' => !empty($p['home_visit_fees']) ? $p['home_visit_fees'] : null,
'moderator_ticket' => $parts->insured_part * $p['amount'], // to calculate,
'insurance_amount' => $parts->insurer_part * $p['amount'], // to calculate, montant de l'assurance
'created_at' => $datetime, 'updated_at' => $datetime,
]);
$insurance = $sheet->insurance;
#Clone relations
//reset relations on EXISTING MODEL (this way you can control which ones will be loaded
$sheet->setRelations([]);
//load relations on EXISTING MODEL
$sheet->load('prescriptions', 'exams'); // Cloner uniquement les prescriptions et les examens
//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) {
$prescription = NhMedicalPrescription::create(array_merge($p, [
'created_at' => $datetime, 'updated_at' => $datetime,
]));
if ($relation == 'exams') {
if (!in_array($i->id, $examsIds)) {
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([
'sheet_id' => $healthCareSheet->id,
'prescription_id' => $prescription->id,
'prescription_id' => $item->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,
]);
if ($relation == 'exams') {
NhHealthCareSheetsExam::create([
'sheet_id' => $healthCareSheet->id,
'exam_id' => $exam->id,
'exam_id' => $item->id,
'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([
'action' => 'ADD',
@ -769,13 +899,13 @@ class HealthCareSheetController extends Controller
]);
$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),
'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();
return $this->successResponse(trans('messages.consultation_or_prescription_carried_out'));
return $this->successResponse(trans('messages.execution_carried_out'));
} catch (Throwable $e) {
Log::error($e->getMessage() . '\n' . $e->getTraceAsString());
DB::rollBack();

View File

@ -28,6 +28,7 @@ use Illuminate\Database\Eloquent\Model;
* @property Carbon|null $pregnancy_end_at
* @property string $type
* @property string $state
* @property int $prescription_sheet_id
* @property Carbon $created_at
* @property Carbon $updated_at
*
@ -40,6 +41,7 @@ class NhHealthCareSheet extends Model
protected $casts = [
'insurance_id' => 'int',
'network_agent_id' => 'int',
'prescription_sheet_id' => 'int'
];
protected $dates = [
@ -63,7 +65,8 @@ class NhHealthCareSheet extends Model
'pregnancy_start_at',
'pregnancy_end_at',
'type',
'state'
'state',
'prescription_sheet_id'
];
public function institution()
@ -75,4 +78,22 @@ class NhHealthCareSheet extends Model
{
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 Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;
/**
* Class NhHealthCareSheetsExam
@ -20,7 +21,7 @@ use Illuminate\Database\Eloquent\Model;
*
* @package App\Models
*/
class NhHealthCareSheetsExam extends Model
class NhHealthCareSheetsExam extends Pivot
{
protected $table = 'nh_health_care_sheets_exams';

View File

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

View File

@ -31,9 +31,9 @@ class NhMedicalPrescription extends Model
protected $casts = [
'drug_or_device_id' => 'int',
'quantity' => 'int',
'unit_price' => 'float',
'insured_paid_amount' => 'float',
'insurer_paid_amount' => 'float'
// 'unit_price' => 'float',
// 'insured_paid_amount' => 'float',
// 'insurer_paid_amount' => 'float'
];
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",
"care_sheet_accepted" => "The care sheet has been accepted",
"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",
"care_sheet_accepted" => "La feuille de soins a été accepté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.
",
];