nanosanteservice/app/Http/Controllers/HealthCareSheetController.php

1747 lines
79 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers;
use App\Events\InsuredConsultation;
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\NhInfosHealthCareSheets;
use App\Models\NhInsurance;
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\Event;
use Illuminate\Support\Facades\Log;
use stdClass;
use Throwable;
class HealthCareSheetController extends Controller
{
/**
* @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();
foreach ($drugs as $drug) {
$drug->type = trans('states.' . $drug->type);
}
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" : {"network_id":250,"code":"ABD","name":"Nivaquine","type":"COMPRESSED","on_prescription":false,"updated_at":"2021-11-29T11:32:31.000000Z","created_at":"2021-11-29T11:32:31.000000Z","id":4},
* "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'));
}
$drug = NhDrugsAndDevice::create($request->all());
return $this->successResponse($drug);
}
/**
* @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/performances-amount",
* summary="Calculer le montant des prestations lors d'une consulation",
* tags={"Feuilles de soins"},
* security={{"api_key":{}}},
* @OA\RequestBody(
* description="Corps de la requete",
* required=true,
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* @OA\Property(property="network_id",
* type="integer",
* example = 250,
* description="ID du reseau de l'assureur"
* ),
* @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="amount",
* type="integer",
* example = 20000,
* description="Montant de la prestation"
* ),
* ),
* example = {"network_id":250,"care_condition":"CURRENT_AFFECTION","amount":20000 }
* )
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {"status":200,"response":{"moderator_ticket":"4\u202f000 FCFA","insurance_amount":"16\u202f000 FCFA"},"error":null},
* )
* )
* )
*/
public function calculateConsultationPerformancesAmount(Request $request)
{
$this->validate($request, [
'network_id' => 'required|integer|exists:networks,id',
'care_condition' => 'required|in:CURRENT_AFFECTION,LONG_TERM_AFFECTION,EXONERATION',
'amount' => 'required|numeric',
]);
$nhConfig = NhNetworksConfig::where('network_id', $request->input('network_id'))->first();
if (!isset($nhConfig)) {
return $this->errorResponse(trans('errors.nano_health_not_activated'));
}
$currency_code = $this->getNetworkCurrency($request->input('network_id'));
$parts = $this->getConfigInsuranceParts($nhConfig, $request->input('care_condition'));
$result = new stdClass();
$result->moderator_ticket = $this->toMoneyWithCurrencyCode($parts->insured_part * $request->input('amount'), $currency_code);
$result->insurance_amount = $this->toMoneyWithCurrencyCode($parts->insurer_part * $request->input('amount'), $currency_code); //
return $this->successResponse($result);
}
/**
* @OA\Post(
* path="/health-care-sheets/consultation",
* summary="Consulter ou prescritpion 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="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",
* "performances"},
* @OA\Property(
* property="insured_id",
* description = "Numéro immatriculation de lassuré",
* 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" : "Consultation ou prescription effectuée",
* "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' => 'nullable|date_format:Y-m-d|after:pregnancy_start_at',
'performances' => 'required|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'));
$beneficiary_id = $request->input('beneficiary_id');
if (!empty($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();
if (!isset($nhConfig)) {
return $this->errorResponse(trans('errors.nano_health_not_activated'));
}
$parts = $this->getConfigInsuranceParts($nhConfig, $request->input('care_condition'));
try {
DB::beginTransaction();
$datetime = $this->getCurrentTimeByCountryCode($insurance->network->country->code_country);
$accident_date = $request->input('accident_date');
$pregnancy_start_at = $request->input('pregnancy_start_at');
$pregnancy_end_at = $request->input('pregnancy_end_at');
$healthCareSheet = NhHealthCareSheet::create([
'health_care_sheet_id' => $this->generateSheetID(),
'beneficiary_id' => $request->input('beneficiary_id'),
'network_agent_id' => $request->input('network_agent_id'),
'care_condition' => $request->input('care_condition'),
'practitioner_lastname' => $request->input('practitioner_lastname'),
'practitioner_firstname' => $request->input('practitioner_firstname'),
'practitioner_provider_class_id' => $request->input('practitioner_provider_class_id'),
'insurance_id' => $insurance->id,
'patient_lastname' => $request->input('patient_lastname'),
'patient_firstname' => $request->input('patient_firstname'),
'patient_situation' => isset($beneficiary) ? 'HAVING_RIGHT' : 'INSURED',
'type' => HealthCareSheetType::CONSULTATION,
'state' => InsuranceSubscriptionState::UNDER_VALIDATION,
'accident_date' => (!empty($accident_date)) ? $accident_date : null,
'pregnancy_start_at' => (!empty($pregnancy_start_at)) ? $pregnancy_start_at : null,
'pregnancy_end_at' => (!empty($pregnancy_end_at)) ? $pregnancy_end_at : null,
]);
foreach ($request->input('performances', []) as $p) {
$fees = !empty($p['home_visit_fees']) ? $p['home_visit_fees'] : 0;
$performance = NhPerformance::create([
'act_id' => $p['act_id'],
'amount' => $p['amount'],
'home_visit_fees' => $fees != 0 ? $fees : null,
'moderator_ticket' => $parts->insured_part * ($p['amount'] + $fees), // to calculate,
'insurance_amount' => $parts->insurer_part * ($p['amount'] + $fees), // 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,
]);
$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,
'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')));
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);
}
}
/**
* @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|integer|exists:nh_health_care_sheets,id',
'network_agent_id' => 'required|integer|exists:networks_agents,id',
'password' => 'required|string',
'practitioner_lastname' => 'required|string',
'practitioner_firstname' => 'nullable|string',
'practitioner_provider_class_id' => 'required|integer',
'prescriptions' => 'nullable|array',
'prescriptions.*.id' => 'required|integer|exists:nh_medical_prescriptions,id',
'prescriptions.*.unit_price' => 'required|numeric',
'exams' => 'nullable|array',
'exams.*.id' => 'required|integer|exists:nh_exams,id',
'exams.*.unit_price' => 'required|numeric',
]);
$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'));
$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, $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($sheet->insurance->network->country->code_country);
$healthCareSheet = $sheet->replicate();
$healthCareSheet->health_care_sheet_id = $this->generateSheetID();
$healthCareSheet->network_agent_id = $request->input('network_agent_id');
$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();
$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;
}
$itemIndex = array_search($i->id, $prescriptionsIds);
if ($i->billed) {
return $this->errorResponse(__('errors.prescription_already_invoiced', ['id' => $itemIndex + 1]));
}
$item->unit_price = $prescriptions[$itemIndex]['unit_price'];
}
if ($relation == 'exams') {
if (!in_array($i->id, $examsIds)) {
continue;
}
$itemIndex = array_search($i->id, $examsIds);
if ($i->billed) {
return $this->errorResponse(__('errors.exam_already_invoiced', ['id' => $itemIndex + 1]));
}
$item->unit_price = $exams[$itemIndex]['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->billed = true;
$item->push();
$i->billed = true;
$i->save();
if ($relation == 'prescriptions') {
NhHealthCareSheetsPrescription::create([
'sheet_id' => $healthCareSheet->id,
'prescription_id' => $item->id,
'created_at' => $datetime, 'updated_at' => $datetime,
]);
}
if ($relation == 'exams') {
NhHealthCareSheetsExam::create([
'sheet_id' => $healthCareSheet->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',
'health_care_sheet_id' => $healthCareSheet->health_care_sheet_id,
'state' => $healthCareSheet->state,
'created_at' => $datetime, 'updated_at' => $datetime,
]);
$healthCareSheet->user = $insurance->user;
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.execution_carried_out')));
DB::commit();
return $this->successResponse(trans('messages.execution_carried_out'));
} catch (Throwable $e) {
Log::error($e->getMessage() . '\n' . $e->getTraceAsString());
DB::rollBack();
return $this->errorResponse(trans('errors.unexpected_error'), 500);
}
}
/**
* @OA\Get(
* path="/health-care-sheets",
* summary="Obtenir les feuilles de soins d'un utilisateur",
* tags={"Feuilles de soins"},
* security={{"api_key":{}}},
* @OA\Parameter(
* parameter="user_id",
* name="user_id",
* description="ID de l'utilisateur",
* @OA\Schema(
* type="integer",
* default = 349
* ),
* in="query",
* required=false
* ),
* @OA\Parameter(
* parameter="beneficiary_id",
* name="beneficiary_id",
* description="ID du beneficiaire",
* @OA\Schema(
* type="integer",
* default = 3
* ),
* in="query",
* required=false
* ),
* @OA\Parameter(
* parameter="network_agent_id",
* name="network_agent_id",
* description="ID de l'agent dans le reseau",
* @OA\Schema(
* type="integer",
* default = 43510
* ),
* in="query",
* required=false
* ),
* @OA\Parameter(
* parameter="type",
* name="type",
* description="Type des feuilles de soins",
* @OA\Schema(
* type="string",
* enum = {"CONSULTATION","EXECUTION"},
* default = "CONSULTATION"
* ),
* in="query",
* required=false
* ),
* @OA\Parameter(
* parameter="state",
* name="state",
* description="Status des feuilles de soins",
* @OA\Schema(
* type="string",
* enum = {"UNTREATED","TREATED","ACCEPTED","TO_BILL"},
* default = "UNTREATED"
* ),
* in="query",
* required=false
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {
* "status" : 200,
* "response" : {{"insured_id":"GJKS8ZGBEJTL","network_id":250,"user_id":349,"id":8,"health_care_sheet_id":"XLLLCY75OU8H","insurance_id":4,"network_agent_id":43510,"patient_lastname":"Dietchi",
* "patient_firstname":"Djery","patient_situation":"AYANT DROIT","practitioner_lastname":"Dr Luc","practitioner_firstname":"Boris","practitioner_provider_class_id":"1","care_condition":"AFFECTION COURANTE",
* "accident_date":null,"pregnancy_start_at":null,"pregnancy_end_at":null,"state":"EN COURS DE VALIDATION","created_at":"2021-11-25T04:39:06.000000Z","updated_at":"2021-11-25T04:39:06.000000Z","type":"CONSULTATION",
* "practitioner_provider_class":"Chirugien","institution_name":"Agent 2 cnamgs fond 4","institution_code":"aon8K9BZOn","currency_code":"XAF","performances":{{"id":10,"act_id":5,"amount":"5 000 FCFA","moderator_ticket":"1 000 FCFA",
* "insurance_amount":"4 000 FCFA","home_visit_fees":"2 000 FCFA","created_at":"2021-11-25T05:39:06.000000Z","updated_at":"2021-11-25T05:39:06.000000Z","act":{"id":5,"code":"CODE2","name":"Les actes infirmiers"}}},"exams":{{"id":2,"act_id":7,"description":"Une description de l'examen","quantity":5,"unit_price":null,"insured_paid_amount":null,"insurer_paid_amount":null,"created_at":"2021-11-25T04:39:06.000000Z",
* "updated_at":"2021-11-25T04:39:06.000000Z","laravel_through_key":8,"act":{"id":7,"code":"CODE4","name":"Les analyses de biologie m\u00e9dicale"}}},"prescriptions":{{"id":4,"drug_or_device_id":1,"dosage":"3 fois\/jour","quantity":5,"unit_price":null,"insured_paid_amount":null,"insurer_paid_amount":null,"created_at":"2021-11-25T05:39:06.000000Z","updated_at":"2021-11-25T05:39:06.000000Z",
* "drug_or_device":{"id":1,"name":"Paracetamol"}}}}},
* "error":null
* }
* )
* )
* )
*/
public function getHealthCareSheets(Request $request)
{
$this->validate($request, [
'user_id' => 'required_without:network_agent_id|integer|exists:users,id',
'beneficiary_id' => 'nullable|integer|exists:nh_having_rights,id',
'network_agent_id' => 'required_without:user_id|integer|exists:networks_agents,id',
'type' => 'nullable|in:CONSULTATION,EXECUTION',
'state' => 'nullable|in:UNTREATED,TREATED,ACCEPTED,TO_BILL'
]);
$type = $request->input('type');
$state = $request->input('state');
$user_id = $request->input('user_id');
$beneficiary_id = $request->input('beneficiary_id');
$network_agent_id = $request->input('network_agent_id');
if (!empty($user_id)) {
$query = NhInfosHealthCareSheets::where('user_id', $user_id);
if (!empty($beneficiary_id)) {
$query = $query->where('beneficiary_id', $beneficiary_id);
} else {
$query = $query->whereNull('beneficiary_id');
}
if (!empty($network_agent_id)) {
$query = $query->where('network_agent_id', $network_agent_id);
}
} else {
$query = NhInfosHealthCareSheets::where('network_agent_id', $network_agent_id);
}
$query = $query->with(['performances.act:id,code,name', 'exams.act:id,code,name', 'prescriptions.drug_or_device:id,name']);
if (!empty($state) && $state == 'TO_BILL') {
// Liste des feuilles de soins a afficher pour l'execution
$query = NhInfosHealthCareSheets::with(['performances.act:id,code,name', 'exams' => function ($q) {
return $q->with(['act:id,code,name'])->where('billed', 0);
}, 'prescriptions' => function ($q) {
return $q->with(['drug_or_device:id,name'])->where('billed', 0);
}])->where('state', InsuranceSubscriptionState::ACCEPTED)
->where('user_id', $request->input('user_id'));
if (!empty($beneficiary_id)) {
$query = $query->where('beneficiary_id', $beneficiary_id);
} else {
$query = $query->whereNull('beneficiary_id');
}
}
if (!empty($type)) {
$query = $query->where('type', $type);
}
if (!empty($state)) {
switch ($state) {
case 'UNTREATED' :
$query = $query->where('state', InsuranceSubscriptionState::UNDER_VALIDATION);
break;
case 'TREATED' :
$query = $query->where('state', '!=', InsuranceSubscriptionState::UNDER_VALIDATION);
break;
case 'ACCEPTED' :
$query = $query->where('state', InsuranceSubscriptionState::ACCEPTED);
break;
}
}
$sheets = $query->orderBy('created_at', 'DESC')->get();
if (!empty($state) && $state == 'TO_BILL') {
// Liste des feuilles de soins a afficher pour l'execution ,
// Retirer les feuilles de soins qui n'ont ni exams ou prescriptions non soldes
$notEmptySheets = [];
foreach ($sheets as $s) {
if (sizeof($s->exams) == 0 && sizeof($s->prescriptions) == 0) {
continue;
}
$notEmptySheets[] = $s;
}
$sheets = $notEmptySheets;
}
foreach ($sheets as $sheet) {
$this->formalizeHealthCareSheet($sheet);
}
return $this->successResponse($sheets);
}
/**
* @OA\Get(
* path="/health-care-sheets/{id}",
* summary="Obtenir une feuilles de soins par son id",
* tags={"Feuilles de soins"},
* security={{"api_key":{}}},
* @OA\Parameter(
* parameter="id",
* name="id",
* description="ID de la feuille de soins",
* @OA\Schema(
* type="integer",
* default = 349
* ),
* in="path",
* required=true
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {
* "status" : 200,
* "response" : {"insured_id":"GJKS8ZGBEJTL","network_id":250,"user_id":349,"id":8,"health_care_sheet_id":"XLLLCY75OU8H","insurance_id":4,"network_agent_id":43510,"patient_lastname":"Dietchi",
* "patient_firstname":"Djery","patient_situation":"AYANT DROIT","practitioner_lastname":"Dr Luc","practitioner_firstname":"Boris","practitioner_provider_class_id":"1","care_condition":"AFFECTION COURANTE",
* "accident_date":null,"pregnancy_start_at":null,"pregnancy_end_at":null,"state":"EN COURS DE VALIDATION","created_at":"2021-11-25T04:39:06.000000Z","updated_at":"2021-11-25T04:39:06.000000Z","type":"CONSULTATION",
* "practitioner_provider_class":"Chirugien","institution_name":"Agent 2 cnamgs fond 4","institution_code":"aon8K9BZOn","currency_code":"XAF","performances":{{"id":10,"act_id":5,"amount":"5 000 FCFA","moderator_ticket":"1 000 FCFA",
* "insurance_amount":"4 000 FCFA","home_visit_fees":"2 000 FCFA","created_at":"2021-11-25T05:39:06.000000Z","updated_at":"2021-11-25T05:39:06.000000Z","act":{"id":5,"code":"CODE2","name":"Les actes infirmiers"}}},"exams":{{"id":2,"act_id":7,"description":"Une description de l'examen","quantity":5,"unit_price":null,"insured_paid_amount":null,"insurer_paid_amount":null,"created_at":"2021-11-25T04:39:06.000000Z",
* "updated_at":"2021-11-25T04:39:06.000000Z","laravel_through_key":8,"act":{"id":7,"code":"CODE4","name":"Les analyses de biologie m\u00e9dicale"}}},"prescriptions":{{"id":4,"drug_or_device_id":1,"dosage":"3 fois\/jour","quantity":5,"unit_price":null,"insured_paid_amount":null,"insurer_paid_amount":null,"created_at":"2021-11-25T05:39:06.000000Z","updated_at":"2021-11-25T05:39:06.000000Z",
* "drug_or_device":{"id":1,"name":"Paracetamol"}}}},
* "error":null
* }
* )
* )
* )
*/
public function getOneHealthCareSheets($id)
{
$sheet = NhInfosHealthCareSheets::with(['performances.act:id,code,name', 'exams.act:id,code,name', 'prescriptions.drug_or_device:id,name'])->where('id', $id)->first();
$this->formalizeHealthCareSheet($sheet);
return $this->successResponse($sheet);
}
private function formatExamAndPrescriptionAmounts($e, $sheet): void
{
$e->unit_price_formatted = isset($e->unit_price) ? $this->toMoneyWithCurrencyCode($e->unit_price, $sheet->currency_code) : null;
$e->insured_paid_amount_formatted = isset($e->insured_paid_amount) ? $this->toMoneyWithCurrencyCode($e->insured_paid_amount, $sheet->currency_code) : null;
$e->insurer_paid_amount_formatted = isset($e->insurer_paid_amount) ? $this->toMoneyWithCurrencyCode($e->insurer_paid_amount, $sheet->currency_code) : null;
}
/**
* @OA\Put(
* path="/health-care-sheets",
* summary="Accepter ou Rejeter 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(
* required={"health_care_sheet_id", "user_id", "action"},
* @OA\Property(
* property="health_care_sheet_id",
* description = "ID de la feuille de soins",
* type="integer",
* example= 4
* ),
* @OA\Property(
* property="user_id",
* description = "ID de l'utilisateur",
* type="integer",
* example= 349
* ),
* @OA\Property(
* property="action",
* description = "Action à effectuer",
* enum={"ACCEPT","REJECT","RESUBMIT"},
* example= "ACCEPT"
* ),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {
* "status" : 200,
* "response" : "La feuille de soins a été acceptée",
* "error":null
* }
* )
* )
* )
*/
public function treatHealthCareSheet(Request $request)
{
$this->validate($request, [
'health_care_sheet_id' => 'required|integer|exists:nh_health_care_sheets,id',
'user_id' => 'required|integer|exists:users,id',
'action' => 'required|in:ACCEPT,REJECT,RESUBMIT'
]);
$action = $request->input('action');
$user_id = $request->input('user_id');
$sheet = NhHealthCareSheet::findOrFail($request->input('health_care_sheet_id'));
if ($sheet->insurance->user_id != $user_id) {
return $this->errorResponse(trans('errors.unauthorized'));
}
if ($action != 'RESUBMIT' && $sheet->state != InsuranceSubscriptionState::UNDER_VALIDATION) {
return $this->errorResponse(trans('errors.care_sheet_already_been_processed'));
}
$datetime = $this->getCurrentTimeByCountryCode($sheet->insurance->network->country->code_country);
if ($action == 'ACCEPT') {
$sheet->state = InsuranceSubscriptionState::ACCEPTED;
$sheet->updated_at = $datetime;
$sheet->save();
return $this->successResponse(trans('messages.care_sheet_accepted'));
} else if ($action == 'REJECT') {
$sheet->state = InsuranceSubscriptionState::REJECTED;
$sheet->updated_at = $datetime;
$sheet->save();
return $this->successResponse(trans('messages.care_sheet_rejected'));
} else {
$sheet->state = InsuranceSubscriptionState::UNDER_VALIDATION;
$sheet->updated_at = $sheet->created_at = $datetime;
$sheet->save();
return $this->successResponse(trans('messages.care_sheet_resubmitted'));
}
}
private function getConfigInsuranceParts(NhNetworksConfig $nhConfig, $care_condition): stdClass
{
$insuredPart = 0;
$insurerPart = 0;
switch ($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;
}
$result = new stdClass();
$result->insured_part = $insuredPart;
$result->insurer_part = $insurerPart;
return $result;
}
/**
* @OA\Put(
* path="/health-care-sheets/{id}",
* summary="Modifier 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="update_health_care_sheet",
* title = "Modfiier une feuille de soins",
* required={"insured_id", "network_agent_id", "password", "practitioner_lastname", "practitioner_provider_class_id"},
* @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/update_performance")
* ),
* @OA\Property(property="prescriptions",
* type="array",
* description="Listes des prescriptions medicales",
* @OA\Items(ref="#/components/schemas/update_prescription")
* ),
* @OA\Property(property="exams",
* type="array",
* description="Listes des examens",
* @OA\Items(ref="#/components/schemas/update_exam")
* )
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {
* "status" : 200,
* "response" : "Consultation ou prescription mis à jour",
* "error":null
* }
* )
* )
* )
*/
public function updateHealthCareSheet(Request $request, $id)
{
/**
* @OA\Schema(
* schema="update_performance",
* title = "Modifier une prestation",
* @OA\Property(property="id",
* type="integer",
* example = 1,
* description="ID de la prestation"
* ),
* @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\Property(property="to_delete",
* type="boolean",
* example=true,
* description="A supprimer"
* )
* )
*
* @OA\Schema(
* schema="update_prescription",
* title = "Modifier une prescription medicale",
* @OA\Property(property="id",
* type="integer",
* example = 1,
* description="ID de la prescription medicale"
* ),
* @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\Property(property="unit_price",
* type="number",
* example=3000,
* description="Prix unitaire"
* ),
* @OA\Property(property="to_delete",
* type="boolean",
* example=true,
* description="A supprimer"
* )
* )
*
* @OA\Schema(
* schema="update_exam",
* title = "Modifier un examen",
* @OA\Property(property="id",
* type="integer",
* example = 1,
* description="ID de l'examen"
* ),
* @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é"
* ),
* @OA\Property(property="unit_price",
* type="number",
* example=5000,
* description="Prix unitaire"
* ),
* @OA\Property(property="to_delete",
* type="boolean",
* example=true,
* description="A supprimer"
* )
* )
*/
$this->validate($request, [
'network_agent_id' => 'required|integer|exists:networks_agents,id',
'password' => 'required|string',
'beneficiary_id' => 'nullable|int|exists:nh_having_rights,id',
'practitioner_lastname' => 'nullable|string',
'practitioner_firstname' => 'nullable|string',
'practitioner_provider_class_id' => 'nullable|integer',
'care_condition' => 'nullable|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' => 'nullable|date_format:Y-m-d|after:pregnancy_start_at',
'performances' => 'nullable|array',
'performances.*.id' => 'nullable|integer|exists:nh_performances,id',
'performances.*.act_id' => 'required_with:performances.*.id|integer|exists:nh_acts,id',
'performances.*.amount' => 'required_with:performances.*.id|numeric',
'performances.*.home_visit_fees' => 'nullable|numeric',
'performances.*.to_delete' => 'nullable|boolean',
'prescriptions' => 'nullable|array',
'prescriptions.*.id' => 'nullable|integer|exists:nh_medical_prescriptions,id',
'prescriptions.*.drug_or_device_id' => 'required_with:prescriptions.*.id|integer|exists:nh_drugs_and_devices,id',
'prescriptions.*.dosage' => 'required_with:prescriptions.*.id|string',
'prescriptions.*.quantity' => 'required_with:prescriptions.*.id|integer',
'prescriptions.*.unit_price' => 'nullable|numeric',
'prescriptions.*.to_delete' => 'nullable|boolean',
'exams' => 'nullable|array',
'exams.*.id' => 'nullable|integer|exists:nh_exams,id',
'exams.*.act_id' => 'required_with:exams.*.id|integer|exists:nh_acts,id',
'exams.*.description' => 'required_with:exams.*.id|string',
'exams.*.quantity' => 'required_with:exams.*.id|integer',
'exams.*.unit_price' => 'nullable|numeric',
'exams.*.to_delete' => 'nullable|boolean',
]);
$sheet = NhHealthCareSheet::where('id', $id)->where('state', InsuranceSubscriptionState::UNDER_VALIDATION)->first();
if (!isset($sheet)) {
return $this->errorResponse(__('errors.sheet_cannot_be_modified'));
}
if ($sheet->network_agent_id != $request->input('network_agent_id')) {
return $this->errorResponse(__('errors.unauthorized_to_update_sheet'), 403);
}
$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 (!empty($beneficiary_id)) {
$beneficiary = $sheet->insurance->beneficiaries()->where('nh_having_rights.id', $beneficiary_id)->first();
if (!isset($beneficiary)) {
return $this->errorResponse(trans('errors.beneficiary_not_found'));
}
$sheet->beneficiary_id = $beneficiary_id;
}
$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', $sheet->care_condition));
$performances = $request->input('performances', []);
$prescriptions = $request->input('prescriptions', []);
$exams = $request->input('exams', []);
$performancesIds = array_map(function ($r) {
return $r['id'] ?? null;
}, $performances);
$prescriptionsIds = array_map(function ($r) {
return $r['id'] ?? null;
}, $prescriptions);
$examsIds = array_map(function ($r) {
return $r['id'] ?? null;
}, $exams);
try {
DB::beginTransaction();
$datetime = $this->getCurrentTimeByCountryCode($sheet->insurance->network->country->code_country);
$sheet->updated_at = $datetime;
$sheet->practitioner_lastname = $request->input('practitioner_lastname', $sheet->practitioner_lastname);
$sheet->practitioner_firstname = $request->input('practitioner_firstname', $sheet->practitioner_firstname);
$sheet->practitioner_provider_class_id = $request->input('practitioner_provider_class_id', $sheet->practitioner_provider_class_id);
if ($sheet->type == HealthCareSheetType::CONSULTATION) {
$accident_date = $request->input('accident_date');
$pregnancy_start_at = $request->input('pregnancy_start_at');
$pregnancy_end_at = $request->input('pregnancy_end_at');
$sheet->care_condition = $request->input('care_condition', $sheet->care_condition);
$sheet->accident_date = !empty($accident_date) ? $accident_date : null;
$sheet->pregnancy_start_at = !empty($pregnancy_start_at) ? $pregnancy_start_at : null;
$sheet->pregnancy_end_at = !empty($pregnancy_end_at) ? $pregnancy_end_at : null;
if (isset($beneficiary)) {
$sheet->patient_lastname = $beneficiary->lastname;
$sheet->patient_firstname = $beneficiary->firstname;
$sheet->patient_situation = 'HAVING_RIGHT';
}
foreach ($request->input('performances', []) as $p) {
if (!empty($p['to_delete'])) {
NhPerformance::find($p['id'])->delete();
NhHealthCareSheetsPerformance::where('sheet_id', $sheet->id)->where('performance_id', $p['id'])->delete();
continue;
}
if (!empty($p['id'])) {
$shPerformance = NhHealthCareSheetsPerformance::where('sheet_id', $sheet->id)->where('performance_id', $p['id'])->first();
if (!isset($shPerformance)) {
return $this->errorResponse(__('errors.performance_not_belong_to_sheet', ['id' => array_search($p['id'], $performancesIds) + 1]));
}
$performance = NhPerformance::findOrFail($p['id']);
} else {
$performance = new NhPerformance();
$performance->created_at = $datetime;
}
$performance->act_id = !empty($p['act_id']) ? $p['act_id'] : $performance->act_id;
$performance->home_visit_fees = !empty($p['home_visit_fees']) ? $p['home_visit_fees'] : $performance->home_visit_fees;
$fees = !empty($performance->home_visit_fees) ? $performance->home_visit_fees : 0;
if (!empty($p['amount'])) {
$performance->amount = $p['amount'];
$performance->moderator_ticket = $parts->insured_part * ($p['amount'] + $fees); // to calculate,
$performance->insurance_amount = $parts->insurer_part * ($p['amount'] + $fees); // to calculate, montant de l'assurance
}
$performance->updated_at = $datetime;
$performance->save();
if (empty($p['id'])) {
NhHealthCareSheetsPerformance::create([
'sheet_id' => $sheet->id,
'performance_id' => $performance->id,
'created_at' => $datetime, 'updated_at' => $datetime,
]);
}
}
}
foreach ($request->input('prescriptions', []) as $p) {
if (!empty($p['to_delete'])) {
NhMedicalPrescription::find($p['id'])->delete();
NhHealthCareSheetsPrescription::where('sheet_id', $sheet->id)->where('prescription_id', $p['id'])->delete();
continue;
}
if (!empty($p['id'])) {
$shPrescription = NhHealthCareSheetsPrescription::where('sheet_id', $sheet->id)->where('prescription_id', $p['id'])->first();
if (!isset($shPrescription)) {
return $this->errorResponse(__('errors.prescription_not_belong_to_sheet', ['id' => array_search($p['id'], $prescriptionsIds) + 1]));
}
$prescription = NhMedicalPrescription::findOrFail($p['id']);
} else {
$prescription = new NhMedicalPrescription();
$prescription->created_at = $datetime;
}
if ($sheet->type == HealthCareSheetType::CONSULTATION) {
$prescription->drug_or_device_id = !empty($p['drug_or_device_id']) ? $p['drug_or_device_id'] : $prescription->drug_or_device_id;
$prescription->dosage = !empty($p['dosage']) ? $p['dosage'] : $prescription->dosage;
$prescription->quantity = !empty($p['quantity']) ? $p['quantity'] : $prescription->quantity;
} else {
if (!empty($p['unit_price'])) {
$prescription->unit_price = $p['unit_price'];
$prescription->insured_paid_amount = $parts->insured_part * $prescription->unit_price * ($prescription->quantity ?? 1);
$prescription->insurer_paid_amount = $parts->insurer_part * $prescription->unit_price * ($prescription->quantity ?? 1);
}
}
$prescription->updated_at = $datetime;
$prescription->save();
if (empty($p['id'])) {
NhHealthCareSheetsPrescription::create([
'sheet_id' => $sheet->id,
'prescription_id' => $prescription->id,
'created_at' => $datetime, 'updated_at' => $datetime,
]);
}
}
foreach ($request->input('exams', []) as $p) {
if (!empty($p['to_delete'])) {
NhExam::find($p['id'])->delete();
NhHealthCareSheetsExam::where('sheet_id', $sheet->id)->where('exam_id', $p['id'])->delete();
continue;
}
if (!empty($p['id'])) {
$shExam = NhHealthCareSheetsExam::where('sheet_id', $sheet->id)->where('exam_id', $p['id'])->first();
if (!isset($shExam)) {
return $this->errorResponse(__('errors.prescription_not_belong_to_sheet', ['id' => array_search($p['id'], $examsIds) + 1]));
}
$exam = NhExam::findOrFail($p['id']);
} else {
$exam = new NhExam();
$exam->created_at = $datetime;
}
if ($sheet->type == HealthCareSheetType::CONSULTATION) {
$exam->act_id = !empty($p['act_id']) ? $p['act_id'] : $exam->act_id;
$exam->description = !empty($p['description']) ? $p['description'] : $exam->description;
$exam->quantity = !empty($p['quantity']) ? $p['quantity'] : $exam->quantity;
} else {
if (!empty($p['unit_price'])) {
$exam->unit_price = $p['unit_price'];
$exam->insured_paid_amount = $parts->insured_part * $exam->unit_price * ($exam->quantity ?? 1);
$exam->insurer_paid_amount = $parts->insurer_part * $exam->unit_price * ($exam->quantity ?? 1);
}
}
$exam->updated_at = $datetime;
$exam->save();
if (empty($p['id'])) {
NhHealthCareSheetsExam::create([
'sheet_id' => $sheet->id,
'exam_id' => $exam->id,
'created_at' => $datetime, 'updated_at' => $datetime,
]);
}
}
$sheet->save();
DB::commit();
return $this->successResponse(trans('messages.consultation_or_prescription_updated'));
} 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;
}
/**
* @param $sheet
* @return void
*/
private function formalizeHealthCareSheet($sheet): void
{
$sheet->state = trans('states.' . $sheet->state);
$sheet->patient_situation = trans('states.' . $sheet->patient_situation);
$sheet->_care_condition = $sheet->care_condition;
$sheet->care_condition = trans('states.' . $sheet->care_condition);
foreach ($sheet->performances as $p) {
$p->amount_formatted = $this->toMoneyWithCurrencyCode($p->amount, $sheet->currency_code);
$p->moderator_ticket_formatted = $this->toMoneyWithCurrencyCode($p->moderator_ticket, $sheet->currency_code);
$p->insurance_amount_formatted = $this->toMoneyWithCurrencyCode($p->insurance_amount, $sheet->currency_code);
$p->home_visit_fees_formatted = isset($p->home_visit_fees) ? $this->toMoneyWithCurrencyCode($p->home_visit_fees, $sheet->currency_code) : null;
}
foreach ($sheet->exams as $e) {
$this->formatExamAndPrescriptionAmounts($e, $sheet);
}
foreach ($sheet->prescriptions as $p) {
$this->formatExamAndPrescriptionAmounts($p, $sheet);
}
}
}