Files
expense/app/Helpers/GlobalHelper.php
T
2024-12-02 01:18:34 +07:00

327 lines
12 KiB
PHP

<?php
namespace App\Helpers;
use Illuminate\Support\Facades\DB;
class GlobalHelper
{
/**
* Get the client's age from Oracle using FN_GET_AGE function.
*
* @param string $birthDate Birth date in 'YYYY-MM-DD' format
* @param string $loanStartdate Birth date in 'YYYY-MM-DD' format
* @return int|null The client's age, or null if no data is found
*/
public static function getClientAge($birthDate, $loanStartdate)
{
try {
$query = "SELECT ADMIN_AJK.FN_GET_AGE(:birthDate, :loanstartdate) AS age FROM dual";
$result = DB::select($query, [
'birthDate' => date('Y-m-d', strtotime($birthDate)),
'loanstartdate' => date('Y-m-d', strtotime($loanStartdate))
]);
if (!empty($result) && isset($result[0]->age)) {
return (int) $result[0]->age;
}
return null;
} catch (\Exception $e) {
report($e);
return null;
}
}
/**
* Get the result of auto underwriting for SPAJK.
*
* @param string $spajk_id SPAJK ID
* @return boolean The result of auto underwriting
*/
public static function GetCriteriaUnderWriting($spajk_id)
{
try {
$query = "SELECT FN_GET_AUTOUW_SPAJK(:spajk_id) AS RESULT FROM DUAL";
$result = DB::select($query, ['spajk_id' => $spajk_id]);
if (!empty($result) && isset($result[0]->result)) {
if($result[0]->result == 'AUTOUW_CRITERIA_OK') {
return TRUE;
}else{
return FALSE;
}
}
return FALSE;
} catch (\Exception $e) {
report($e);
return FALSE;
}
}
/**
* Generate SPAJK number based on partner ID
*
* @param integer $partner_id Partner ID
* @return string|null SPAJK number or null if error occurs
*/
public static function GenerateSPAJKNo($partner_id)
{
try {
$query = "SELECT FN_GEN_SPAJKNO(:partner_id) AS RESULT FROM DUAL";
$result = DB::select($query, ['partner_id' => $partner_id]);
if (!empty($result) && isset($result[0]->result)) {
return $result[0]->result;
}
return null;
} catch (\Exception $e) {
report($e);
return null;
}
}
/**
* Calculate Net Premium of a policy
*
* @param array $params Parameters to calculate the net premium
* - percentage_fee: The percentage of the fee
* - percentage_ppn: The percentage of the ppn
* - percentage_pph: The percentage of the pph
* - gross_premium: The gross premium
* - premi_gross_total: The total gross premium
*
* @return float The calculated net premium
*/
public static function calculateNetPremi($params){
$percentage_fee = isset($params['percentage_fee']) ? $params['percentage_fee'] : 0;
$percentage_ppn = isset($params['percentage_ppn']) ? $params['percentage_ppn'] : 0;
$percentage_pph = isset($params['percentage_pph']) ? $params['percentage_pph'] : 0;
$UP = isset($params['gross_premium']) ? $params['gross_premium'] : 0;
$premi_gross_total = isset($params['premi_gross_total']) ? $params['premi_gross_total'] : 0;
$fee = round($percentage_fee / 100 * $UP,0);
$dpp_include_ppn = 100 / (100 + $percentage_ppn);
$dpp = round($dpp_include_ppn * $fee,0);
$ppn = round($percentage_ppn / 100 * $dpp,0);
$pph = round($percentage_pph / 100 * $dpp,0);
$premi_net_total = $premi_gross_total - $fee + $ppn + $pph;
return $premi_net_total;
}
private static function FaktorPenurunan($B40, $B14, $J5) {
$result = round((1 - pow(1 + $B40, -$B14 + $J5)) / (1 - pow(1 + $B40, -$B14)), 3);
return $result;
}
// Fungsi untuk menghitung Premi Substandard
private static function CalculatePremiSubstandard($EP, $UP, $faktorPenurunan) {
$EP_per_month = round($EP / 12, 2);
$UP_ceiling = ceil($UP);
$premiSubstandard = ($EP_per_month / 1000) * $UP_ceiling * $faktorPenurunan;
return round($premiSubstandard, 2);
}
/**
* Menghitung premi substandard berdasarkan parameter yang diberikan.
*
* @param array $params parameter yang diperlukan
* - extra_premium: nilai extra premi (EP)
* - gross_premium: nilai premi bruto (UP)
* - loan_interest: bunga pinjaman per bulan
* - loan_coverage_month: masa asuransi dalam bulan
*
* @return int
*/
public static function calculateExtraPremi($params){
$EP = isset($params['extra_premium']) ? $params['extra_premium'] : 0; // Nilai Extra Premi (EP)
$UP = isset($params['gross_premium']) ? $params['gross_premium'] : 0;
$loan_interest = isset($params['loan_interest']) ? $params['loan_interest'] : 0;
$masa_asuransi_bulan = isset($params['loan_coverage_month']) ? $params['loan_coverage_month'] : 0;
// Menghitung faktor penurunan
$iloan = round($loan_interest / 12, 8);
$faktor_penurunan = 0;
for ($i = 0; $i < $masa_asuransi_bulan; $i++) {
$faktor_perbulan = self::FaktorPenurunan($iloan, $masa_asuransi_bulan, $i);
$faktor_penurunan = $faktor_penurunan + $faktor_perbulan;
}
$result = self::CalculatePremiSubstandard($EP, $UP,round($faktor_penurunan,2));
return round($result,0);
}
/**
* Calculate the extra mortality based on given parameters.
*
* @param array $params {
* Array containing parameters for calculation.
*
* @type int 'em' The extra mortality percentage (default 0).
* @type int 'gross_premi' The gross premium amount (default 0).
* }
* @return int The calculated extra mortality value.
*/
public static function calculateExtraMortality($params){
$em = isset($params['extra_mortality']) ? $params['extra_mortality'] : 0;
$gross_premi = isset($params['gross_premi']) ? $params['gross_premi'] : 0;
$gross_premi_total = intval($em) / 100 * intval($gross_premi);
$gross_premi_total = round(intval($gross_premi_total), 0);
$extra_mortality = intval($gross_premi_total) + intval( $gross_premi);
return $extra_mortality;
}
public static function calculateGrossPremi($params)
{
try {
$product_id = isset($params['product_id']) ? $params['product_id'] : 0;
$usia_masuk = isset($params['usia_masuk']) ? $params['usia_masuk'] : 0;
$loan_start_date = isset($params['loan_start_date']) ? $params['loan_start_date'] : '0000-00-00';
$loan_end_date = isset($params['loan_end_date']) ? $params['loan_end_date'] : '0000-00-00';
$loan_amount = isset($params['loan_amount']) ? $params['loan_amount'] : 0; //Besar Pinjaman (UP)
$query = "SELECT PREMIUM_RATE_ID, PREMIUM_RATE_CODE, FORMULA_RATE_ID, FORMULA_RATE_CODE FROM VW_PRODUCT_DETAIL WHERE PRODUCT_ID = :product_id";
$product_premi = DB::select($query, ['product_id' => $product_id])[0];
if (!empty($product_premi)) {
$premium_rate_id = $product_premi->premium_rate_id;
$formula_rate_code = $product_premi->formula_rate_code;
switch ($formula_rate_code) {
case 'RUP': //ROUNDING UP
return self::calculatePremiRoundingUp($loan_start_date, $loan_end_date, $usia_masuk, $loan_amount, $premium_rate_id);
case 'PRO': //PRORATE
return self::calculatePremiProrate($loan_start_date, $loan_end_date, $usia_masuk, $loan_amount, $premium_rate_id);
}
}
return null;
} catch (\Exception $e) {
throw $e;
}
}
public static function calculatePremiProrate($loan_start_date, $loan_end_date, $usia_masuk, $loan_ammount, $RatePremi)
{
try {
$loan_start_date_obj = \Carbon\Carbon::createFromFormat('d-m-Y', $loan_start_date);
$loan_end_date_obj = \Carbon\Carbon::createFromFormat('d-m-Y', $loan_end_date);
$difference = $loan_start_date_obj->diff($loan_end_date_obj);
$coverage_year = $difference->y;
$coverage_day = $difference->d;
$add_month = ($coverage_day >= 1 && $coverage_day <= 31) ? 1 : 0;
$masa_asuransi_month = $loan_start_date_obj->diffInMonths($loan_end_date_obj) + $add_month;
$coverage_month_mod = $masa_asuransi_month % 12;
if ($coverage_year == 0) {
throw new \Exception("Loan tidak boleh kurang dari 1 tahun.");
}
$rate_low = DB::table('MS_RATE_PREMI as mrp')
->where('mrp.AGE', '=', $usia_masuk)
->where('mrp.INSURANCE_PERIODE_YEAR', '=', $coverage_year)
->where('mrp.MS_PREMIUM_RATE_ID', '=', $RatePremi)
->value('mrp.PREMI_VALUE') ?? 0;
$rate_high = DB::table('MS_RATE_PREMI as mrp')
->where('mrp.AGE', '=', $usia_masuk)
->where('mrp.INSURANCE_PERIODE_YEAR', '=', ($coverage_year + 1))
->where('mrp.MS_PREMIUM_RATE_ID', '=', $RatePremi)
->value('mrp.PREMI_VALUE') ?? 0;
if (!isset($rate_low) || !isset($rate_high)) {
throw new \Exception("Rate untuk perhitungan Gross Premium tidak tersedia.");
}
$calculate_rate = ($rate_low + $coverage_month_mod / 12 * ($rate_high - $rate_low));
$up = ceil($loan_ammount);
$premi_standard = $calculate_rate / 1000 * $up;
$premi = round($premi_standard, 0);
return $premi;
} catch (\Exception $e) {
throw $e;
}
}
public static function calculatePremiRoundingUp($loan_start_date, $loan_end_date, $usia_masuk, $loan_ammount, $RatePremi)
{
try {
$loan_start_date_obj = \Carbon\Carbon::createFromFormat('d-m-Y', $loan_start_date);
$loan_end_date_obj = \Carbon\Carbon::createFromFormat('d-m-Y', $loan_end_date);
$masa_asuransi = $loan_start_date_obj->diffInMonths($loan_end_date_obj);
$round_up = ceil($masa_asuransi / 12);
$premi_value = DB::table('MS_RATE_PREMI as mrp')
->where('mrp.AGE', '=', $usia_masuk)
->where('mrp.INSURANCE_PERIODE_YEAR', '=', $round_up)
->where('mrp.MS_PREMIUM_RATE_ID', '=', $RatePremi)
->value('mrp.PREMI_VALUE');
$up = ceil($loan_ammount);
if (!isset($premi_value)) {
throw new \Exception("Rate untuk perhitungan Gross Premium tidak tersedia.");
}
$premi_standard = $premi_value / 1000 * $up;
$premi = round($premi_standard, 0);
return $premi;
} catch (\Exception $e) {
throw $e;
}
}
public static function generateCertificateSPAJK($product_id,$partner_id)
{
$product_prefix = DB::table('PRODUCT as p')
->select('mbp.ABBREVIATION as prefx')
->join('MS_BASIC_PRODUCT as mbp', 'p.BASIC_PRODUCT', '=', 'mbp.ID')
->where('p.ID', '=', $product_id)
->first();
$no_certif = DB::select("SELECT SEQ_NO_CERTIFICATE.NEXTVAL as no_certif FROM dual");
$no_certif_value = $no_certif[0]->no_certif;
$formatted_no_certif = str_pad($no_certif_value, 5, '0', STR_PAD_LEFT);
$partner = DB::table('MS_PARTNER')
->select('abbreviation_name as prefx')
->where('code', '=', $partner_id)
->first();
$singkatan_value = $product_prefix ? $product_prefix->prefx : '';
$partner_value = $partner ? $partner->prefx : '';
$awalan = "PK";
$certifNo = $awalan . '/' . $singkatan_value . '/' . $partner_value . '-' . $formatted_no_certif;
return $certifNo;
}
}