Files
aso/Modules/Internal/Services/MemberEnrollmentService.php
2022-07-25 10:20:35 +07:00

548 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'],
];
if ($corporate->currentPolicy->code != $row['policy_number']) {
throw new ImportRowException(__('enrollment.POLICY_NUMBER_NOT_MATCH', [
'policy_id' => $row['policy_number']
]), 0, null, $row);
}
switch ($row['record_mode']) {
case "1": // New Member
$member = Member::query()
->where('member_id', $row['member_id'])
// ->whereHas('employeds', function ($query) use ($corporate) {
// $query->where('corporate_id', $corporate->id);
// })
->first();
if ($member) {
throw new ImportRowException(__('enrollment.MEMBER_UNIQUE', [
'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->member_id,
'policy_id' => $row['policy_number'],
'start' => Carbon::parse(strtotime($row['member_effective_date'])),
'end' => Carbon::parse(strtotime($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(strtotime($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(strtotime($row['member_effective_date'])) > Carbon::parse(strtotime($row['member_expiry_date']))) {
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_INVALID'), 0, null, $row);
}
if (Carbon::parse($memberPolicy->end) > Carbon::parse(strtotime($row['member_expiry_date'])
|| $memberPolicy->end > Carbon::parse(strtotime($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(strtotime($row['member_effective_date'])) > Carbon::parse(strtotime($row['member_expiry_date']))) {
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_INVALID'), 0, null, $row);
}
if (Carbon::parse($memberPolicy->end) > Carbon::parse(strtotime($row['member_expiry_date'])
|| $memberPolicy->end > Carbon::parse(strtotime($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(strtotime($row['member_effective_date'])) < now() || Carbon::parse(strtotime($row['member_expiry_date'])) < now()) {
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_MUST_BE_AFTER_TODAY'), 0, null, $row);
}
if (Carbon::parse(strtotime($row['member_effective_date'])) > Carbon::parse(strtotime($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 $e; //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;
}
}