From da68ae3e05b809b60132f38ff2ecdc75f98da155 Mon Sep 17 00:00:00 2001 From: Tb Fajri Date: Wed, 17 May 2023 09:16:42 +0700 Subject: [PATCH] add validasi import member ship --- .../Api/CorporateMemberController.php | 104 ++++++++++++++++++ Modules/Internal/Routes/api.php | 1 + .../Services/MemberEnrollmentService.php | 89 +++++++++++++-- app/Http/Resources/MemberListResource.php | 32 ++++++ app/Models/Member.php | 6 + ..._17_090708_add_column_to_members_table.php | 36 ++++++ .../src/pages/Corporates/Member/List.tsx | 15 ++- .../Corporate Membership Import List.xlsx | 0 public/files/CorporateMembershipList.xlsx | Bin 0 -> 4037 bytes 9 files changed, 273 insertions(+), 10 deletions(-) create mode 100644 app/Http/Resources/MemberListResource.php create mode 100644 database/migrations/2023_05_17_090708_add_column_to_members_table.php create mode 100755 public/files/Corporate Membership Import List.xlsx create mode 100644 public/files/CorporateMembershipList.xlsx diff --git a/Modules/Internal/Http/Controllers/Api/CorporateMemberController.php b/Modules/Internal/Http/Controllers/Api/CorporateMemberController.php index 4f67e4ac..31ecf692 100755 --- a/Modules/Internal/Http/Controllers/Api/CorporateMemberController.php +++ b/Modules/Internal/Http/Controllers/Api/CorporateMemberController.php @@ -247,4 +247,108 @@ class CorporateMemberController extends Controller $pdf = PDF::loadView('pdf.guaranted_leter', compact(['member', 'dateOfAdmission'])); return $pdf->download('Guaranted Letter - '.$member->full_name.'.pdf'); } + + public function generateMemberList(Request $request, $corporate_id){ + // Mendapatkan data yang akan diekspor (misalnya, dari database) + $data = Member::with(['currentPlan', 'currentCorporate', 'division', 'employeds', 'currentPolicy']) + // ->filter($request->all()) + // ->where('corporate_id', $corporate_id) + ->whereHas('employeds', function ($employeds) use ($corporate_id) { + $employeds->where('corporate_id', $corporate_id); + })->get()->toArray(); + // Membuat penulis entitas Spout + $writer = WriterEntityFactory::createXLSXWriter(); + + // Membuka penulis untuk menulis ke file + $writer->openToFile(public_path('files/CorporateMembershipList.xlsx')); + // Menulis header kolom + $headers_map_to_table_fields = $this->memberEnrollmentService->listing_doc_headers; + $headerRow = WriterEntityFactory::createRowFromArray($headers_map_to_table_fields); + + $writer->addRow($headerRow); + // dd('test'); + // Menulis data + if (!empty($data)) { + foreach ($data as $item) { + $rowData = [ $item['record_type'], // Recode Type + $item['payor_id'], // Payor ID + $item['member_id'], // Member ID + $item['principal_id'], // Mapping ID + NULL, // Link Medis Member ID + $item['current_corporate']['code'] ?? null, // Corporate ID + $item['employeds'][0]['nik'] ?? null, // NIK + $item['division']['code'] ?? null, // Devision + $item['employeds'][0]['branch_code'] ?? null, // Branch Code + $item['bank_info'], // Bank Info + $item['language'], // Language + null, // Type of Work + $item['race'], // Race + $item['current_policy']['code'] ?? null, // Policy Number + $item['marital_status'], // Marital Status + $item['relation_with_principal'], // Relationship + str_replace('-', '',$item['members_effective_date']), // Member effective date + str_replace('-', '',$item['members_expire_date']), // Member expiry date + NULL, // Faskes FKTP (First Level Provider) or Individual preferred provider + NULL, // Faskes FKRTL (Next Level Provider) or Individual group preferred provider + $item['bpjs_class'], // The Right Classes Room of BPJS Participants + NULL, // Name of Faskes + NULL, // Rule BPJSK + NULL, // Internal Use + $item['full_name'], // Member Name + $item['address1'], // Address1 + $item['address2'], // Address2 + $item['address3'], // Address3 + $item['address4'], // Address4 + $item['city'], // City + NULL, // State + $item['postal_code'], // Post Code + NULL, // Telephone - Mobile + NULL, // Telephone - Res + NULL, // Telephone - Office + $item['nric'], // NRIC + $item['passport_no'], // Passport No + $item['passport_country'], // Passport Country + $item['email'], // Email + $item['identification_code'], // Identification Code + $item['birth_date'], // Date of Birth + $item['gender_code'], // Sex + NULL, // Internal Use + $item['current_plan']['code'], // Plan-ID + NULL, // Employment-Status + NULL, // Internal Use + NULL, // Internal Use + NULL,// Internal Use + str_replace('-', '',$item['terminated_date']), // Date Terminated + $item['pre_existing'], // Pre Existing + $item['bpjs_id'], // BPJS ID + $item['endorsement_date'], // Endorsement Date + $item['remarks'], // Remarks + NULL, // Internal Use + NULL,// Member Since + NULL,// Internal Use + $item['policy_in_force'], // Policy Inforce + NULL, // Member Suspended + str_replace('-', '',$item['activation_date']), // Activation Date + NULL, // Internal Use + $item['start_no_claim'], // StartNoClaim + $item['end_no_claim'], // EndNoClaim + NULL, // Option Mode + ]; + $row = WriterEntityFactory::createRowFromArray($rowData); + $writer->addRow($row); + } + } + + // Menutup penulis + $writer->close(); + // dd('test'); + // Mengembalikan response untuk mengunduh file + $filePath = public_path('files/CorporateMembershipList.xlsx'); + // dd($filePath); + // Mengembalikan response untuk mengunduh file + return Helper::responseJson([ + 'file_name' => "Corporate Plan & Benefit List " . date('Y-m-d h:i:s'), + "file_url" => url('files/CorporateMembershipList.xlsx') + ]); + } } diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index efbd0baf..a3eb8867 100755 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -91,6 +91,7 @@ Route::prefix('internal')->group(function () { Route::put('corporates/{corporate_id}/divisions/{id}', [DivisionController::class, 'update']); Route::get('corporates/{corporate_id}/members', [CorporateMemberController::class, 'index']); + Route::get('corporates/{corporate_id}/members/list', [CorporateMemberController::class, 'generateMemberList']); Route::post('corporates/{corporate_id}/members/import', [CorporateMemberController::class, 'import']); Route::put('members/{member_id}/activation', [CorporateMemberController::class, 'activation']); diff --git a/Modules/Internal/Services/MemberEnrollmentService.php b/Modules/Internal/Services/MemberEnrollmentService.php index fe06e671..9c5205d0 100755 --- a/Modules/Internal/Services/MemberEnrollmentService.php +++ b/Modules/Internal/Services/MemberEnrollmentService.php @@ -174,6 +174,7 @@ class MemberEnrollmentService "ingestion_code" => "Ingestion Code", "ingestion_status" => "Ingestion Status", ]; + public $result_doc_headers = [ "Record Mode", "Record Type", @@ -246,6 +247,78 @@ class MemberEnrollmentService "Ingestion Status", ]; + public $listing_doc_headers = [ + // "Record Mode", + "Record Type", + "Payor ID", + "Member ID", + "Mapping ID", + "Link Medis 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", + "Internal Use", + "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 Inforce", + "Member Suspended", + "Activation Date", + "Internal Use", + "StartNoClaim", + "EndNoClaim", + "Option Mode", + // "Renewal Activation Date", + // "Ingestion Code", + // "Ingestion Status", + ]; + public function __construct(Member $member) { $this->member = $member; @@ -462,9 +535,13 @@ class MemberEnrollmentService "members_expire_date" => $row['member_expiry_date'] ?? null, "activation_date" => $row['activation_date'] ?? null, "terminated_date" => $row['date_terminated'] ?? null, + + "telephone_mobile" => $row['telephone_mobile'] ?? null, + "telephone_res" => $row['telephone_res'] ?? null, + "telephone_office" => $row['telephone_office'] ?? null, ]; - $this->validateRow($row); + // $this->validateRow($row); if (!isset($corporate->currentPolicy) || $corporate->currentPolicy->code != $row['policy_number']) { throw new ImportRowException(__('enrollment.POLICY_NUMBER_NOT_MATCH', [ 'policy_id' => $row['policy_number'] @@ -556,6 +633,7 @@ class MemberEnrollmentService switch ($row['record_mode']) { case "1": // New Member + $this->validateRow($row); $member = Member::query() ->where('member_id', $row['member_id']) // ->whereHas('employeds', function ($query) use ($corporate) { @@ -608,11 +686,6 @@ class MemberEnrollmentService if (!$plan) { throw new ImportRowException(__('enrollment.PLAN_NOT_FOUND'), 0, null, $row); } - - - - $this->validateRow($row); - try { DB::beginTransaction(); @@ -675,6 +748,7 @@ class MemberEnrollmentService } break; case "2": // Member Information Update (Without Replacement Card) + $this->validateRow($row); $member = Member::query() ->where('member_id', $row['member_id']) ->first(); @@ -686,9 +760,6 @@ class MemberEnrollmentService 'policy_id' => $row['policy_number'] ]), 0, null, $row); } - - $this->validateRow($row); - try { $memberPolicy = MemberPolicy::query() ->where('policy_id', $row['policy_number']) diff --git a/app/Http/Resources/MemberListResource.php b/app/Http/Resources/MemberListResource.php new file mode 100644 index 00000000..3a0de911 --- /dev/null +++ b/app/Http/Resources/MemberListResource.php @@ -0,0 +1,32 @@ +claims->groupBy('status'); + $data['total_claims'] = [ + 'draft' => count($data['claim_grouped_by_status']['draft'] ?? []), + 'requested' => count($data['claim_grouped_by_status']['requested'] ?? []), + 'received' => count($data['claim_grouped_by_status']['received'] ?? []), + 'approved' => count($data['claim_grouped_by_status']['approved'] ?? []), + 'paid' => count($data['claim_grouped_by_status']['paid'] ?? []), + 'declined' => count($data['claim_grouped_by_status']['declined'] ?? []) + ]; + + // $data = ['fuck' => 'you']; + + return $data; + } +} diff --git a/app/Models/Member.php b/app/Models/Member.php index a9f8e824..a6884783 100755 --- a/app/Models/Member.php +++ b/app/Models/Member.php @@ -147,6 +147,12 @@ class Member extends Model ->latest(); // TODO Fix This } + public function currentEmployeds() + { + return $this->hasOneThrough(CorporateEmployee::class, Person::class, 'nik', 'id', 'id', 'nik') + ->latest(); // TODO Fix This + } + public function policies() { return $this->hasMany(MemberPolicy::class, 'member_id', 'member_id'); diff --git a/database/migrations/2023_05_17_090708_add_column_to_members_table.php b/database/migrations/2023_05_17_090708_add_column_to_members_table.php new file mode 100644 index 00000000..188f86ee --- /dev/null +++ b/database/migrations/2023_05_17_090708_add_column_to_members_table.php @@ -0,0 +1,36 @@ +string('telephone_mobile')->after('postal_code')->nullable(); + $table->string('telephone_res')->after('telephone_mobile')->nullable(); + $table->string('telephone_office')->after('telephone_res')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('members', function (Blueprint $table) { + $table->dropColumn('telephone_mobile'); + $table->dropColumn('telephone_res'); + $table->dropColumn('telephone_office'); + }); + } +}; diff --git a/frontend/dashboard/src/pages/Corporates/Member/List.tsx b/frontend/dashboard/src/pages/Corporates/Member/List.tsx index d0a695d8..38678411 100755 --- a/frontend/dashboard/src/pages/Corporates/Member/List.tsx +++ b/frontend/dashboard/src/pages/Corporates/Member/List.tsx @@ -79,7 +79,6 @@ export default function CorporatePlanList() { .catch((response) => { enqueueSnackbar('Failed getting data. ' + response.message, { variant: 'error' }); }); - // console.log(response.data); setDataTableLoading(false); setDataTableData(response.data); @@ -161,6 +160,19 @@ export default function CorporatePlanList() { } }; + const handleMemberList = async (appliedFilter = null) => { + axios.get('corporates/' + corporate_id + '/members/list').then((response) => { + console.log(response); + const link = document.createElement('a'); + console.log(response.data.data.file_name); + link.href = response.data.data.file_url; + link.setAttribute('download', response.data.data.file_name); + document.body.appendChild(link); + link.click(); + handleClose(); + }); + } + const handleCancelImportButton = () => { importPlan.current.value = ''; importPlan.current.dispatchEvent(new Event('change', { bubbles: true })); @@ -254,6 +266,7 @@ export default function CorporatePlanList() { > Download Template + Download Member )} diff --git a/public/files/Corporate Membership Import List.xlsx b/public/files/Corporate Membership Import List.xlsx new file mode 100755 index 00000000..e69de29b diff --git a/public/files/CorporateMembershipList.xlsx b/public/files/CorporateMembershipList.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..4400f4e4524c8b4a363ed31b34b6d71901ce7d8e GIT binary patch literal 4037 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 VE*bgRpH%qo4Sa~a&sHYDzW^@*(Cq*K literal 0 HcmV?d00001