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; } }