nanosanteservice/app/Http/Controllers/InvoiceController.php

276 lines
11 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers;
use App\BillingPeriodType;
use App\InsuranceState;
use App\InsuranceSubscriptionState;
use App\Models\AgentPlus;
use App\Models\CountriesCurrency;
use App\Models\NhHealthCareSheet;
use App\Models\NhInfosInsurances;
use App\Models\NhInfosInvoice;
use App\Models\NhInsurance;
use App\Models\NhInvoice;
use App\Models\NhNetworksConfig;
use Barryvdh\DomPDF\Facade as PDF;
use DateTime;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
class InvoiceController extends Controller
{
/**
* @OA\Get(
* path="/generate-invoice",
* summary="Facturer les feuilles de soins",
* tags={"Factures"},
* security={{"api_key":{}}},
* @OA\Parameter(
* parameter="network_agent_id",
* name="network_agent_id",
* description="ID de l'agent dans le reseau",
* @OA\Schema(
* type="integer"
* ),
* in="query",
* required=true
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {
* "status" : 200,
* "response" : "La facture a été générée",
* "error":null
* }
* )
* )
* )
*/
// Generer les factures periodiquement pour chaque agent
public function generateInvoice(Request $request)
{
$this->validate($request, [
'network_agent_id' => 'required|integer|exists:networks_agents,id'
]);
$network_agent_id = $request->input('network_agent_id');
$agent = AgentPlus::where('network_agent_id', $network_agent_id)->first();
$hyper = AgentPlus::where('network_id', $agent->network_id)->where('category', 'hyper')->first();
$config = NhNetworksConfig::where('network_id', $agent->network_id)->first();
if (!isset($config)) {
return $this->errorResponse(__('errors.nano_health_not_activated'));
}
// executer le script chaque Dimanche a minuit
$start_at = new DateTime();
switch ($config->provider_billing_period) {
case BillingPeriodType::WEEKLY:
$start_at->modify('-7 days');
break;
case BillingPeriodType::BIMONTHLY:
$start_at->modify('-14 days');
break;
case BillingPeriodType::MONTHLY:
$start_at->modify('-28 days');
break;
default:
$start_at = new DateTime();
}
$end_at = new DateTime();
$invoice_id = $this->generateInvoiceID($agent->code_membre);
$country = CountriesCurrency::findOrFail($agent->country_id);
$datetime = $this->getCurrentTimeByCountryCode($country->code_country);
$totalInsurerAmount = 0;
$totalInsuredAmount = 0;
$sheets = NhHealthCareSheet::with(['insurance'])->where('network_agent_id', $network_agent_id)->where('state', InsuranceSubscriptionState::ACCEPTED)
->where('created_at', '>=', $start_at)->where('created_at', '<=', $end_at)->orderBy('created_at', 'DESC')->get();
if (sizeof($sheets) == 0) {
return $this->errorResponse(__('errors.no_sheet_available'));
}
foreach ($sheets as $sheet) {
$this->fetchHealthCareSheetAmounts($sheet);
$totalInsuredAmount += $sheet->insured_amount;
$totalInsurerAmount += $sheet->insurer_amount;
$sheet->date = $sheet->created_at->format('d/m/Y');
}
try {
DB::beginTransaction();
$directoryName = '/invoices-docs/';
$filename = $start_at->format('dmY') . '_' . $end_at->format('dmY') . '_' . $agent->code_membre . '_' . time() . '.pdf';
$invoice = NhInvoice::create([
'invoice_id' => $invoice_id,
'network_agent_id' => $agent->network_agent_id,
'amount' => $totalInsuredAmount + $totalInsurerAmount,
'insured_amount' => $totalInsuredAmount,
'insurer_amount' => $totalInsurerAmount,
'period_start_at' => $start_at,
'period_end_at' => $end_at,
'file_url' => config('services.app_url') . $directoryName . $filename,
'created_at' => $datetime,
'updated_at' => $datetime
]);
$invoice->amount = $this->toMoneyWithCurrencyCode($invoice->amount, $country->currency_code);
$invoice->insured_amount = $this->toMoneyWithCurrencyCode($invoice->insured_amount, $country->currency_code);
$invoice->insurer_amount = $this->toMoneyWithCurrencyCode($invoice->insurer_amount, $country->currency_code);
$invoice->home_visit_fees = $this->toMoneyWithCurrencyCode($invoice->home_visit_fees, $country->currency_code);
$ids = array_map(function ($r) {
return $r['id'];
}, $sheets->toArray());
DB::update("UPDATE nh_health_care_sheets SET state = :state_ , invoice_id = :id WHERE id IN (" . implode(',', $ids) . ")",
['id' => $invoice->id, 'state_' => InsuranceSubscriptionState::INVOICE_ISSUED]);
$invoice->sheets = $sheets;
$invoice->agent = $agent;
$invoice->hyper = $hyper;
$invoice->period = $start_at->format('d/m/Y') . ' ' . trans('messages.to') . ' ' . $end_at->format('d/m/Y');
//Check if the directory already exists.
if (!is_dir(public_path($directoryName))) {
//Directory does not exist, so lets create it.
mkdir(public_path($directoryName), 0755);
}
$title = $agent->lastname . ' - ' . trans('messages.invoice') . ' ' . $invoice->invoice_id;
$message = __('messages.generated_invoice_mail', ['agent' => $agent->lastname, 'period' => $invoice->period]);
$file = PDF::loadView('emails.invoice', $invoice->toArray())->setPaper('a4', 'landscape')->setWarnings(false)->save(public_path($directoryName . $filename));
DB::commit();
$recipients = [preg_replace("/\s+/", "", $hyper->email)]; // Supprimer les espaces dans le mail
Mail::mailer('smtp')->raw($message, function ($message) use ($recipients, $title, $file) {
$message->subject($title)
->to($recipients)
->attachData($file->output(), str_replace(' ', '-', $title) . '.pdf');
});
} catch (\Throwable $t) {
DB::rollBack();
Log::error('-------- Mail not sent -----------');
Log::error($t->getMessage() . " :\n" . $t->getTraceAsString());
}
return $this->successResponse(__('messages.invoice_generated'));
}
/**
* @OA\Get(
* path="/invoices",
* summary="Lister les factures",
* tags={"Factures"},
* security={{"api_key":{}}},
* @OA\Parameter(
* parameter="network_id",
* name="network_id",
* description="ID du reseau",
* @OA\Schema(
* type="integer"
* ),
* 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"
* ),
* in="query",
* required=false
* ),
* @OA\Parameter(
* parameter="page",
* name="page",
* description="Page",
* in="query",
* required=false,
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* parameter="perPage",
* name="perPage",
* description="Pas de pagination",
* in="query",
* required=false,
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {
* "status" : 200,
* "response" : {{"id":12,"invoice_id":"25\/01\/2022\/aon8K9BZOn","network_agent_id":43510,"amount":"110\u202f600 FCFA","insured_amount":"104\u202f320 FCFA",
* "insurer_amount":"6\u202f280 FCFA","period_start_at":"2021-12-28T00:00:00.000000Z","period_end_at":"2022-01-25T00:00:00.000000Z","file_url":"http:\/\/localhost:8086\/invoices-docs\/28122021_25012022_aon8K9BZOn.pdf",
* "created_at":"2022-01-25T19:54:44.000000Z","updated_at":"2022-01-25T19:54:44.000000Z","institution_name":"Agent 2 cnamgs fond 4","institution_code":"aon8K9BZOn","network_id":250,"currency_code":"XAF",
* "health_care_sheets":{{"id":72,"invoice_id":12,"health_care_sheet_id":"LG83D7QFGM3X","type":"CONSULTATION","practitioner_lastname":"DIETCHI","practitioner_firstname":"Djery","practitioner_provider_class":"Chirugien",
* "patient_lastname":"Zele","patient_firstname":"Brice","institution_name":"Agent 2 cnamgs fond 4","institution_code":"aon8K9BZOn","amount":"5\u202f000 FCFA","insurerAmount":"1\u202f000 FCFA","insuredAmount":"4\u202f000 FCFA"}}}},
* "error":null
* }
* )
* )
* )
*/
public function getInvoices(Request $request)
{
$this->validate($request, [
'network_id' => 'required_without:network_agent_id|integer|exists:networks,id',
'network_agent_id' => 'required_without:network_id|integer|exists:networks_agents,id'
]);
$network_id = $request->input('network_id');
$network_agent_id = $request->input('network_agent_id');
$query = NhInfosInvoice::with(['health_care_sheets:id,invoice_id,health_care_sheet_id,type,practitioner_lastname,practitioner_firstname,practitioner_provider_class,patient_lastname,patient_firstname,institution_name,institution_code']);
if (!empty($network_id)) {
$query = $query->where('network_id', $network_id);
}
if (!empty($network_agent_id)) {
$query = $query->where('network_agent_id', $network_agent_id);
}
$invoices = $query->orderBy('created_at', 'DESC')->paginate($request->input('perPage', 10));
foreach ($invoices->items() as $i) {
$i->amount = $this->toMoneyWithCurrencyCode($i->amount, $i->currency_code);
$i->insured_amount = $this->toMoneyWithCurrencyCode($i->insured_amount, $i->currency_code);
$i->insurer_amount = $this->toMoneyWithCurrencyCode($i->insurer_amount, $i->currency_code);
foreach ($i->health_care_sheets as $sheet) {
$this->fetchHealthCareSheetAmounts($sheet);
$sheet->amount = $this->toMoneyWithCurrencyCode($sheet->insured_amount + $sheet->insurer_amount, $i->currency_code);
$sheet->insurerAmount = $this->toMoneyWithCurrencyCode($sheet->insurer_amount, $i->currency_code);
$sheet->insuredAmount = $this->toMoneyWithCurrencyCode($sheet->insured_amount, $i->currency_code);
}
}
return $this->successResponse($invoices);
}
}