diff --git a/Modules/Internal/Http/Controllers/Api/MemberController.php b/Modules/Internal/Http/Controllers/Api/MemberController.php
index e3d7bb93..bd912037 100644
--- a/Modules/Internal/Http/Controllers/Api/MemberController.php
+++ b/Modules/Internal/Http/Controllers/Api/MemberController.php
@@ -123,11 +123,10 @@ class MemberController extends Controller
$writer = WriterEntityFactory::createXLSXWriter();
$writer->openToFile(Storage::disk('public')->path('temp/result-'.$file_name));
- $headers_map_to_table_fields = Member::$doc_headers_to_field_map;
+ $headers_map_to_table_fields = $this->memberEnrollmentService->doc_headers_to_field_map;
- // Write Header to File
- $result_headers = array_keys($headers_map_to_table_fields);
- array_push($result_headers, 'Ingestion Status');
+ // Write Header to File with certain Format from MemberEnrollmentService::$result_doc_headers
+ $result_headers = $this->memberEnrollmentService->result_doc_headers;
$singleRow = WriterEntityFactory::createRow($this->memberEnrollmentService->makeResultRow($result_headers));
$writer->addRow($singleRow);
@@ -147,6 +146,7 @@ class MemberController extends Controller
$doc_headers_indexes[$index] = $title;
}
} else { // Next Row Should be Data
+ // Collecting Values from table rows and map it to correct fields
$new_member_data = [];
foreach ($row->getCells() as $header_index => $cell) {
if (isset($headers_map_to_table_fields[$doc_headers_indexes[$header_index]])) {
@@ -155,23 +155,29 @@ class MemberController extends Controller
}
try {
+ // dd($new_member_data);
$rowResponse = $this->memberEnrollmentService->handleImportRow($corporate, $new_member_data);
// Write Success Result to File
- array_push($new_member_data, 'SUCCESS');
- $singleRow = WriterEntityFactory::createRow($this->memberEnrollmentService->makeResultRow($new_member_data));
+ $singleRow = WriterEntityFactory::createRow($this->memberEnrollmentService->makeResultRowWithResultFormat($new_member_data));
$writer->addRow($singleRow);
$imported_member_data++;
} catch (ImportRowException $e) {
// Write Data Validation Error to File
- array_push($new_member_data, $e->getMessage());
- $singleRow = WriterEntityFactory::createRow($this->memberEnrollmentService->makeResultRow($new_member_data));
+ $new_member_data = array_merge($new_member_data, [
+ 'ingestion_code' => $e->getCode(),
+ 'ingestion_status' => $e->getMessage(),
+ ]);
+ $singleRow = WriterEntityFactory::createRow($this->memberEnrollmentService->makeResultRowWithResultFormat($new_member_data));
$writer->addRow($singleRow);
$failed_member_data[] = ['row_number' => $index, 'error' => $e->getMessage()];
} catch (\Exception $e) {
// Write Server Error to File
- array_push($new_member_data, "Server Error");
- $singleRow = WriterEntityFactory::createRow($this->memberEnrollmentService->makeResultRow($new_member_data));
+ $new_member_data = array_merge($new_member_data, [
+ 'ingestion_code' => $e->getCode(),
+ 'ingestion_status' => $e->getMessage(),
+ ]);
+ $singleRow = WriterEntityFactory::createRow($this->memberEnrollmentService->makeResultRowWithResultFormat($new_member_data));
$writer->addRow($singleRow);
$failed_member_data[] = ['row_number' => $index, 'error' => $e->getMessage()];
}
diff --git a/Modules/Internal/Services/MemberEnrollmentService.php b/Modules/Internal/Services/MemberEnrollmentService.php
index 1bd36957..ebd1dcf0 100644
--- a/Modules/Internal/Services/MemberEnrollmentService.php
+++ b/Modules/Internal/Services/MemberEnrollmentService.php
@@ -17,6 +17,230 @@ use DB;
class MemberEnrollmentService
{
+ public $doc_headers_to_field_map = [
+ "Record Mode" => "record_mode",
+ "Record Type" => "record_type",
+ "Payor ID" => "payor_id",
+ "Member ID" => "member_id",
+ "Mapping ID" => "principal_id",
+ "Halodoc Member ID" => "halodoc_member_id",
+ "Corporate ID" => "corporate_id",
+ "NIK" => "nik",
+ "Division" => "division_code",
+ "Branch Code" => "branch_code",
+ "Bank Info" => "banks_info",
+ "Language" => "language",
+ "Type of work" => "type_of_work",
+ "Race" => "race",
+ "Policy Number" => "policy_number",
+ "Policy No." => "policy_number",
+ "Marital Status" => "marital_status",
+ "Relationship" => "relationship_with_principal",
+ "Member's Effective Date" => "member_effective_date",
+ "Member's Expiry Date" => "member_expiry_date",
+ "Faskes FKTP (First Level Provider) or Individual preferred provider" => "faskes_fktp",
+ "Faskes FKRTL (Next Level Provider) or Individual group preferred provider" => "faskes_fkrtl",
+ "The Right Classes Room of BPJS Participants" => "bpjs_class",
+ "Name of Faskes" => "faskes_name",
+ "Rule_BPJSK ('Y' or 'N')" => "bpjsk",
+ "Agent Code / intermediary code" => "agent_code",
+ "Member Name" => "name",
+ "Address1" => "address1",
+ "Address 1" => "address1",
+ "Address2" => "address2",
+ "Address3" => "address3",
+ "Address4" => "address4",
+ "City" => "city",
+ "State" => "state",
+ "Post Code" => "post_code",
+ "Telephone - Mobile" => "telephone_mobile",
+ "Telephone – Mobile" => "telephone_mobile",
+ "Telephone - mobile" => "telephone_mobile",
+ "Telephone – Res" => "telephone_res",
+ "Telephone Res" => "telephone_res",
+ "Telephone - Res" => "telephone_res",
+ "Telephone – Office" => "telephone_office",
+ "Telephone - Office" => "telephone_office",
+ "NRIC" => "nric",
+ "Passport No" => "passport_number",
+ "Passport Country" => "passport_country",
+ "Email" => "email",
+ "Identification Code" => "identification_code",
+ "Date of Birth" => "date_of_birth",
+ "Sex" => "sex",
+ "Internal Use" => "internal_use",
+ "Plan-ID" => "plan_id",
+ "Employment-Status" => "employment_status",
+ "Internal Use" => "internal_use_1",
+ "Internal Use" => "internal_use_2",
+ "Internal Use" => "internal_use_3",
+ "Date Terminated" => "date_terminated",
+ "Pre Existing" => "pre_existing",
+ "BPJS ID" => "bpjs_id",
+ "Endorsement Date" => "endorsement_date",
+ "Remarks" => "remarks",
+ "Internal Use" => "internal_use_4",
+ "Member Since" => "member_since",
+ "Internal Use" => "internal_use_5",
+ "Policy In Force" => "policy_in_force",
+ "Member Suspended" => "member_suspended",
+ "Activation Date" => "activation_date",
+ "Internal Use" => "internal_use_6",
+ "StartNoClaim" => "start_no_claim",
+ "EndNoClaim" => "end_no_claim",
+ "Option Mode" => "option_mode",
+ "Policy Inforce" => "policy_inforce",
+ "Renewal activation date" => "renewal_activation_date",
+ "Renewal Activation Date" => "renewal_activation_date",
+ "Ingestion Code" => "ingestion_code", // TODO I think this should not be here because if user uploading result then ingestion code and status will be filled
+ "Ingestion Status" => "ingestion_status",
+ ];
+
+ public $field_to_doc_headers_map = [
+ "record_mode" => "Record Mode",
+ "record_type" => "Record Type",
+ "payor_id" => "Payor ID",
+ "member_id" => "Member ID",
+ "principal_id" => "Mapping ID",
+ "halodoc_member_id" => "Halodoc Member ID",
+ "corporate_id" => "Corporate ID",
+ "nik" => "NIK",
+ "division_code" => "Division",
+ "branch_code" => "Branch Code",
+ "banks_info" => "Bank Info",
+ "language" => "Language",
+ "type_of_work" => "Type of work",
+ "race" => "Race",
+ "policy_number" => "Policy Number",
+ "policy_number" => "Policy No.",
+ "marital_status" => "Marital Status",
+ "relationship_with_principal" => "Relationship",
+ "member_effective_date" => "Member's Effective Date",
+ "member_expiry_date" => "Member's Expiry Date",
+ "faskes_fktp" => "Faskes FKTP (First Level Provider) or Individual preferred provider",
+ "faskes_fkrtl" => "Faskes FKRTL (Next Level Provider) or Individual group preferred provider",
+ "bpjs_class" => "The Right Classes Room of BPJS Participants",
+ "faskes_name" => "Name of Faskes",
+ "bpjsk" => "Rule_BPJSK ('Y' or 'N')",
+ "agent_code" => "Agent Code / intermediary code",
+ "name" => "Member Name",
+ "address1" => "Address1",
+ "address1" => "Address 1",
+ "address2" => "Address2",
+ "address3" => "Address3",
+ "address4" => "Address4",
+ "city" => "City",
+ "state" => "State",
+ "post_code" => "Post Code",
+ "telephone_mobile" => "Telephone - Mobile",
+ "telephone_res" => "Telephone - Res",
+ "telephone_office" => "Telephone - Office",
+ "nric" => "NRIC",
+ "passport_number" => "Passport No",
+ "passport_country" => "Passport Country",
+ "email" => "Email",
+ "identification_code" => "Identification Code",
+ "date_of_birth" => "Date of Birth",
+ "sex" => "Sex",
+ "internal_use" => "Internal Use",
+ "plan_id" => "Plan-ID",
+ "employment_status" => "Employment-Status",
+ "internal_use_1" => "Internal Use",
+ "internal_use_2" => "Internal Use",
+ "internal_use_3" => "Internal Use",
+ "date_terminated" => "Date Terminated",
+ "pre_existing" => "Pre Existing",
+ "bpjs_id" => "BPJS ID",
+ "endorsement_date" => "Endorsement Date",
+ "remarks" => "Remarks",
+ "internal_use_4" => "Internal Use",
+ "member_since" => "Member Since",
+ "internal_use_5" => "Internal Use",
+ "policy_in_force" => "Policy In Force",
+ "member_suspended" => "Member Suspended",
+ "activation_date" => "Activation Date",
+ "internal_use_6" => "Internal Use",
+ "start_no_claim" => "StartNoClaim",
+ "end_no_claim" => "EndNoClaim",
+ "option_mode" => "Option Mode",
+ "policy_inforce" => "Policy Inforce",
+ "renewal_activation_date" => "Renewal Activation Date",
+ "ingestion_code" => "Ingestion Code",
+ "ingestion_status" => "Ingestion Status",
+ ];
+ public $result_doc_headers = [
+ "Record Mode",
+ "Record Type",
+ "Payor ID",
+ "Member ID",
+ "Mapping ID",
+ "Halodoc Member ID",
+ "Corporate ID",
+ "NIK",
+ "Division",
+ "Branch Code",
+ "Bank Info",
+ "Language",
+ "Type of work",
+ "Race",
+ "Policy Number",
+ "Policy No.",
+ "Marital Status",
+ "Relationship",
+ "Member's Effective Date",
+ "Member's Expiry Date",
+ "Faskes FKTP (First Level Provider) or Individual preferred provider",
+ "Faskes FKRTL (Next Level Provider) or Individual group preferred provider",
+ "The Right Classes Room of BPJS Participants",
+ "Name of Faskes",
+ "Rule_BPJSK ('Y' or 'N')",
+ "Agent Code / intermediary code",
+ "Member Name",
+ "Address1",
+ "Address 1",
+ "Address2",
+ "Address3",
+ "Address4",
+ "City",
+ "State",
+ "Post Code",
+ "Telephone - Mobile",
+ "Telephone - Res",
+ "Telephone - Office",
+ "NRIC",
+ "Passport No",
+ "Passport Country",
+ "Email",
+ "Identification Code",
+ "Date of Birth",
+ "Sex",
+ "Internal Use",
+ "Plan-ID",
+ "Employment-Status",
+ "Internal Use",
+ "Internal Use",
+ "Internal Use",
+ "Date Terminated",
+ "Pre Existing",
+ "BPJS ID",
+ "Endorsement Date",
+ "Remarks",
+ "Internal Use",
+ "Member Since",
+ "Internal Use",
+ "Policy In Force",
+ "Member Suspended",
+ "Activation Date",
+ "Internal Use",
+ "StartNoClaim",
+ "EndNoClaim",
+ "Option Mode",
+ "Policy Inforce",
+ "Renewal Activation Date",
+ "Ingestion Code",
+ "Ingestion Status",
+ ];
+
public function __construct(Member $member)
{
$this->member = $member;
@@ -102,9 +326,9 @@ class MemberEnrollmentService
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') {
+ && !(substr($row['telephone_mobile'], 0, 4) == '+628' || substr($row['telephone_mobile'], 0, 3) == '628')) {
throw new ImportRowException(__('enrollment.PHONE_INVALID'), 0, null, $row);
}
@@ -121,50 +345,46 @@ class MemberEnrollmentService
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'],
+ "name" => $row['name'] ?? null,
+ "member_id" => $row['member_id'] ?? null,
+ "payor_id" => $row['payor_id'] ?? null,
+ "nik" => $row['nik'] ?? null,
"birth_date" => Carbon::parse(strtotime($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'],
- "nric" => $row['nric'],
- "email" => $row['email'],
- "bank_info" => $row['banks_info'],
- "agent_code" => $row['agent_code'],
- "address1" => $row['address1'],
- "address2" => $row['address2'],
- "address3" => $row['address3'],
- "address4" => $row['address4'],
- "city" => $row['city'],
- "state" => $row['state'],
- "postal_code" => $row['post_code'],
- "passport_no" => $row['passport_number'],
- "passport_country" => $row['passport_country'],
- "identification_code" => $row['identification_code'],
- "pre_existing" => $row['pre_existing'],
- "bpjs_id" => $row['bpjs_id'],
- "endorsement_date" => $row['endorsement_date'],
- "remarks" => $row['remarks'],
- "policy_in_force" => $row['policy_in_force'],
- "start_no_claim" => $row['start_no_claim'],
- "end_no_claim" => $row['end_no_claim'],
+ "language" => $row['language'] ?? null,
+ "race" => $row['race'] ?? null,
+ "marital_status" => $row['marital_status'] ?? null,
+ "record_type" => $row['record_type'] ?? null,
+ "principal_id" => $row['principal_id'] ?? null,
+ "relation_with_principal" => $row['relationship_with_principal'] ?? null,
+ "bpjs_class" => $row['bpjs_class'] ?? null,
+ "nric" => $row['nric'] ?? null,
+ "email" => $row['email'] ?? null,
+ "bank_info" => $row['banks_info'] ?? null,
+ "agent_code" => $row['agent_code'] ?? null,
+ "address1" => $row['address1'] ?? null,
+ "address2" => $row['address2'] ?? null,
+ "address3" => $row['address3'] ?? null,
+ "address4" => $row['address4'] ?? null,
+ "city" => $row['city'] ?? null,
+ "state" => $row['state'] ?? null,
+ "postal_code" => $row['post_code'] ?? null,
+ "passport_no" => $row['passport_number'] ?? null,
+ "passport_country" => $row['passport_country'] ?? null,
+ "identification_code" => $row['identification_code'] ?? null,
+ "pre_existing" => $row['pre_existing'] ?? null,
+ "bpjs_id" => $row['bpjs_id'] ?? null,
+ "endorsement_date" => $row['endorsement_date'] ?? null,
+ "remarks" => $row['remarks'] ?? null,
+ "policy_in_force" => $row['policy_in_force'] ?? null,
+ "start_no_claim" => $row['start_no_claim'] ?? null,
+ "end_no_claim" => $row['end_no_claim'] ?? null,
];
if (!isset($corporate->currentPolicy) || $corporate->currentPolicy->code != $row['policy_number']) {
@@ -261,8 +481,8 @@ class MemberEnrollmentService
if (!$memberPolicy->member->isDirty()) {
throw new ImportRowException(__('enrollment.MEMBER_NO_CHANGE'), 0, null, $row);
}
-
- return $memberPolicy->member->save();
+
+ $memberPolicy->member->save();
break;
case "3": // Member Deletion
@@ -288,7 +508,7 @@ class MemberEnrollmentService
$member = $memberPolicy->member;
$member->active = false;
- return $member->save();
+ $member->save();
break;
case "4": // Member Update Start and End Date
$memberPolicy = MemberPolicy::query()
@@ -323,7 +543,7 @@ class MemberEnrollmentService
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_INVALID'), 0, null, $row);
}
- return $memberPolicy->save();
+ $memberPolicy->save();
break;
case "5": // Member Renewal Policy (without card)
@@ -364,7 +584,8 @@ class MemberEnrollmentService
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_NO_CHANGE'), 0, null, $row);
}
- return $memberPolicy->save();
+ $memberPolicy->save();
+
break;
case "6": // Member Renewal Policy (with card)
$memberPolicy = MemberPolicy::query()
@@ -404,7 +625,8 @@ class MemberEnrollmentService
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_NO_CHANGE'), 0, null, $row);
}
- return $memberPolicy->save();
+ $memberPolicy->save();
+
break;
case "7": // Requesting to Change the Unique Data of the Member
$memberPolicy = MemberPolicy::query()
@@ -492,7 +714,7 @@ class MemberEnrollmentService
'end' => $row['member_expiry_date']
]);
- return $memberPolicy->save();
+ $memberPolicy->save();
break;
// case "10": // No Information Available
@@ -555,10 +777,31 @@ class MemberEnrollmentService
throw new ImportRowException(__("enrollment.MODE_UNAVAILABLE"), 0, null, $row);
}
} catch (\Exception $e) {
+ // dd($row, $e->getMessage());
throw new ImportRowException($e->getMessage(), (int) $e->getCode(), $e, $row);
}
+
+ // Should be success then returning new member data with extra ingestion code & status
+ $member_data['ingestion_code'] = "200";
+ $member_data['ingestion_status'] = "SUCCESS";
+
+ return $member_data;
}
+
+ // This returning row with format or order following $result_doc_headers
+ public function makeResultRowWithResultFormat($row_data)
+ {
+ $cells = [];
+ foreach ($this->result_doc_headers as $header) {
+ $value = $row_data[$this->doc_headers_to_field_map[$header]] ?? null;
+ $cells[] = WriterEntityFactory::createCell($value);
+ }
+
+ return $cells;
+ }
+
+ // This returning row with format or order as it is
public function makeResultRow($row_data)
{
$cells = [];
diff --git a/app/Models/Member.php b/app/Models/Member.php
index e42390a2..f938c85a 100644
--- a/app/Models/Member.php
+++ b/app/Models/Member.php
@@ -56,73 +56,6 @@ class Member extends Model
"end_no_claim",
];
- public static $doc_headers_to_field_map = [
- "Record Mode" => "record_mode",
- "Record Type" => "record_type",
- "Payor ID" => "payor_id",
- "Member ID" => "member_id",
- "Mapping ID" => "principal_id",
- "Halodoc Member ID" => "halodoc_member_id",
- "Corporate ID" => "corporate_id",
- "NIK" => "nik",
- "Division" => "division_code",
- "Branch Code" => "branch_code",
- "Bank Info" => "banks_info",
- "Language" => "language",
- "Type of work" => "type_of_work",
- "Race" => "race",
- "Policy Number" => "policy_number",
- "Marital Status" => "marital_status",
- "Relationship" => "relationship_with_principal",
- "Member's Effective Date" => "member_effective_date",
- "Member's Expiry Date" => "member_expiry_date",
- "Faskes FKTP (First Level Provider) or Individual preferred provider" => "faskes_fktp",
- "Faskes FKRTL (Next Level Provider) or Individual group preferred provider" => "faskes_fkrtl",
- "The Right Classes Room of BPJS Participants" => "bpjs_class",
- "Name of Faskes" => "faskes_name",
- "Rule_BPJSK ('Y' or 'N')" => "bpjsk",
- "Agent Code / intermediary code" => "agent_code",
- "Member Name" => "name",
- "Address1" => "address1",
- "Address2" => "address2",
- "Address3" => "address3",
- "Address4" => "address4",
- "City" => "city",
- "State" => "state",
- "Post Code" => "post_code",
- "Telephone – Mobile" => "telephone_mobile",
- "Telephone – Res" => "telephone_res",
- "Telephone – Office" => "telephone_office",
- "NRIC" => "nric",
- "Passport No" => "passport_number",
- "Passport Country" => "passport_country",
- "Email" => "email",
- "Identification Code" => "identification_code",
- "Date of Birth" => "date_of_birth",
- "Sex" => "sex",
- "Internal Use" => "internal_use",
- "Plan-ID" => "plan_id",
- "Employment-Status" => "employment_status",
- "Internal Use" => "internal_use_1",
- "Internal Use" => "internal_use_2",
- "Internal Use" => "internal_use_3",
- "Date Terminated" => "date_terminated",
- "Pre Existing" => "pre_existing",
- "BPJS ID" => "bpjs_id",
- "Endorsement Date" => "endorsement_date",
- "Remarks" => "remarks",
- "Internal Use" => "internal_use_4",
- "Member Since" => "member_since",
- "Internal Use" => "internal_use_5",
- "Policy In Force" => "policy_in_force",
- "Member Suspended" => "member_suspended",
- "Activation Date" => "activation_date",
- "Internal Use" => "internal_use_6",
- "StartNoClaim" => "start_no_claim",
- "EndNoClaim" => "end_no_claim",
- "Option Mode" => "option_mode",
- ];
-
public function employeds()
{
return $this->hasMany(CorporateEmployee::class, 'member_id');
diff --git a/frontend/dashboard/.eslintrc b/frontend/dashboard/.eslintrc
index fdc41fd7..0ddcccd0 100644
--- a/frontend/dashboard/.eslintrc
+++ b/frontend/dashboard/.eslintrc
@@ -17,7 +17,8 @@
"settings": {
"import/resolver": {
"typescript": {
- "alwaysTryTypes": true
+ "alwaysTryTypes": true,
+ "exceptAfterSingleLine": true
}
}
},
diff --git a/frontend/dashboard/src/pages/Corporates/Member/List.tsx b/frontend/dashboard/src/pages/Corporates/Member/List.tsx
index b45b896f..ba1ad6d8 100644
--- a/frontend/dashboard/src/pages/Corporates/Member/List.tsx
+++ b/frontend/dashboard/src/pages/Corporates/Member/List.tsx
@@ -262,14 +262,14 @@ export default function CorporatePlanList() {
{row.member_id}
{row.principal_id}
{row.employeds[0]?.nik}
- {row.current_policy.policy_id}
- {row.current_policy.start}
+ {row.current_policy?.policy_id}
+ {row.current_policy?.start}
{row.name}
{row.nric}
{row.email}
{row.plan_id}
- {row.current_policy.start}
- {row.current_policy.end}
+ {row.current_policy?.start}
+ {row.current_policy?.end}
{( row.active ? ()
: ()
)}