From 4e99ba51094838d02c36db58cb8326c4ff54496a Mon Sep 17 00:00:00 2001 From: Dell Date: Tue, 12 Jul 2022 13:23:27 +0700 Subject: [PATCH] Re Route --- .../Controllers/Api/BenefitController.php | 147 +++++++++++ .../Api/CorporateBenefitController.php | 86 ++++++ .../Api/CorporatePlanController.php | 86 ++++++ .../Http/Controllers/Api/PlanController.php | 2 +- Modules/Internal/Routes/api.php | 12 +- app/Models/Benefit.php | 17 ++ app/Models/CorporateBenefit.php | 11 + app/Models/CorporatePlan.php | 9 + app/Models/CorporatePolicy.php | 6 + app/Models/MemberBenefit.php | 98 +++++++ ...022_06_23_070847_create_benefits_table.php | 61 ++++- ...23_094719_create_member_benefits_table.php | 89 ------- ...025440_create_corporate_benefits_table.php | 43 +++ database/seeders/BenefitSeeder.php | 43 +-- frontend/dashboard/src/@types/corporates.ts | 66 ++++- .../src/pages/Corporates/Benefit/Index.tsx | 5 +- .../src/pages/Corporates/Benefit/List.tsx | 159 ++++++----- .../Corporates/CorporateBenefit/Create.tsx | 241 +++++++++++++++++ .../Corporates/CorporateBenefit/Index.tsx | 54 ++++ .../Corporates/CorporateBenefit/List.tsx | 220 ++++++++++++++++ .../pages/Corporates/CorporatePlan/Create.tsx | 247 ++++++++++++++++++ .../pages/Corporates/CorporatePlan/Index.tsx | 53 ++++ .../pages/Corporates/CorporatePlan/List.tsx | 221 ++++++++++++++++ .../Corporates/CorporateTabNavigations.tsx | 30 ++- .../dashboard/src/pages/Corporates/Form.tsx | 2 +- .../src/pages/Corporates/Plan/Index.tsx | 5 +- .../src/pages/Corporates/Plan/List.tsx | 4 +- .../dashboard/src/pages/Corporates/Show.tsx | 7 +- frontend/dashboard/src/routes/index.tsx | 30 ++- 29 files changed, 1826 insertions(+), 228 deletions(-) create mode 100644 Modules/Internal/Http/Controllers/Api/BenefitController.php create mode 100644 Modules/Internal/Http/Controllers/Api/CorporateBenefitController.php create mode 100644 Modules/Internal/Http/Controllers/Api/CorporatePlanController.php create mode 100644 app/Models/CorporateBenefit.php delete mode 100644 database/migrations/2022_06_23_094719_create_member_benefits_table.php create mode 100644 database/migrations/2022_07_12_025440_create_corporate_benefits_table.php create mode 100644 frontend/dashboard/src/pages/Corporates/CorporateBenefit/Create.tsx create mode 100644 frontend/dashboard/src/pages/Corporates/CorporateBenefit/Index.tsx create mode 100644 frontend/dashboard/src/pages/Corporates/CorporateBenefit/List.tsx create mode 100644 frontend/dashboard/src/pages/Corporates/CorporatePlan/Create.tsx create mode 100644 frontend/dashboard/src/pages/Corporates/CorporatePlan/Index.tsx create mode 100644 frontend/dashboard/src/pages/Corporates/CorporatePlan/List.tsx diff --git a/Modules/Internal/Http/Controllers/Api/BenefitController.php b/Modules/Internal/Http/Controllers/Api/BenefitController.php new file mode 100644 index 00000000..f50ab213 --- /dev/null +++ b/Modules/Internal/Http/Controllers/Api/BenefitController.php @@ -0,0 +1,147 @@ +filter($request->all()) + ->where('corporate_id', $corporate_id) + ->paginate(0) + ->appends($request->all()); + + return $benefits; + } + + /** + * Show the form for creating a new resource. + * @return Renderable + */ + public function create() + { + return view('internal::create'); + } + + /** + * Store a newly created resource in storage. + * @param Request $request + * @return Renderable + */ + public function store(Request $request) + { + // + } + + /** + * Show the specified resource. + * @param int $id + * @return Renderable + */ + public function show($id) + { + return view('internal::show'); + } + + /** + * Show the form for editing the specified resource. + * @param int $id + * @return Renderable + */ + public function edit($id) + { + return view('internal::edit'); + } + + /** + * Update the specified resource in storage. + * @param Request $request + * @param int $id + * @return Renderable + */ + public function update(Request $request, $id) + { + // + } + + /** + * Remove the specified resource from storage. + * @param int $id + * @return Renderable + */ + public function destroy($id) + { + // + } + + public function memberBenefitImport(Request $request, $corporate_id) + { + $request->validate([ + 'file' => 'required|file|mimes:xls,xlsx,csv,txt', + ]); + $file_name = now()->getPreciseTimestamp(3).'-'.$request->file('file')->getClientOriginalName(); + $file = $request->file('file')->storeAs('temp', $file_name); + + $reader = ReaderEntityFactory::createReaderFromFile(Storage::path('temp/'.$file_name)); + $reader->open(Storage::path('temp/'.$file_name)); + + $headers_map_to_table_fields = MemberBenefit::$doc_headers_to_field_map; + + $imported_benefit_data = 0; + $failed_benefit_data = []; + foreach ($reader->getSheetIterator() as $sheet) { + $doc_headers_indexes = []; + foreach ($sheet->getRowIterator() as $index => $row) { + if ($index == 1) { // First Row Must be Header + foreach ($row->getCells() as $index => $cell) { + $doc_headers_indexes[$index] = rtrim($cell->getValue()); + } + } else { // Next Row Should be Data + $new_benefit_data = []; + foreach ($row->getCells() as $index => $cell) { + $new_benefit_data[$headers_map_to_table_fields[$doc_headers_indexes[$index]]] = $cell->getValue(); + } + + // $imported_plan_data[] = $new_row; // Insert to Array + // Create Directly + $new_benefit_data['corporate_id'] = $corporate_id; + try { + MemberBenefit::updateOrCreate([ + 'corporate_id' => $corporate_id, + 'code' => $new_benefit_data['code'] + ], $new_benefit_data); + + $imported_benefit_data++; + } catch(\Exception $e) { + $new_benefit_data['error'] = $e->getMessage(); + $failed_benefit_data[] = $new_benefit_data; + } + } + } + + break; //only read first sheet + } + $reader->close(); + Storage::delete('temp/'.$file_name); + // throw(404); + + return [ + 'total_successed_row' => $imported_benefit_data, + 'total_failed_row' => count($failed_benefit_data), + 'failed_row' => $failed_benefit_data + ]; + } +} diff --git a/Modules/Internal/Http/Controllers/Api/CorporateBenefitController.php b/Modules/Internal/Http/Controllers/Api/CorporateBenefitController.php new file mode 100644 index 00000000..fe07e0da --- /dev/null +++ b/Modules/Internal/Http/Controllers/Api/CorporateBenefitController.php @@ -0,0 +1,86 @@ +filter($request->all()) + ->where('corporate_id', $corporate_id) + ->paginate(0) + ->appends($request->all()); + + return $benefits; + } + + /** + * Show the form for creating a new resource. + * @return Renderable + */ + public function create() + { + return view('internal::create'); + } + + /** + * Store a newly created resource in storage. + * @param Request $request + * @return Renderable + */ + public function store(Request $request) + { + // + } + + /** + * Show the specified resource. + * @param int $id + * @return Renderable + */ + public function show($id) + { + return view('internal::show'); + } + + /** + * Show the form for editing the specified resource. + * @param int $id + * @return Renderable + */ + public function edit($id) + { + return view('internal::edit'); + } + + /** + * Update the specified resource in storage. + * @param Request $request + * @param int $id + * @return Renderable + */ + public function update(Request $request, $id) + { + // + } + + /** + * Remove the specified resource from storage. + * @param int $id + * @return Renderable + */ + public function destroy($id) + { + // + } +} diff --git a/Modules/Internal/Http/Controllers/Api/CorporatePlanController.php b/Modules/Internal/Http/Controllers/Api/CorporatePlanController.php new file mode 100644 index 00000000..1e872c4f --- /dev/null +++ b/Modules/Internal/Http/Controllers/Api/CorporatePlanController.php @@ -0,0 +1,86 @@ +filter($request->all()) + ->where('corporate_id', $corporate_id) + ->paginate(0) + ->appends($request->all()); + + return $benefits; + } + + /** + * Show the form for creating a new resource. + * @return Renderable + */ + public function create() + { + return view('internal::create'); + } + + /** + * Store a newly created resource in storage. + * @param Request $request + * @return Renderable + */ + public function store(Request $request) + { + // + } + + /** + * Show the specified resource. + * @param int $id + * @return Renderable + */ + public function show($id) + { + return view('internal::show'); + } + + /** + * Show the form for editing the specified resource. + * @param int $id + * @return Renderable + */ + public function edit($id) + { + return view('internal::edit'); + } + + /** + * Update the specified resource in storage. + * @param Request $request + * @param int $id + * @return Renderable + */ + public function update(Request $request, $id) + { + // + } + + /** + * Remove the specified resource from storage. + * @param int $id + * @return Renderable + */ + public function destroy($id) + { + // + } +} diff --git a/Modules/Internal/Http/Controllers/Api/PlanController.php b/Modules/Internal/Http/Controllers/Api/PlanController.php index 95a1ad03..0a318bb3 100644 --- a/Modules/Internal/Http/Controllers/Api/PlanController.php +++ b/Modules/Internal/Http/Controllers/Api/PlanController.php @@ -89,7 +89,7 @@ class PlanController extends Controller // } - public function plansImport(Request $request, $corporate_id) + public function planImport(Request $request, $corporate_id) { $request->validate([ 'file' => 'required|file|mimes:xls,xlsx,csv,txt', diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index f998157b..177a798a 100644 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -2,7 +2,10 @@ use Modules\Internal\Http\Controllers\Api\AuthController; use Illuminate\Http\Request; +use Modules\Internal\Http\Controllers\Api\BenefitController; +use Modules\Internal\Http\Controllers\Api\CorporateBenefitController; use Modules\Internal\Http\Controllers\Api\CorporateController; +use Modules\Internal\Http\Controllers\Api\CorporatePlanController; use Modules\Internal\Http\Controllers\Api\PlanController; /* @@ -32,9 +35,14 @@ Route::prefix('internal')->group(function () { }); Route::resource('corporates', CorporateController::class); - // Route::post('corporates/{id}/plans', [CorporateController::class, 'planImport']); Route::get('corporates/{corporate_id}/plans', [PlanController::class, 'index']); Route::post('corporates/{corporate_id}/plans/import', [PlanController::class, 'planImport']); + + Route::get('corporates/{corporate_id}/benefits', [BenefitController::class, 'index']); + Route::post('corporates/{corporate_id}/benefits/import', [BenefitController::class, 'memberBenefitImport']); + + Route::get('corporates/{corporate_id}/corporate-plans', [CorporatePlanController::class, 'index']); + + Route::get('corporates/{corporate_id}/corporate-benefits', [CorporateBenefitController::class, 'index']); }); }); -// Route::resource('corporates', CorporateController::class); diff --git a/app/Models/Benefit.php b/app/Models/Benefit.php index becbcf1a..a103d1ad 100644 --- a/app/Models/Benefit.php +++ b/app/Models/Benefit.php @@ -8,4 +8,21 @@ use Illuminate\Database\Eloquent\Model; class Benefit extends Model { use HasFactory; + + protected $fillable = [ + "corporate_id", + "code", + "name", + "description" + ]; + + public function scopeFilter($query, array $filters) + { + $query->when($filters['search'] ?? false, function ($query, $search) { + return $query + ->where('code', 'like', "%" . $search . "%") + ->orWhere('name', 'like', "%" . $search . "%") + ->orWhere('description', 'like', "%" . $search . "%"); + }); + } } diff --git a/app/Models/CorporateBenefit.php b/app/Models/CorporateBenefit.php new file mode 100644 index 00000000..4e5e42d0 --- /dev/null +++ b/app/Models/CorporateBenefit.php @@ -0,0 +1,11 @@ +belongsTo(Corporate::class); } + + public function scopeFilter($query, array $filters) + { + $query->when($filters['search'] ?? false, function ($query, $search) { + return $query + ->where('code', 'like', "%" . $search . "%") + ->orWhere('name', 'like', "%" . $search . "%"); + }); + } } diff --git a/app/Models/CorporatePolicy.php b/app/Models/CorporatePolicy.php index 0d1e99d5..7af2a05d 100644 --- a/app/Models/CorporatePolicy.php +++ b/app/Models/CorporatePolicy.php @@ -4,6 +4,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class CorporatePolicy extends Model { @@ -28,4 +29,9 @@ class CorporatePolicy extends Model { return $this->belongsTo(Corporate::class); } + + public function setCodeAttribute($value) + { + $this->attributes['code'] = !empty($value) ? $value : Str::upper(Str::random('6')); + } } diff --git a/app/Models/MemberBenefit.php b/app/Models/MemberBenefit.php index b90f8593..bcab54ff 100644 --- a/app/Models/MemberBenefit.php +++ b/app/Models/MemberBenefit.php @@ -10,14 +10,17 @@ class MemberBenefit extends Model use HasFactory; protected $fillable = [ + 'corporate_id', 'service_code', 'plan_code', 'benefit_code', + 'code', 'description', 'budget', 'budget_conditions', 'budget_code', 'primary_benefit_code', + 'benefit_mode', 'room_class_coverage', 'max_bed_coverage', 'tolerance_parameter', @@ -25,6 +28,7 @@ class MemberBenefit extends Model 'limit_amount', 'area_limit', 'shared_benefit', + 'shared_benefit_type', 'msc', 'genders', 'min_age', @@ -33,6 +37,7 @@ class MemberBenefit extends Model 'daily_frequency', 'weekly_frequency', 'monthly_frequency', + 'yearly_frequency', 'custom_frequency_days', 'custom_duration_value', 'allowed_transaction_types', @@ -52,6 +57,7 @@ class MemberBenefit extends Model 'co_share_c_percentage', 'cashless_deductible', 'reimbursement_deductible', + 'digital_deductible', 'co_share_m_deductible', 'co_share_s_deductible', 'co_share_c_deductible', @@ -63,4 +69,96 @@ class MemberBenefit extends Model 'show_benefit_item', 'show_benefit_value', ]; + + public static $doc_headers_to_field_map = [ + "Service" => 'service_code', + "Plan" => 'plan_code', + "Benefit Code" => 'benefit_code', + "Customer Benefit Code" => 'code', + "Detail Benefit" => 'description', + "ASO/Budget" => 'budget', + "Budget Condition" => 'budget_conditions', + "Budget Code" => 'budget_code', + "Primary benefit" => 'primary_benefit_code', + "Benefit Mode" => 'benefit_mode', + "Room Class" => 'room_class_coverage', + "Max Bed" => 'max_bed_coverage', + "Tolerance Paramater" => 'tolerance_parameter', + "Max. Room Class" => 'max_room_class', + "Limit Value" => 'limit_amount', + "Area" => 'area_limit', + "Shared Benefit With" => 'shared_benefit', + "Shared Benefit Type" => 'shared_benefit_type', + "MSC" => 'msc', + "Gender" => 'genders', + "Min Age" => 'min_age', + "Max Age" => 'max_age', + "Freq. Period" => 'max_frequency_period', + "Daily Frequency" => 'daily_frequency', + "Weekly Frequency" => 'weekly_frequency', + "Monthly Frequency" => 'monthly_frequency', + "Yearly Frequency" => 'yearly_frequency', + "Custom Duration" => 'custom_frequency_days', + "Custom Duration Value" => 'custom_duration_value', + "Cashless, Reimbursement" => 'allowed_transaction_types', + "High Plan Factor" => 'high_plan_factor', + "Pre Post Treatment" => 'pre_post_treatment', + "Pre Treatment" => 'pre_treatment_days', + "Post Treatment" => 'post_treatment_days', + "Layer Type 1" => 'layer_type_1', + "Layer Value 1" => 'layer_value_1', + "Layer Type 2" => 'layer_type_2', + "Layer Value 2" => 'layer_value_2', + "Cashless (%)" => 'cashless_percentage', + "Reimburse (%)" => 'reimbursement_percentage', + "Digital (%)" => 'digital_percentage', + "CoShareM (%)" => 'co_share_m_percentage', + "CoShareS (%)" => 'co_share_s_percentage', + "CoShareC (%)" => 'co_share_c_percentage', + "Cashless Deductible" => 'cashless_deductible', + "Reimbursement Deductible" => 'reimbursement_deductible', + "Digital Deductible" => 'digital_deductible', + "DeductibleM" => 'co_share_m_deductible', + "DeductibleS" => 'co_share_s_deductible', + "DeductibleC" => 'co_share_c_deductible', + "Prorate Type" => 'prorate_type', + "Prorate Lookup" => 'prorate_lookup', + "Max Days for Disability" => 'max_days_for_disability', + "Max Periode of Disability" => 'max_period_for_disability', + "Currency" => 'currency', + "Show Benefit Item" => 'show_benefit_item', + "Show Benefit Value" => 'show_benefit_value', + ]; + + public function setPrePostTreatmentAttribute($value) + { + return empty($value) ? null : ($value == 'Y'); + } + + public function getPrePostTreatmentAttribute($value) + { + return empty($value) ? null : ($value ? 'Y' : 'N'); + } + + public function scopeFilter($query, array $filters) + { + $query->when($filters['search'] ?? false, function ($query, $search) { + return $query + ->where('service_code', 'like', "%" . $search . "%") + ->orWhere('code', 'like', "%" . $search . "%") + ->orWhereHas('plan', function ($query) use ($search) { + $query->where('code', 'like', "%" . $search . "%"); + }); + }); + } + + public function benefit() + { + return $this->belongsTo(Benefit::class, 'benefit_code', 'code'); + } + + public function plan() + { + return $this->belongsTo(Plan::class, 'plan_code', 'code'); + } } diff --git a/database/migrations/2022_06_23_070847_create_benefits_table.php b/database/migrations/2022_06_23_070847_create_benefits_table.php index c50ba0ef..6eb93c91 100644 --- a/database/migrations/2022_06_23_070847_create_benefits_table.php +++ b/database/migrations/2022_06_23_070847_create_benefits_table.php @@ -15,10 +15,65 @@ return new class extends Migration { Schema::create('benefits', function (Blueprint $table) { $table->id(); - $table->string('code')->unique(); - $table->string('name'); + $table->foreignId('corporate_id')->index()->nullable(); + $table->string('service_code')->index()->nullable(); + $table->string('plan_code')->index()->nullable(); + $table->string('benefit_code')->index()->nullable(); + $table->string('code')->index()->nullable(); $table->text('description')->nullable(); - + $table->string('budget')->nullable(); + $table->string('budget_conditions')->nullable(); + $table->string('budget_code')->nullable(); + $table->string('primary_benefit_code')->index()->nullable(); + $table->string('benefit_mode')->nullable(); + $table->string('room_class_coverage')->nullable(); + $table->string('max_bed_coverage')->nullable(); + $table->string('tolerance_parameter')->nullable(); + $table->string('max_room_class')->nullable(); + $table->decimal('limit_amount', 15, 2)->nullable(); + $table->boolean('area_limit')->default(false)->nullable(); + $table->string('shared_benefit')->nullable(); + $table->string('shared_benefit_type')->nullable(); + $table->string('msc')->nullable(); + $table->string('genders')->nullable(); + $table->string('min_age')->nullable(); + $table->string('max_age')->nullable(); + $table->string('max_frequency_period')->nullable(); + $table->string('daily_frequency')->nullable(); + $table->string('weekly_frequency')->nullable(); + $table->string('monthly_frequency')->nullable(); + $table->string('yearly_frequency')->nullable(); + $table->string('custom_frequency_days')->nullable(); + $table->string('custom_duration_value')->nullable(); + $table->string('allowed_transaction_types')->nullable(); + $table->string('high_plan_factor')->nullable(); + $table->boolean('pre_post_treatment')->nullable(); + $table->string('pre_treatment_days')->nullable(); + $table->string('post_treatment_days')->nullable(); + $table->string('layer_type_1')->nullable(); + $table->string('layer_value_1')->nullable(); + $table->string('layer_type_2')->nullable(); + $table->string('layer_value_2')->nullable(); + $table->tinyInteger('cashless_percentage')->default(100)->nullable(); + $table->tinyInteger('reimbursement_percentage')->default(100)->nullable(); + $table->tinyInteger('digital_percentage')->default(100)->nullable(); + $table->tinyInteger('co_share_m_percentage')->default(100)->nullable(); + $table->tinyInteger('co_share_s_percentage')->default(100)->nullable(); + $table->tinyInteger('co_share_c_percentage')->default(100)->nullable(); + $table->decimal('cashless_deductible', 15, 2)->nullable(); + $table->decimal('reimbursement_deductible', 15, 2)->nullable(); + $table->decimal('digital_deductible', 15, 2)->nullable(); + $table->decimal('co_share_m_deductible', 15, 2)->nullable(); + $table->decimal('co_share_s_deductible', 15, 2)->nullable(); + $table->decimal('co_share_c_deductible', 15, 2)->nullable(); + $table->string('prorate_type')->nullable(); + $table->string('prorate_lookup')->nullable(); + $table->string('max_days_for_disability')->nullable(); + $table->string('max_period_for_disability')->nullable(); + $table->string('currency')->nullable(); + $table->string('show_benefit_item')->nullable(); + $table->string('show_benefit_value')->nullable(); + $table->timestamps(); $table->softDeletes(); diff --git a/database/migrations/2022_06_23_094719_create_member_benefits_table.php b/database/migrations/2022_06_23_094719_create_member_benefits_table.php deleted file mode 100644 index 52094064..00000000 --- a/database/migrations/2022_06_23_094719_create_member_benefits_table.php +++ /dev/null @@ -1,89 +0,0 @@ -id(); - $table->string('service_code')->index()->nullable(); - $table->string('plan_code')->index()->nullable(); - $table->string('benefit_code')->index()->nullable(); - $table->text('description')->nullable(); - $table->string('budget')->nullable(); - $table->string('budget_conditions')->nullable(); - $table->string('budget_code')->nullable(); - $table->string('primary_benefit_code')->index()->nullable(); - $table->string('room_class_coverage')->nullable(); - $table->string('max_bed_coverage')->nullable(); - $table->string('tolerance_parameter')->nullable(); - $table->string('max_room_class')->nullable(); - $table->decimal('limit_amount', 15, 2)->nullable(); - $table->boolean('area_limit')->default(false)->nullable(); - $table->string('shared_benefit')->nullable(); - $table->string('msc')->nullable(); - $table->string('genders')->nullable(); - $table->string('min_age')->nullable(); - $table->string('max_age')->nullable(); - $table->string('max_frequency_period')->nullable(); - $table->string('daily_frequency')->nullable(); - $table->string('weekly_frequency')->nullable(); - $table->string('monthly_frequency')->nullable(); - $table->string('custom_frequency_days')->nullable(); - $table->string('custom_duration_value')->nullable(); - $table->string('allowed_transaction_types')->nullable(); - $table->string('high_plan_factor')->nullable(); - $table->boolean('pre_post_treatment')->nullable(); - $table->string('pre_treatment_days')->nullable(); - $table->string('post_treatment_days')->nullable(); - $table->string('layer_type_1')->nullable(); - $table->string('layer_value_1')->nullable(); - $table->string('layer_type_2')->nullable(); - $table->string('layer_value_2')->nullable(); - $table->tinyInteger('cashless_percentage')->default(100)->nullable(); - $table->tinyInteger('reimbursement_percentage')->default(100)->nullable(); - $table->tinyInteger('digital_percentage')->default(100)->nullable(); - $table->tinyInteger('co_share_m_percentage')->default(100)->nullable(); - $table->tinyInteger('co_share_s_percentage')->default(100)->nullable(); - $table->tinyInteger('co_share_c_percentage')->default(100)->nullable(); - $table->decimal('cashless_deductible', 15, 2)->nullable(); - $table->decimal('reimbursement_deductible', 15, 2)->nullable(); - $table->decimal('co_share_m_deductible', 15, 2)->nullable(); - $table->decimal('co_share_s_deductible', 15, 2)->nullable(); - $table->decimal('co_share_c_deductible', 15, 2)->nullable(); - $table->string('prorate_type')->nullable(); - $table->string('prorate_lookup')->nullable(); - $table->string('max_days_for_disability')->nullable(); - $table->string('max_period_for_disability')->nullable(); - $table->string('currency')->nullable(); - $table->string('show_benefit_item')->nullable(); - $table->string('show_benefit_value')->nullable(); - - $table->timestamps(); - $table->softDeletes(); - - $table->foreignId('created_by')->nullable()->index(); - $table->foreignId('updated_by')->nullable()->index(); - $table->foreignId('deleted_by')->nullable()->index(); - }); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - Schema::dropIfExists('member_benefits'); - } -}; diff --git a/database/migrations/2022_07_12_025440_create_corporate_benefits_table.php b/database/migrations/2022_07_12_025440_create_corporate_benefits_table.php new file mode 100644 index 00000000..8e732c69 --- /dev/null +++ b/database/migrations/2022_07_12_025440_create_corporate_benefits_table.php @@ -0,0 +1,43 @@ +id(); + $table->foreignId('corporate_id')->index(); + $table->string('code')->index(); + $table->string('name')->nullable(); + $table->text('description')->nullable(); + + $table->timestamps(); + $table->softDeletes(); + + $table->foreignId('created_by')->nullable()->index(); + $table->foreignId('updated_by')->nullable()->index(); + $table->foreignId('deleted_by')->nullable()->index(); + + $table->unique(['corporate_id', 'code']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('corporate_benefits'); + } +}; diff --git a/database/seeders/BenefitSeeder.php b/database/seeders/BenefitSeeder.php index c9d1fda1..a456ec7c 100644 --- a/database/seeders/BenefitSeeder.php +++ b/database/seeders/BenefitSeeder.php @@ -2,6 +2,8 @@ namespace Database\Seeders; +use App\Models\Benefit; +use App\Models\MemberBenefit; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; @@ -14,37 +16,14 @@ class BenefitSeeder extends Seeder */ public function run() { - $listOfBenefit = [ - [ - "service_code" => 'OP', - "code" => "GP", - "name" => "General Practitioner", - "description" => "Consultation With General Practitioner" - ], - [ - "service_code" => 'OP', - "code" => "GP", - "name" => "General Practitioner", - "description" => "Consultation With General Practitioner" - ], - [ - "service_code" => 'OP', - "code" => "GP", - "name" => "General Practitioner", - "description" => "Consultation With General Practitioner" - ], - [ - "service_code" => 'OP', - "code" => "GP", - "name" => "General Practitioner", - "description" => "Consultation With General Practitioner" - ], - [ - "service_code" => 'OP', - "code" => "GP", - "name" => "General Practitioner", - "description" => "Consultation With General Practitioner" - ], - ]; + $member_benefits = MemberBenefit::pluck('benefit_code')->unique(); + + foreach ($member_benefits as $benefit_code) { + Benefit::create([ + 'code' => $benefit_code, + 'name' => "Benefit ". $benefit_code, + 'corporate_id' => 3, + ]); + } } } diff --git a/frontend/dashboard/src/@types/corporates.ts b/frontend/dashboard/src/@types/corporates.ts index 7016778c..827121ea 100644 --- a/frontend/dashboard/src/@types/corporates.ts +++ b/frontend/dashboard/src/@types/corporates.ts @@ -41,16 +41,16 @@ export type Policy = { end: string | Date; } -export type CorporatePlan = { +export type Plan = { id: number; corporate_id: number; code: string; name: string; } -export type Plan = { +export type PlanConfig = { id: number; - corporate_plan: CorporatePlan | null; + corporate_plan: Plan | null; service_code: string; corporate_plan_id: string; code: string; @@ -100,3 +100,63 @@ export type Plan = { max_surgery_reinstatement_days: string; max_surgery_periode_days: string; } + +export type MemberBenefit = { + service_code : string; + plan_code : string; + benefit_code : string; + code : string; + description : string; + budget : string; + budget_conditions : string; + budget_code : string; + primary_benefit_code : string; + benefit_mode : string; + room_class_coverage : string; + max_bed_coverage : string; + tolerance_parameter : string; + max_room_class : string; + limit_amount : string; + area_limit : string; + shared_benefit : string; + shared_benefit_type : string; + msc : string; + genders : string; + min_age : string; + max_age : string; + max_frequency_period : string; + daily_frequency : string; + weekly_frequency : string; + monthly_frequency : string; + yearly_frequency : string; + custom_frequency_days : string; + custom_duration_value : string; + allowed_transaction_types : string; + high_plan_factor : string; + pre_post_treatment : string; + pre_treatment_days : string; + post_treatment_days : string; + layer_type_1 : string; + layer_value_1 : string; + layer_type_2 : string; + layer_value_2 : string; + cashless_percentage : string; + reimbursement_percentage : string; + digital_percentage : string; + co_share_m_percentage : string; + co_share_s_percentage : string; + co_share_c_percentage : string; + cashless_deductible : string; + reimbursement_deductible : string; + digital_deductible : string; + co_share_m_deductible : string; + co_share_s_deductible : string; + co_share_c_deductible : string; + prorate_type : string; + prorate_lookup : string; + max_days_for_disability : string; + max_period_for_disability : string; + currency : string; + show_benefit_item : string; + show_benefit_value : string; +} diff --git a/frontend/dashboard/src/pages/Corporates/Benefit/Index.tsx b/frontend/dashboard/src/pages/Corporates/Benefit/Index.tsx index 0ab7f815..de7aca6a 100644 --- a/frontend/dashboard/src/pages/Corporates/Benefit/Index.tsx +++ b/frontend/dashboard/src/pages/Corporates/Benefit/Index.tsx @@ -13,14 +13,13 @@ export default function Divisions() { const { id } = useParams(); - const pageTitle = 'Benefit List'; + const pageTitle = 'Benefit'; return ( { - console.log('Search Input: useEffect') + // console.log('Search Input: useEffect') setSearchText(searchParams.get('search') ?? ''); }, [searchParams]) @@ -88,7 +88,7 @@ export default function PlanList() { if (importPlan.current?.files.length) { const formData = new FormData(); formData.append("file", importPlan.current?.files[0]) - axios.post(`corporates/${id}/plans/import`, formData ) + axios.post(`corporates/${id}/benefits/import`, formData ) .then(response => { handleCancelImportButton(); loadDataTableData(); @@ -155,9 +155,9 @@ export default function PlanList() { } // Called on every row to map the data to the columns - function createData( plan: Plan ): Plan { + function createData( memberBenefit: MemberBenefit ): MemberBenefit { return { - ...plan, + ...memberBenefit, } } @@ -179,29 +179,43 @@ export default function PlanList() { {row.service_code} - {row.corporate_plan?.code} + {row.plan_code} + {row.benefit_code} {row.code} - {row.type} - {row.start} - {row.end} - {row.require_referral} - {row.referral_source} - {row.referral_duration} - {row.family_plan} - {row.family_plan_share_rules} - {row.limit_rules} - {row.layer} - {row.layer_conditions} - {row.budget_type} - {row.budget_code} + {row.description} + {row.budget} {row.budget_conditions} - {row.surgery_limit} - {row.non_surgery_limit} - {row.max_claim_limit} - {row.max_claim_count} + {row.budget_code} + {row.primary_benefit_code} + {row.benefit_mode} + {row.room_class_coverage} + {row.max_bed_coverage} + {row.tolerance_parameter} + {row.max_room_class} + {row.limit_amount} {row.area_limit} - {row.limit_shared_plans} - {row.limit_shared_plan_type} + {row.shared_benefit} + {row.shared_benefit_type} + {row.msc} + {row.genders} + {row.min_age} + {row.max_age} + {row.max_frequency_period} + {row.daily_frequency} + {row.weekly_frequency} + {row.monthly_frequency} + {row.yearly_frequency} + {row.custom_frequency_days} + {row.custom_duration_value} + {row.allowed_transaction_types} + {row.high_plan_factor} + {row.pre_post_treatment} + {row.pre_treatment_days} + {row.post_treatment_days} + {row.layer_type_1} + {row.layer_value_1} + {row.layer_type_2} + {row.layer_value_2} {row.cashless_percentage} {row.reimbursement_percentage} {row.digital_percentage} @@ -214,18 +228,14 @@ export default function PlanList() { {row.co_share_m_deductible} {row.co_share_s_deductible} {row.co_share_c_deductible} - {row.co_share_deductible_condition} - {row.msc} - {row.genders} - {row.min_age} - {row.max_age} - {row.rule_of_excess} - {row.max_excess_covered} {row.prorate_type} {row.prorate_lookup} + {row.max_days_for_disability} + {row.max_period_for_disability} {row.currency} - {row.max_surgery_reinstatement_days} - {row.max_surgery_periode_days} + {row.show_benefit_item} + {row.show_benefit_value} + @@ -296,7 +306,7 @@ export default function PlanList() { const loadDataTableData = async (appliedFilter = null) => { setDataTableLoading(true); const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]); - const response = await axios.get('/corporates/'+id+'/plans', { params: filter }); + const response = await axios.get('/corporates/'+id+'/benefits', { params: filter }); // console.log(response.data); setDataTableLoading(false); @@ -329,52 +339,61 @@ export default function PlanList() { Service Plan - Code - Type - Start - End - Referral - Referral Source - Referral Duration - Family Plan - Family Sharing Overflow - Plan Limit - Layer ID - Layer Condition - Budget Type - Budget Code + Benefit Code + Customer Benefit Code + Detail Benefit + ASO/Budget Budget Condition - Surgery - Non Surgery - Max/Claim - Max Count of Claim + Budget Code + Primary benefit + Benefit Mode + Room Class + Max Bed + Tolerance Paramater + Max. Room Class + Limit Value Area - Shared Plan - Limit Shared Type - Cashless(%) - Reimbursement(%) - Digital(%) - CoShare M(%) - CoShare S(%) - CoShare C(%) + Shared Benefit With + Shared Benefit Type + MSC + Gender + Min Age + Max Age + Freq. Period + Daily Frequency + Weekly Frequency + Monthly Frequency + Yearly Frequency + Custom Duration + Custom Duration Value + Cashless, Reimbursement + High Plan Factor + Pre Post Treatment + Pre Treatment + Post Treatment + Layer Type 1 + Layer Value 1 + Layer Type 2 + Layer Value 2 + Cashless (%) + Reimburse (%) + Digital (%) + CoShareM (%) + CoShareS (%) + CoShareC (%) Cashless Deductible Reimbursement Deductible Digital Deductible DeductibleM DeductibleS DeductibleC - CoShare & Deductible Condition - MSC - Gender - Min Age - Max Age - Rule of Excess - Max Excess Covered Prorate Type Prorate Lookup + Max Days for Disability + Max Periode of Disability Currency - Reinstatement Surgery - Period of Surgery + Show Benefit Item + Show Benefit Value Status Action diff --git a/frontend/dashboard/src/pages/Corporates/CorporateBenefit/Create.tsx b/frontend/dashboard/src/pages/Corporates/CorporateBenefit/Create.tsx new file mode 100644 index 00000000..093e9aba --- /dev/null +++ b/frontend/dashboard/src/pages/Corporates/CorporateBenefit/Create.tsx @@ -0,0 +1,241 @@ +import * as Yup from 'yup'; +import { yupResolver } from "@hookform/resolvers/yup"; +import { Card, Collapse, Divider, Grid, Stack, Typography } from "@mui/material"; +import { useForm } from "react-hook-form"; +import { useParams } from "react-router-dom"; +import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs"; +import { FormProvider, RHFCheckbox, RHFSelect, RHFTextField } from "../../../components/hook-form"; +import Page from "../../../components/Page"; +import useSettings from "../../../hooks/useSettings"; +import CorporateTabNavigations from "../CorporateTabNavigations"; +import DivisionsList from "./List"; +import { useMemo, useState } from 'react'; + + + +export default function Divisions() { + const { themeStretch } = useSettings(); + + const { id } = useParams(); + + const NewDivisionSchema = Yup.object().shape({ + name: Yup.string().required('Name is required'), + code: Yup.string().required('Corporate Code is required'), + active: Yup.boolean().required('Corporate Status is required'), + }); + + const defaultValues = useMemo( + () => ({ + code: '', + }), + [] + ); + + const methods = useForm({ + resolver: yupResolver(NewDivisionSchema), + defaultValues, + }); + + const { + reset, + watch, + control, + setValue, + getValues, + setError, + handleSubmit, + formState: { isSubmitting }, + } = methods; + + const onSubmit = async (data: any) => { + console.log(data); + }; + + const [open, setOpen] = useState(false); + + const benefits = [ + { + 'category' : 'General Practitioner', + 'childs' : [ + { + 'name' : 'External Doctor Online', + 'code' : 'gp-external-doctor-online' + }, + { + 'name' : 'External Doctor Offline', + 'code' : 'gp-external-doctor-offline' + }, + { + 'name' : 'Internal Doctor Online', + 'code' : 'gp-internal-doctor-online' + }, + { + 'name' : 'Internal Doctor Offline', + 'code' : 'gp-internal-doctor-offline' + }, + ] + }, + { + 'category' : 'Specialist', + 'childs' : [ + { + 'name' : 'External Doctor Online', + 'code' : 'sp-external-doctor-online' + }, + { + 'name' : 'External Doctor Offline', + 'code' : 'sp-external-doctor-offline' + }, + { + 'name' : 'Internal Doctor Online', + 'code' : 'sp-internal-doctor-online' + }, + { + 'name' : 'Internal Doctor Offline', + 'code' : 'sp-internal-doctor-offline' + }, + ] + }, + { + 'category' : 'Medicines', + 'childs' : [ + { + 'name' : 'Vitamins', + 'code' : 'medicines-vitamins' + }, + { + 'name' : 'Delivery Fee', + 'code' : 'medicines-delivery-fee' + }, + ] + }, + ]; + + const products = [ + { + 'name' : 'Inpatient', + 'code' : 'IP', + }, + { + 'name' : 'Outpatient', + 'code' : 'OP', + }, + { + 'name' : 'Dental', + 'code' : 'DT', + }, + { + 'name' : 'Dental', + 'code' : 'DTL', + }, + { + 'name' : 'Matternity', + 'code' : 'MT', + }, + { + 'name' : 'Special Benefit', + 'code' : 'SB', + }, + ]; + + return ( + + + + + + + + + + + + Benefit Detail + + + + + + Benefit Configuration + + + }> + + + {benefits.map(row => ( + + {row.category} + + {row.childs.map(benefit => ( + + + + ))} + + + ))} + Admin Fee + + {benefits.map(row => ( + + + + ))} + + + + + + + {benefits.map(row => ( + + {row.category} + + {row.childs.map(benefit => ( + + + + ))} + + + ))} + Admin Fee + + {benefits.map(row => ( + + + + ))} + + + + + + + + + + + ); +} diff --git a/frontend/dashboard/src/pages/Corporates/CorporateBenefit/Index.tsx b/frontend/dashboard/src/pages/Corporates/CorporateBenefit/Index.tsx new file mode 100644 index 00000000..57245523 --- /dev/null +++ b/frontend/dashboard/src/pages/Corporates/CorporateBenefit/Index.tsx @@ -0,0 +1,54 @@ +import { Card, Grid } from "@mui/material"; +import { useParams } from "react-router-dom"; +import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs"; +import Page from "../../../components/Page"; +import useSettings from "../../../hooks/useSettings"; +import CorporateTabNavigations from "../CorporateTabNavigations"; +import DivisionsList from "./List"; + + + +export default function Divisions() { + const { themeStretch } = useSettings(); + + const { id } = useParams(); + + const pageTitle = 'Corporate Benefit'; + return ( + + + + + + + + + + + + + + Corporate Detail Goes Here +   + + + + + ); +} diff --git a/frontend/dashboard/src/pages/Corporates/CorporateBenefit/List.tsx b/frontend/dashboard/src/pages/Corporates/CorporateBenefit/List.tsx new file mode 100644 index 00000000..4b49d9ac --- /dev/null +++ b/frontend/dashboard/src/pages/Corporates/CorporateBenefit/List.tsx @@ -0,0 +1,220 @@ +// @mui +import { Box, Button, Card, Collapse, IconButton, InputLabel, MenuItem, OutlinedInput, Paper, Select, SelectChangeEvent, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, Typography, Badge, Tab, Tabs, CardHeader, Stack, Menu, ButtonGroup } from '@mui/material'; +import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; +import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'; +import AddIcon from '@mui/icons-material/Add'; +import UploadIcon from '@mui/icons-material/Upload'; +import CancelIcon from '@mui/icons-material/Cancel'; +// hooks +import React, { Component, useEffect, useRef, useState } from 'react'; +import useSettings from '../../../hooks/useSettings'; +import { useParams, useSearchParams } from 'react-router-dom'; +// components +import axios from '../../../utils/axios'; +import { MemberBenefit } from '../../../@types/corporates'; +import { LaravelPaginatedData } from '../../../@types/paginated-data'; + +export default function PlanList() { + const { themeStretch } = useSettings(); + const { id } = useParams(); + const [searchParams, setSearchParams] = useSearchParams(); + + function SearchInput(props: any) { + // SEARCH + const searchInput = useRef(null); + const [searchText, setSearchText] = useState(""); + + const handleSearchChange = (event: any) => { + const newSearchText = event.target.value ?? '' + setSearchText(newSearchText); + } + + const handleSubmit = (event: any) => { + event.preventDefault(); + props.onSearch(searchText); // Trigger to Parent + } + + useEffect(() => { + // console.log('Search Input: useEffect') + setSearchText(searchParams.get('search') ?? ''); + }, [searchParams]) + + return ( +
+ + + ); + } + + // Called on every row to map the data to the columns + function createData( benefit: Benefit ): Benefit { + return { + ...benefit, + } + } + + // Generate the every row of the table + function Row(props: { row: ReturnType }) { + const { row } = props; + const [open, setOpen] = React.useState(false); + + return ( + + *': { borderBottom: 'unset' } }}> + + setOpen(!open)} + > + {open ? : } + + + {row.code} + {row.name} + + + + + {/* COLLAPSIBLE ROW */} + + + + + + No Extra Data + + + {false && + + Rules + + + + + Date + Customer + Amount + Total price ($) + + + + {/* {row.history ? row.history.map((historyRow) => ( */} + + {row.start} - {row.end} + {row.start} + {row.start} + {row.start} + + {/* )) + : ( + + No Data + + ) + } */} + +
+
} +
+
+
+
+ ); + } + + // Dummy Default Data + const [dataTableIsLoading, setDataTableLoading] = React.useState(true); + const [dataTableData, setDataTableData] = React.useState({ + current_page: 1, + data: [], + path: "", + first_page_url: "", + last_page: 1, + last_page_url: "", + next_page_url: "", + prev_page_url: "", + per_page: 10, + from: 0, + to: 0, + total: 0 + }); + + const loadDataTableData = async (appliedFilter = null) => { + setDataTableLoading(true); + const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]); + const response = await axios.get('/corporates/'+id+'/corporate-benefits', { params: filter }); + // console.log(response.data); + setDataTableLoading(false); + + setDataTableData(response.data); + } + + const headStyle = { + fontWeight: 'bold', + }; + + const applyFilter = async (searchFilter) => { + await loadDataTableData({ "search" : searchFilter }); + setSearchParams({ "search" : searchFilter }); + } + + useEffect(() => { + loadDataTableData(); + }, []) + + return ( + + + + + + + + {/* The Main Table */} + + + + + + Code + Name + Status + Action + + + {dataTableIsLoading ? + ( + + + Loading + + + ) : ( + dataTableData.data.length == 0 ? + ( + + + No Data + + + ) : ( + + {dataTableData.data.map(row => ( + + ))} + + ) + )} +
+
+
+
+ ); +} diff --git a/frontend/dashboard/src/pages/Corporates/CorporatePlan/Create.tsx b/frontend/dashboard/src/pages/Corporates/CorporatePlan/Create.tsx new file mode 100644 index 00000000..d1d40617 --- /dev/null +++ b/frontend/dashboard/src/pages/Corporates/CorporatePlan/Create.tsx @@ -0,0 +1,247 @@ +import * as Yup from 'yup'; +import { yupResolver } from "@hookform/resolvers/yup"; +import { Card, Collapse, Divider, Grid, Stack, Typography } from "@mui/material"; +import { useForm } from "react-hook-form"; +import { useParams } from "react-router-dom"; +import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs"; +import { FormProvider, RHFCheckbox, RHFSelect, RHFTextField } from "../../../components/hook-form"; +import Page from "../../../components/Page"; +import useSettings from "../../../hooks/useSettings"; +import CorporateTabNavigations from "../CorporateTabNavigations"; +import DivisionsList from "./List"; +import { useMemo, useState } from 'react'; + + + +export default function PlanCreate() { + const { themeStretch } = useSettings(); + + const { id } = useParams(); + + const NewDivisionSchema = Yup.object().shape({ + name: Yup.string().required('Name is required'), + code: Yup.string().required('Corporate Code is required'), + active: Yup.boolean().required('Corporate Status is required'), + }); + + const defaultValues = useMemo( + () => ({ + code: '', + }), + [] + ); + + const methods = useForm({ + resolver: yupResolver(NewDivisionSchema), + defaultValues, + }); + + const { + reset, + watch, + control, + setValue, + getValues, + setError, + handleSubmit, + formState: { isSubmitting }, + } = methods; + + const onSubmit = async (data: any) => { + console.log(data); + }; + + const [open, setOpen] = useState(false); + + const benefits = [ + { + 'category' : 'General Practitioner', + 'childs' : [ + { + 'name' : 'External Doctor Online', + 'code' : 'gp-external-doctor-online' + }, + { + 'name' : 'External Doctor Offline', + 'code' : 'gp-external-doctor-offline' + }, + { + 'name' : 'Internal Doctor Online', + 'code' : 'gp-internal-doctor-online' + }, + { + 'name' : 'Internal Doctor Offline', + 'code' : 'gp-internal-doctor-offline' + }, + ] + }, + { + 'category' : 'Specialist', + 'childs' : [ + { + 'name' : 'External Doctor Online', + 'code' : 'sp-external-doctor-online' + }, + { + 'name' : 'External Doctor Offline', + 'code' : 'sp-external-doctor-offline' + }, + { + 'name' : 'Internal Doctor Online', + 'code' : 'sp-internal-doctor-online' + }, + { + 'name' : 'Internal Doctor Offline', + 'code' : 'sp-internal-doctor-offline' + }, + ] + }, + { + 'category' : 'Medicines', + 'childs' : [ + { + 'name' : 'Vitamins', + 'code' : 'medicines-vitamins' + }, + { + 'name' : 'Delivery Fee', + 'code' : 'medicines-delivery-fee' + }, + ] + }, + ]; + + const products = [ + { + 'name' : 'Inpatient', + 'code' : 'IP', + }, + { + 'name' : 'Outpatient', + 'code' : 'OP', + }, + { + 'name' : 'Dental', + 'code' : 'DT', + }, + { + 'name' : 'Dental', + 'code' : 'DTL', + }, + { + 'name' : 'Matternity', + 'code' : 'MT', + }, + { + 'name' : 'Special Benefit', + 'code' : 'SB', + }, + ]; + + return ( + + + + + + + + + + + + Plan Detail + + + + + + + + + + + + Benefit Configuration + + + }> + + + {benefits.map(row => ( + + {row.category} + + {row.childs.map(benefit => ( + + + + ))} + + + ))} + Admin Fee + + {benefits.map(row => ( + + + + ))} + + + + + + + {benefits.map(row => ( + + {row.category} + + {row.childs.map(benefit => ( + + + + ))} + + + ))} + Admin Fee + + {benefits.map(row => ( + + + + ))} + + + + + + + + + + + ); +} diff --git a/frontend/dashboard/src/pages/Corporates/CorporatePlan/Index.tsx b/frontend/dashboard/src/pages/Corporates/CorporatePlan/Index.tsx new file mode 100644 index 00000000..7c3c8907 --- /dev/null +++ b/frontend/dashboard/src/pages/Corporates/CorporatePlan/Index.tsx @@ -0,0 +1,53 @@ +import { Card, Grid } from "@mui/material"; +import { useParams } from "react-router-dom"; +import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs"; +import Page from "../../../components/Page"; +import useSettings from "../../../hooks/useSettings"; +import CorporateTabNavigations from "../CorporateTabNavigations"; +import DivisionsList from "./List"; + + + +export default function Divisions() { + const { themeStretch } = useSettings(); + + const { id } = useParams(); + + return ( + + + + + + + + + + + + + + Corporate Detail Goes Here +   + + + + + ); +} diff --git a/frontend/dashboard/src/pages/Corporates/CorporatePlan/List.tsx b/frontend/dashboard/src/pages/Corporates/CorporatePlan/List.tsx new file mode 100644 index 00000000..1dbf6db6 --- /dev/null +++ b/frontend/dashboard/src/pages/Corporates/CorporatePlan/List.tsx @@ -0,0 +1,221 @@ +// @mui +import { Box, Button, Card, Collapse, IconButton, InputLabel, MenuItem, OutlinedInput, Paper, Select, SelectChangeEvent, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, Typography, Badge, Tab, Tabs, CardHeader, Stack, Menu, ButtonGroup } from '@mui/material'; +import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; +import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'; +import AddIcon from '@mui/icons-material/Add'; +import UploadIcon from '@mui/icons-material/Upload'; +import CancelIcon from '@mui/icons-material/Cancel'; +// hooks +import React, { Component, useEffect, useRef, useState } from 'react'; +import useSettings from '../../../hooks/useSettings'; +import { useParams, useSearchParams } from 'react-router-dom'; +// components +import axios from '../../../utils/axios'; +import { Plan } from '../../../@types/corporates'; +import { LaravelPaginatedData } from '../../../@types/paginated-data'; + +export default function PlanList() { + const { themeStretch } = useSettings(); + const { id } = useParams(); + const [searchParams, setSearchParams] = useSearchParams(); + + function SearchInput(props: any) { + // SEARCH + const searchInput = useRef(null); + const [searchText, setSearchText] = useState(""); + + const handleSearchChange = (event: any) => { + const newSearchText = event.target.value ?? '' + setSearchText(newSearchText); + } + + const handleSubmit = (event: any) => { + event.preventDefault(); + props.onSearch(searchText); // Trigger to Parent + } + + useEffect(() => { + // console.log('Search Input: useEffect') + setSearchText(searchParams.get('search') ?? ''); + }, [searchParams]) + + return ( +
+ + + ); + } + + // Called on every row to map the data to the columns + function createData( plan: Plan ): Plan { + return { + ...plan, + } + } + + // Generate the every row of the table + function Row(props: { row: ReturnType }) { + const { row } = props; + const [open, setOpen] = React.useState(false); + + return ( + + *': { borderBottom: 'unset' } }}> + + setOpen(!open)} + > + {open ? : } + + + {row.id} + {row.code} + {row.name} + {row.description} + + + + {/* COLLAPSIBLE ROW */} + + + + + + No Extra Data + + + {false && + + Rules + + + + + Date + Customer + Amount + Total price ($) + + + + {/* {row.history ? row.history.map((historyRow) => ( */} + + {row.start} - {row.end} + {row.start} + {row.start} + {row.start} + + {/* )) + : ( + + No Data + + ) + } */} + +
+
} +
+
+
+
+ ); + } + + // Dummy Default Data + const [dataTableIsLoading, setDataTableLoading] = React.useState(true); + const [dataTableData, setDataTableData] = React.useState({ + current_page: 1, + data: [], + path: "", + first_page_url: "", + last_page: 1, + last_page_url: "", + next_page_url: "", + prev_page_url: "", + per_page: 10, + from: 0, + to: 0, + total: 0 + }); + + const loadDataTableData = async (appliedFilter = null) => { + setDataTableLoading(true); + const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]); + const response = await axios.get('/corporates/'+id+'/corporate-plans', { params: filter }); + // console.log(response.data); + setDataTableLoading(false); + + setDataTableData(response.data); + } + + const headStyle = { + fontWeight: 'bold', + }; + + const applyFilter = async (searchFilter) => { + await loadDataTableData({ "search" : searchFilter }); + setSearchParams({ "search" : searchFilter }); + } + + useEffect(() => { + loadDataTableData(); + }, []) + + return ( + + + + + + + + {/* The Main Table */} + + + + + + ID + Code + Name + Description + + + {dataTableIsLoading ? + ( + + + Loading + + + ) : ( + dataTableData.data.length == 0 ? + ( + + + No Data + + + ) : ( + + {dataTableData.data.map(row => ( + + ))} + + ) + )} +
+
+
+
+ ); +} diff --git a/frontend/dashboard/src/pages/Corporates/CorporateTabNavigations.tsx b/frontend/dashboard/src/pages/Corporates/CorporateTabNavigations.tsx index f15c6531..104560c1 100644 --- a/frontend/dashboard/src/pages/Corporates/CorporateTabNavigations.tsx +++ b/frontend/dashboard/src/pages/Corporates/CorporateTabNavigations.tsx @@ -16,24 +16,32 @@ export default function CorporateTabNavigations({ position }: Props) { const mainTabItems = [ { - 'path' : 'members', - 'label': 'Member List', + 'path' : '', + 'label': 'Dashboard', }, { - 'path' : 'claim-history', - 'label': 'Claim History', - }, - { - 'path' : 'divisions', - 'label': 'Divisions', + 'path' : 'corporate-plans', + 'label': 'Corporate Plan', }, { 'path' : 'plans', 'label': 'Plans', }, + { + 'path' : 'corporate-benefits', + 'label': 'Corporate Benefit', + }, { 'path' : 'benefits', - 'label': 'Benefit & Exclusion', + 'label': 'Benefit', + }, + { + 'path' : 'divisions', + 'label': 'Divisions', + }, + { + 'path' : 'members', + 'label': 'Member List', }, { 'path' : 'hospitals', @@ -43,6 +51,10 @@ export default function CorporateTabNavigations({ position }: Props) { 'path' : 'formularium', 'label': 'Formularium', }, + { + 'path' : 'claim-history', + 'label': 'Claim History', + }, ]; useEffect(() => { let currentIndex = mainTabItems.findIndex(item => item.path === position); diff --git a/frontend/dashboard/src/pages/Corporates/Form.tsx b/frontend/dashboard/src/pages/Corporates/Form.tsx index 099e8e61..f3899a50 100644 --- a/frontend/dashboard/src/pages/Corporates/Form.tsx +++ b/frontend/dashboard/src/pages/Corporates/Form.tsx @@ -224,7 +224,7 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) { - + Minimal Deposit Policy Level diff --git a/frontend/dashboard/src/pages/Corporates/Plan/Index.tsx b/frontend/dashboard/src/pages/Corporates/Plan/Index.tsx index 1788d632..e3ef1774 100644 --- a/frontend/dashboard/src/pages/Corporates/Plan/Index.tsx +++ b/frontend/dashboard/src/pages/Corporates/Plan/Index.tsx @@ -19,7 +19,6 @@ export default function Divisions() { diff --git a/frontend/dashboard/src/pages/Corporates/Plan/List.tsx b/frontend/dashboard/src/pages/Corporates/Plan/List.tsx index 0622f281..44871c93 100644 --- a/frontend/dashboard/src/pages/Corporates/Plan/List.tsx +++ b/frontend/dashboard/src/pages/Corporates/Plan/List.tsx @@ -14,7 +14,7 @@ import axios from '../../../utils/axios'; import { Plan } from '../../../@types/corporates'; import { LaravelPaginatedData } from '../../../@types/paginated-data'; -export default function PlanList() { +export default function CorporatePlanList() { const { themeStretch } = useSettings(); const { id } = useParams(); const [searchParams, setSearchParams] = useSearchParams(); @@ -35,7 +35,7 @@ export default function PlanList() { } useEffect(() => { - console.log('Search Input: useEffect') + // console.log('Search Input: useEffect') setSearchText(searchParams.get('search') ?? ''); }, [searchParams]) diff --git a/frontend/dashboard/src/pages/Corporates/Show.tsx b/frontend/dashboard/src/pages/Corporates/Show.tsx index acbc31a9..0cad8ab5 100644 --- a/frontend/dashboard/src/pages/Corporates/Show.tsx +++ b/frontend/dashboard/src/pages/Corporates/Show.tsx @@ -194,12 +194,11 @@ export default function Corporates() { const { id } = useParams(); return ( - + */} - + diff --git a/frontend/dashboard/src/routes/index.tsx b/frontend/dashboard/src/routes/index.tsx index ed0eeff4..09559e82 100644 --- a/frontend/dashboard/src/routes/index.tsx +++ b/frontend/dashboard/src/routes/index.tsx @@ -109,18 +109,26 @@ export default function Router() { }, { path: 'corporates/:id/plans/create', - element: , + element: , }, { path: 'corporates/:id/plans', + element: , + }, + { + path: 'corporates/:id/corporate-plans', element: , }, { path: 'corporates/:id/benefits/create', - element: , + element: , }, { path: 'corporates/:id/benefits', + element: , + }, + { + path: 'corporates/:id/corporate-benefits', element: , }, ] @@ -171,10 +179,20 @@ const MedicinesCreate = Loadable(lazy(() => import('../pages/Medicines/Create')) const Corporate = Loadable(lazy(() => import('../pages/Corporates/Index'))); const CorporateCreate = Loadable(lazy(() => import('../pages/Corporates/Create'))); const CorporateShow = Loadable(lazy(() => import('../pages/Corporates/Show'))); + const CorporateDivisions = Loadable(lazy(() => import('../pages/Corporates/Division/Index'))); const CorporateDivisionsCreate = Loadable(lazy(() => import('../pages/Corporates/Division/Create'))); + const CorporateMembers = Loadable(lazy(() => import('../pages/Corporates/Member/Index'))); -const CorporateBenefitsCreate = Loadable(lazy(() => import('../pages/Corporates/Benefit/Create'))); -const CorporateBenefits = Loadable(lazy(() => import('../pages/Corporates/Benefit/Index'))); -const CorporatePlansCreate = Loadable(lazy(() => import('../pages/Corporates/Plan/Create'))); -const CorporatePlans = Loadable(lazy(() => import('../pages/Corporates/Plan/Index'))); + +const BenefitCreate = Loadable(lazy(() => import('../pages/Corporates/Benefit/Create'))); +const Benefits = Loadable(lazy(() => import('../pages/Corporates/Benefit/Index'))); + +const CorporateBenefitsCreate = Loadable(lazy(() => import('../pages/Corporates/CorporateBenefit/Create'))); +const CorporateBenefits = Loadable(lazy(() => import('../pages/Corporates/CorporateBenefit/Index'))); + +// const PlanCreate = Loadable(lazy(() => import('../pages/Corporates/CorporatePlan/Create'))); +const CorporatePlans = Loadable(lazy(() => import('../pages/Corporates/CorporatePlan/Index'))); + +const PlanCreate = Loadable(lazy(() => import('../pages/Corporates/Plan/Create'))); +const Plans = Loadable(lazy(() => import('../pages/Corporates/Plan/Index')));