validate($request, [ 'user_id' => 'required|integer|exists:users,id', 'state' => 'nullable|in:PAID,UNPAID,TO_PAID', 'pagination' => 'nullable|boolean' ]); $user_id = $request->input('user_id'); $user = User::findOrFail($user_id); $currency_code = $user->network->country->currency_code; $pagination = $request->input('pagination'); $state = $request->input('state'); $datetime = $this->getCurrentTimeByCountryCode($user->network->country->code_country); $query = NhInsurancesInvoice::with(['insurance', 'subscription']) ->whereHas('insurance', function ($q) use ($user_id) { return $q->where('user_id', $user_id); }); if (!empty($state)) { if ($state == 'TO_PAID') { $query = $query->where('state', InsuranceInvoiceState::UNPAID) ->where('payment_deadline', '>=', $datetime); } else { $query = $query->where('state', $state); } } if ($pagination) { $invoices = $query->paginate($request->input('perPage', 10)); } else { $invoices = $query->get(); } $array = $pagination ? $invoices->items() : $invoices; foreach ($array as $invoice) { $invoice->state = trans('states.' . $invoice->state); $invoice->reason = trans('states.' . $invoice->reason); $invoice->amount = $this->toMoneyWithCurrencyCode($invoice->amount, $currency_code); } return $this->successResponse($invoices); } /** * @OA\Put( * path="/insurances/invoices/{id}/pay", * summary="Payer la facture de l'assurance", * tags={"Factures de l'assurance"}, * security={{"api_key":{}}}, * @OA\Parameter( * parameter="id", * name="id", * description="ID de la facture", * in="path", * required=true, * @OA\Schema( * type="integer", * default=12 * ) * ), * @OA\RequestBody( * description="Corps de la requete", * required=true, * @OA\MediaType( * mediaType="application/json", * @OA\Schema( * @OA\Property(property="password", * type="string", * example = "addfdf21", * description="Mot de passe de l'utilisateur" * ) * ), * example = {"password":"adbc1215448"} * ) * ), * @OA\Response( * response=200, * description="OK", * @OA\JsonContent( * ref="#/components/schemas/ApiResponse", * example = {"status":200,"response":"Transaction réussie","error":null} * ) * ) * ) * @throws \App\Exceptions\AppException */ public function payInvoice($id, Request $request) { $this->validate($request, [ 'password' => 'required|string', ]); $invoice = NhInsurancesInvoice::findOrFail($id); $datetime = $this->getCurrentTimeByCountryCode($invoice->insurance->network->country->code_country); if ($invoice->state == InsuranceInvoiceState::PAID) { return $this->errorResponse(trans('errors.invoice_already_paid')); } if ($invoice->payment_deadline < $datetime) { return $this->errorResponse(trans('errors.payment_deadline_reached')); } $user = $invoice->insurance->user; $this->userCredentialsVerification($user, $request->input('password')); $currency = $this->getNetworkCurrency($invoice->insurance->network_id); $amountToPaid = $invoice->amount; if ($user->wallet->balance < $amountToPaid) { $amount = $amountToPaid - $user->wallet->balance; return $this->errorResponse(trans('errors.insufficient_balance', ['amount' => $this->toMoneyWithCurrencyCode($amount, $currency)])); } try { DB::beginTransaction(); $hyperviseur = AgentPlus::where('category', 'hyper')->where('network_id', $invoice->insurance->network_id)->firstOrFail(); $walletHyperviseur = Wallet::where('id_networkAgent', $hyperviseur->network_agent_id)->firstOrFail(); $walletHyperviseur->balance_princ += $amountToPaid; $walletHyperviseur->save(); $user->balance_nano_health += $amountToPaid; $user->wallet->balance -= $amountToPaid; $user->wallet->save(); $user->save(); $invoice->update(['state' => InsuranceInvoiceState::PAID, 'updated_at' => $datetime]); $invoice->insurance->paid_deadlines++; if ($invoice->insurance->paid_deadlines == $invoice->insurance->deadlines) { $invoice->insurance->state = InsuranceState::PAID; $isPartialPayment = false; } else { $invoice->insurance->state = InsuranceState::PARTIALLY_PAID; $isPartialPayment = true; } // Si c'est le 1er paiement if ($invoice->insurance->paid_deadlines == 1) { if ($invoice->reason == InsuranceAction::ADDITION_OF_BENEFICIARY) { $invoice->insurance->bonus_amount = $invoice->subscription->bonus_amount; $invoice->insurance->total_bonus_amount += $invoice->subscription->total_bonus_amount; $invoice->insurance->number_of_beneficiaries += $invoice->subscription->number_of_beneficiaries; $invoice->insurance->updated_at = $datetime; $invoice->insurance->save(); foreach ($invoice->subscription->beneficiaries as $b) { NhInsurancesHavingRight::create([ 'insurance_id' => $invoice->insurance->id, 'having_right_id' => $b->id ]); } } if (in_array($invoice->reason, [InsuranceAction::ACTIVATION, InsuranceAction::RENEWAL])) { if (empty($invoice->insurance->monthsGrid->waiting_period_days)) { $start_at = $datetime; } else { $start_at = $this->addDaysToDateTime($datetime, $invoice->insurance->monthsGrid->waiting_period_days)->format('Y-m-d H:i:s'); } $end_at = $this->addMonthsToDateTime($start_at, $invoice->insurance->monthsGrid->number_of_months); $invoice->insurance->start_at = $start_at; $invoice->insurance->end_at = $end_at; } } $invoice->insurance->save(); Event::dispatch(new InsuranceEvent($invoice->insurance, $isPartialPayment ? trans('messages.insurance_partially_paid') : trans('messages.insurance_subscription_paid'), trans('messages.insurance_paid_mail', ['name' => $invoice->insurance->user->lastname, 'insured_id' => $invoice->insurance->insured_id, 'bonus_amount' => $this->toMoneyWithCurrencyCode($invoice->insurance->bonus_amount, $currency), 'total_bonus_amount' => $this->toMoneyWithCurrencyCode($invoice->insurance->total_bonus_amount, $currency), 'number_of_beneficiaries' => $invoice->insurance->number_of_beneficiaries, 'gender' => trans('states.' . $invoice->insurance->user->identification->gender), 'insurance_name' => $invoice->insurance->network->name, 'months' => $invoice->insurance->monthsGrid->number_of_months, 'invoice_id' => $invoice->invoice_id, 'amount' => $this->toMoneyWithCurrencyCode($invoice->amount, $currency), 'paid_deadlines' => $invoice->insurance->paid_deadlines, 'remains_deadlines' => $invoice->insurance->deadlines - $invoice->insurance->paid_deadlines, 'payment_period' => trans('states.' . $invoice->insurance->monthsGrid->payment_period), 'reason' => trans('states.' . $invoice->reason), 'title' => $isPartialPayment ? trans('messages.insurance_partially_paid_title') : trans('messages.insurance_fully_paid_title'), 'deadlines' => $invoice->insurance->deadlines, 'amount_per_split' => $this->toMoneyWithCurrencyCode($invoice->insurance->amount_per_split, $currency), 'amount_last_payment' => $this->toMoneyWithCurrencyCode($invoice->insurance->amount_last_payment, $currency), 'waiting_days' => empty($invoice->insurance->monthsGrid->waiting_period_days) ? trans('messages.none') : trans('messages.n_days', ['n' => $invoice->insurance->monthsGrid->waiting_period_days]), 'start_at' => $invoice->insurance->start_at ]))); DB::commit(); return $this->successResponse(trans('messages.insurance_invoice_paid')); } catch (Throwable $e) { Log::error($e->getMessage() . '\n' . $e->getTraceAsString()); DB::rollBack(); return $this->errorResponse(trans('errors.unexpected_error'), 500); } } public function generateInvoices() { try { DB::beginTransaction(); $this->generateInsurancesInvoices(); DB::commit(); return $this->successResponse("Success"); } catch (\Throwable $t) { DB::rollBack(); Log::error('-------- Insurances Invoices expired insurance-----------'); Log::error($t->getMessage() . " :\n" . $t->getTraceAsString()); return $this->errorResponse("Error"); } } public function reminderInvoices() { try { $this->reminderInsurancesInvoices(); return $this->errorResponse("Success"); } catch (\Throwable $t) { DB::rollBack(); Log::error('-------- Insurances Invoices expired insurance-----------'); Log::error($t->getMessage() . " :\n" . $t->getTraceAsString()); return $this->errorResponse("Error"); } } }