538 lines
24 KiB
PHP
538 lines
24 KiB
PHP
<?php
|
|
|
|
namespace Modules\Internal\Services;
|
|
|
|
use App\Exceptions\ImportRowException;
|
|
use App\Helpers\Helper;
|
|
use App\Models\Corporate;
|
|
use App\Models\CorporateDivision;
|
|
use App\Models\CorporatePlan;
|
|
use App\Models\Member;
|
|
use App\Models\MemberPolicy;
|
|
use App\Models\Plan;
|
|
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
|
|
use Box\Spout\Common\Entity\Row;
|
|
use Carbon\Carbon;
|
|
use DB;
|
|
|
|
class MemberEnrollmentService
|
|
{
|
|
public function __construct(Member $member)
|
|
{
|
|
$this->member = $member;
|
|
}
|
|
|
|
protected function validateRow($row)
|
|
{
|
|
if (empty($row['record_type'])) {
|
|
throw new ImportRowException(__('enrollment.RECORD_TYPE_REQUIRED'), 0, null, $row);
|
|
}
|
|
|
|
if (empty($row['payor_id'])) {
|
|
throw new ImportRowException(__('enrollment.PAYOR_ID_REQUIRED'), 0, null, $row);
|
|
}
|
|
|
|
if (empty($row['member_id'])) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_ID_REQUIRED'), 0, null, $row);
|
|
}
|
|
|
|
if ($row['record_type'] == 'P') {
|
|
if (!empty($row['principal_id'])) {
|
|
throw new ImportRowException(__('enrollment.PRINCIPAL_ID_NOT_REQUIRED'), 0, null, $row);
|
|
}
|
|
|
|
if (empty($row['corporate_id'])) {
|
|
throw new ImportRowException(__('enrollment.CORPORATE_ID_REQUIRED'), 0, null, $row);
|
|
}
|
|
}
|
|
|
|
if ($row['record_type'] == 'D') {
|
|
if (empty($row['principal_id'])) {
|
|
throw new ImportRowException(__('enrollment.PRINCIPAL_ID_REQUIRED'), 0, null, $row);
|
|
}
|
|
}
|
|
|
|
// TOOD RECORD BCA ONLY
|
|
if ($row['record_type'] == 'D' && !empty($row['branch_code'])) {
|
|
throw new ImportRowException(__('enrollment.BRANCH_CODE_NOT_REQUIRED'), 0, null, $row);
|
|
}
|
|
|
|
// TODO BANK VALIDATION
|
|
// if ($row['record_type'] == 'D' && !empty($row['branch_code'])) {
|
|
// throw new ImportRowException(__('enrollment.BRANCH_CODE_NOT_REQUIRED'), 0, null, $row);
|
|
// }
|
|
|
|
if (!empty($row['language']) && !in_array($row['language'], ['M', 'E', 'C', 'I', 'O'])) {
|
|
throw new ImportRowException(__('enrollment.INVALID_LANGUAGE'), 0, null, $row);
|
|
}
|
|
|
|
if (!empty($row['type_of_work']) && !in_array($row['type_of_work'], ['0', '1', '2', '3'])) {
|
|
throw new ImportRowException(__('enrollment.INVALID_TYPE_OF_WORK'), 0, null, $row);
|
|
}
|
|
|
|
if (!empty($row['race']) && !in_array($row['race'], ['M', 'C', 'I', 'O'])) {
|
|
throw new ImportRowException(__('enrollment.INVALID_RACE'), 0, null, $row);
|
|
}
|
|
|
|
if (empty($row['policy_number'])) {
|
|
throw new ImportRowException(__('enrollment.POLICY_NUMBER_REQUIRED'), 0, null, $row);
|
|
}
|
|
|
|
if (!empty($row['marital_status']) && !in_array($row['marital_status'], ['S', 'M', 'D'])) {
|
|
throw new ImportRowException(__('enrollment.INVALID_MARITAL_STATUS'), 0, null, $row);
|
|
}
|
|
|
|
if (empty($row['member_effective_date']) ) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_EFFECTIVE_REQUIRED'), 0, null, $row);
|
|
}
|
|
// TODO EFFECTIVE DATE VALIDATION
|
|
|
|
if (empty($row['member_expiry_date']) ) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_REQUIRED'), 0, null, $row);
|
|
}
|
|
// TODO EFFECTIVE DATE VALIDATION
|
|
|
|
// TODO FKTP VALIDATION
|
|
// TODO FKRTL VALIDATION
|
|
|
|
if (!empty($row['marital_status']) && !in_array($row['marital_status'], ['S', 'M', 'D'])) {
|
|
throw new ImportRowException(__('enrollment.INVALID_MARITAL_STATUS'), 0, null, $row);
|
|
}
|
|
|
|
if (empty($row['name'])) {
|
|
throw new ImportRowException(__('enrollment.NAME_REQUIRED'), 0, null, $row);
|
|
}
|
|
|
|
if (!empty($row['telephone_mobile'])
|
|
&& substr($row['telephone_mobile'], 0, 4) != '+628') {
|
|
throw new ImportRowException(__('enrollment.PHONE_INVALID'), 0, null, $row);
|
|
}
|
|
|
|
if (!empty($row['email'])
|
|
&& !filter_var($row['email'], FILTER_VALIDATE_EMAIL)) {
|
|
throw new ImportRowException(__('enrollment.EMAIL_INVALID'), 0, null, $row);
|
|
}
|
|
|
|
if (empty($row['date_of_birth'])) {
|
|
throw new ImportRowException(__('enrollment.DATE_OF_BIRTH_REQUIRED'), 0, null, $row);
|
|
}
|
|
// TODO DOB FORMAT VALIDATION
|
|
|
|
if (empty($row['sex'])) {
|
|
throw new ImportRowException(__('enrollment.SEX_REQUIRED'), 0, null, $row);
|
|
}
|
|
|
|
if (empty($row['sex'])) {
|
|
throw new ImportRowException(__('enrollment.SEX_REQUIRED'), 0, null, $row);
|
|
}
|
|
}
|
|
|
|
public function handleImportRow(Corporate $corporate, $row)
|
|
{
|
|
try {
|
|
$member_data = [
|
|
"name" => $row['name'],
|
|
"member_id" => $row['member_id'],
|
|
"payor_id" => $row['payor_id'],
|
|
"nik" => $row['nik'],
|
|
"birth_date" => Carbon::parse($row['date_of_birth']),
|
|
"gender" => Helper::genderNormalization($row['sex']),
|
|
"language" => $row['language'],
|
|
"race" => $row['race'],
|
|
"marital_status" => $row['marital_status'],
|
|
"record_type" => $row['record_type'],
|
|
"principal_id" => $row['principal_id'],
|
|
"relation_with_principal" => $row['relationship_with_principal'],
|
|
"bpjs_class" => $row['bpjs_class'],
|
|
];
|
|
|
|
switch ($row['record_mode']) {
|
|
case "1": // New Member
|
|
$member = Member::query()
|
|
->where('member_id', $row['member_id'])
|
|
->first();
|
|
|
|
if ($member) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_EXISTS', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
} else {
|
|
$member = new Member();
|
|
}
|
|
|
|
$memberPolicy = $member->policies()
|
|
->where('policy_id', $row['policy_number'])
|
|
->first();
|
|
|
|
if ($memberPolicy) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_EXISTS', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
$this->validateRow($row);
|
|
|
|
try {
|
|
DB::beginTransaction();
|
|
$member->fill($member_data);
|
|
if ($member->save()) {
|
|
$memberPolicy = new MemberPolicy();
|
|
$memberPolicy->fill([
|
|
'member_id' => $member->id,
|
|
'policy_id' => $row['policy_number'],
|
|
'start' => Carbon::parse($row['member_effective_date']),
|
|
'end' => Carbon::parse($row['member_expiry_date']),
|
|
'status' => 'active'
|
|
]);
|
|
$memberPolicy->save();
|
|
|
|
if (!empty($row['division'])) {
|
|
$division_id = CorporateDivision::where('code', $row['division_code'])->where('')->pluck('id');
|
|
}
|
|
|
|
$member->employeds()->create([
|
|
'corporate_id' => $corporate->id,
|
|
'branch_code' => $row['branch_code'],
|
|
'division_id' => $division_id ?? null,
|
|
'nik' => $row['nik']
|
|
]);
|
|
}
|
|
DB::commit();
|
|
} catch (\Exception $e) {
|
|
DB::rollback();
|
|
throw new ImportRowException($e->getMessage(), $e->getCode(), $e, $row);
|
|
}
|
|
break;
|
|
case "2": // Member Information Update (Without Replacement Card)
|
|
$memberPolicy = MemberPolicy::query()
|
|
->where('policy_id', $row['policy_number'])
|
|
->where('member_id', $row['member_id'])
|
|
->with('member')
|
|
->first();
|
|
|
|
if (!$memberPolicy) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
if ($memberPolicy->status != 'active') {
|
|
throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
$memberPolicy->member->fill($member_data);
|
|
if (!$memberPolicy->member->isDirty()) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_NO_CHANGE'), 0, null, $row);
|
|
}
|
|
|
|
return $memberPolicy->member->save();
|
|
|
|
break;
|
|
case "3": // Member Deletion
|
|
$memberPolicy = MemberPolicy::query()
|
|
->where('policy_id', $row['policy_number'])
|
|
->where('member_id', $row['member_id'])
|
|
->first();
|
|
|
|
if (!$memberPolicy) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
if ($memberPolicy->status != 'active') {
|
|
throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
return $memberPolicy->delete();
|
|
break;
|
|
case "4": // Member Update Start and End Date
|
|
$memberPolicy = MemberPolicy::query()
|
|
->where('policy_id', $row['policy_number'])
|
|
->where('member_id', $row['member_id'])
|
|
->first();
|
|
|
|
if (!$memberPolicy) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
if ($memberPolicy->status != 'active') {
|
|
throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
$memberPolicy->fill([
|
|
'start' => $row['start_date'],
|
|
'end' => $row['end_date']
|
|
]);
|
|
|
|
if (!$memberPolicy->isDirty()) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_NO_CHANGE'), 0, null, $row);
|
|
}
|
|
|
|
if (Carbon::parse($row['member_effective_date']) > Carbon::parse($row['end_date'])) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_INVALID'), 0, null, $row);
|
|
}
|
|
|
|
return $memberPolicy->save();
|
|
|
|
break;
|
|
case "5": // Member Renewal Policy (without card)
|
|
$memberPolicy = MemberPolicy::query()
|
|
->where('policy_id', $row['policy_number'])
|
|
->where('member_id', $row['member_id'])
|
|
->first();
|
|
|
|
if (!$memberPolicy) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
if ($memberPolicy->status != 'active') {
|
|
throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
if (Carbon::parse($row['member_effective_date']) > Carbon::parse($row['member_expiry_date'])) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_INVALID'), 0, null, $row);
|
|
}
|
|
|
|
if (Carbon::parse($memberPolicy->end) > Carbon::parse($row['member_expiry_date']
|
|
|| $memberPolicy->end > Carbon::parse($row['member_expiry_date']))) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_RENEWAL_STILL_ACTIVE'), 0, null, $row);
|
|
}
|
|
|
|
$memberPolicy->fill([
|
|
'start' => $row['member_expiry_date'],
|
|
'end' => $row['member_expiry_date']
|
|
]);
|
|
|
|
if (!$memberPolicy->isDirty()) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_NO_CHANGE'), 0, null, $row);
|
|
}
|
|
|
|
return $memberPolicy->save();
|
|
break;
|
|
case "6": // Member Renewal Policy (with card)
|
|
$memberPolicy = MemberPolicy::query()
|
|
->where('policy_id', $row['policy_number'])
|
|
->where('member_id', $row['member_id'])
|
|
->first();
|
|
|
|
if (!$memberPolicy) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
if ($memberPolicy->status != 'active') {
|
|
throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
if (Carbon::parse($row['member_effective_date']) > Carbon::parse($row['member_expiry_date'])) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_INVALID'), 0, null, $row);
|
|
}
|
|
|
|
if (Carbon::parse($memberPolicy->end) > Carbon::parse($row['member_expiry_date']
|
|
|| $memberPolicy->end > Carbon::parse($row['member_expiry_date']))) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_RENEWAL_STILL_ACTIVE'), 0, null, $row);
|
|
}
|
|
|
|
$memberPolicy->fill([
|
|
'start' => $row['member_expiry_date'],
|
|
'end' => $row['member_expiry_date']
|
|
]);
|
|
|
|
if (!$memberPolicy->isDirty()) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_NO_CHANGE'), 0, null, $row);
|
|
}
|
|
|
|
return $memberPolicy->save();
|
|
break;
|
|
case "7": // Requesting to Change the Unique Data of the Member
|
|
$memberPolicy = MemberPolicy::query()
|
|
->where('policy_id', $row['policy_number'])
|
|
->where('member_id', $row['member_id'])
|
|
->with('member')
|
|
->first();
|
|
|
|
if (!$memberPolicy) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
if ($memberPolicy->status != 'active') {
|
|
throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
// TODO OPTION MODE FORMAT VALIDATION
|
|
if (empty($row["option_mode"])) {
|
|
throw new ImportRowException(__('enrollment.OPTION_MODE_INVALID_FORMAT', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
if (
|
|
$row['record_type'] == 'P' &&
|
|
$memberPolicy->member->corporate->code == $row["corporate_id"] &&
|
|
$memberPolicy->policy_id == $row['policy_number'] &&
|
|
$memberPolicy->member_id == $row['member_id'] &&
|
|
$memberPolicy->member->record_type == $row['record_type']
|
|
) {
|
|
throw new ImportRowException(__('enrollment.UNIQUE_CHANGE_PRINCIPAL_INVALID', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
if (
|
|
$row['record_type'] == 'D' &&
|
|
$memberPolicy->member->corporate->code == $row["corporate_id"] &&
|
|
$memberPolicy->policy_id == $row['policy_number'] &&
|
|
$memberPolicy->member->record_type == $row['record_type'] &&
|
|
$memberPolicy->member->payor_id == $row['payor_id']
|
|
) {
|
|
throw new ImportRowException(__('enrollment.UNIQUE_CHANGE_DEPENDANT_INVALID', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
throw new ImportRowException(__('MODE 7 NOT HANDLED PROPERLY'), 0, null, $row);
|
|
break;
|
|
case "8": // Member Information Update (With Replacement Card)
|
|
|
|
break;
|
|
case "9": // Member Reactivation and Personal information update (Without replacement Card)
|
|
$memberPolicy = MemberPolicy::query()
|
|
->where('policy_id', $row['policy_number'])
|
|
->where('member_id', $row['member_id'])
|
|
->first();
|
|
|
|
if (!$memberPolicy) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
if (Carbon::parse($row['member_effective_date']) < now() || Carbon::parse($row['member_expiry_date']) < now()) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_MUST_BE_AFTER_TODAY'), 0, null, $row);
|
|
}
|
|
|
|
if (Carbon::parse($row['member_effective_date']) > Carbon::parse($row['member_expiry_date'])) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_INVALID'), 0, null, $row);
|
|
}
|
|
|
|
$memberPolicy->fill([
|
|
'start' => $row['member_effective_date'],
|
|
'end' => $row['member_expiry_date']
|
|
]);
|
|
|
|
return $memberPolicy->save();
|
|
break;
|
|
// case "10": // No Information Available
|
|
|
|
// break;
|
|
case "11": // Advance Renewal with OLD Card No. (PRINT)
|
|
|
|
throw new ImportRowException(__('MODE 11 NOT HANDLED PROPERLY'), 0, null, $row);
|
|
break;
|
|
case "12": // Advance Renewal iwh NEW Card No. (PRINT)
|
|
|
|
throw new ImportRowException(__('MODE 12 NOT HANDLED PROPERLY'), 0, null, $row);
|
|
break;
|
|
case "13": // Advance Renewal with OLD Card No. (NO PRINT)
|
|
|
|
throw new ImportRowException(__('MODE 13 NOT HANDLED PROPERLY'), 0, null, $row);
|
|
break;
|
|
// case "14": // No Information Available
|
|
|
|
// break;
|
|
case "15": // Lost Card / Change Card with new card number (Print) (Rarely Used)
|
|
|
|
throw new ImportRowException(__('MODE 15 NOT HANDLED PROPERLY'), 0, null, $row);
|
|
break;
|
|
case "16": // Endorsement Plan OLD Card No. (NO PRINT)
|
|
$plan = CorporatePlan::query()
|
|
->where('corporate_id', $corporate->id)
|
|
->where('code', $row['plan_id'])
|
|
->where('active', true)
|
|
->first();
|
|
if (!$plan) {
|
|
throw new ImportRowException(__('enrollment.PLAN_NOT_FOUND'), 0, null, $row);
|
|
}
|
|
|
|
$memberPolicy = MemberPolicy::query()
|
|
->where('policy_id', $row['policy_number'])
|
|
->where('member_id', $row['member_id'])
|
|
->first();
|
|
|
|
if (!$memberPolicy) {
|
|
throw new ImportRowException(__('enrollment.MEMBER_NOT_EXISTS', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
if ($memberPolicy->status != 'active') {
|
|
throw new ImportRowException(__('enrollment.MEMBER_INACTIVE', [
|
|
'member_id' => $row['member_id'],
|
|
'policy_id' => $row['policy_number']
|
|
]), 0, null, $row);
|
|
}
|
|
|
|
throw new ImportRowException(__('MODE 16 NOT HANDLED PROPERLY'), 0, null, $row);
|
|
break;
|
|
case "17": // Endorsement Plan OLD Card No. (PRINT)
|
|
|
|
throw new ImportRowException(__('MODE 17 NOT HANDLED PROPERLY'), 0, null, $row);
|
|
break;
|
|
default:
|
|
throw new ImportRowException(__("enrollment.MODE_UNAVAILABLE"), 0, null, $row);
|
|
}
|
|
} catch (\Exception $e) {
|
|
throw new ImportRowException($e->getMessage(), (int) $e->getCode(), $e, $row);
|
|
}
|
|
}
|
|
|
|
public function makeResultRow($row_data)
|
|
{
|
|
$cells = [];
|
|
foreach ($row_data as $cellValue) {
|
|
$cells[] = WriterEntityFactory::createCell($cellValue);
|
|
}
|
|
|
|
return $cells;
|
|
}
|
|
}
|