Add Corporate Specialities
This commit is contained in:
@@ -19,8 +19,17 @@ class CorporateFormulariumController extends Controller
|
|||||||
public function index(Request $request, $corporate_id)
|
public function index(Request $request, $corporate_id)
|
||||||
{
|
{
|
||||||
$formulariums = Formularium::query()
|
$formulariums = Formularium::query()
|
||||||
->filter($request->all())
|
->filter($request->all());
|
||||||
->with(['corporateFormulariums' => function ($query) use ($corporate_id) {
|
if (!empty($request->status) && $request->status == 'inactive') {
|
||||||
|
$formulariums = $formulariums->whereDoesntHave('corporateFormulariums');
|
||||||
|
} else if (!empty($request->status) && $request->status == 'all') {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$formulariums->whereHas('corporateFormulariums', function ($corporateFormularium) use ($corporate_id){
|
||||||
|
$corporateFormularium->where('corporate_id', $corporate_id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$formulariums = $formulariums->with(['corporateFormulariums' => function ($query) use ($corporate_id) {
|
||||||
$query->where('corporate_id', $corporate_id);
|
$query->where('corporate_id', $corporate_id);
|
||||||
}])
|
}])
|
||||||
->withCount('items')
|
->withCount('items')
|
||||||
|
|||||||
@@ -3,8 +3,11 @@
|
|||||||
namespace Modules\Internal\Http\Controllers\Api;
|
namespace Modules\Internal\Http\Controllers\Api;
|
||||||
|
|
||||||
use App\Helpers\Helper;
|
use App\Helpers\Helper;
|
||||||
|
use App\Models\Corporate;
|
||||||
use App\Models\CorporateService;
|
use App\Models\CorporateService;
|
||||||
use App\Models\CorporateServiceConfig;
|
use App\Models\CorporateServiceConfig;
|
||||||
|
use App\Models\CorporateServiceSpeciality;
|
||||||
|
use App\Models\Speciality;
|
||||||
use Illuminate\Contracts\Support\Renderable;
|
use Illuminate\Contracts\Support\Renderable;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Routing\Controller;
|
use Illuminate\Routing\Controller;
|
||||||
@@ -18,7 +21,7 @@ class CorporateServiceController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index(Request $request, $corporate_id)
|
public function index(Request $request, $corporate_id)
|
||||||
{
|
{
|
||||||
$services = CorporateService::with('configs', 'service')->where('corporate_id', $corporate_id)->paginate();
|
$services = CorporateService::with('configs', 'service')->where('corporate_id', $corporate_id)->filter($request->toArray())->paginate();
|
||||||
|
|
||||||
return Helper::paginateResources(CorporateServiceConfigResource::collection($services));
|
return Helper::paginateResources(CorporateServiceConfigResource::collection($services));
|
||||||
}
|
}
|
||||||
@@ -91,4 +94,69 @@ class CorporateServiceController extends Controller
|
|||||||
{
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function corporateServiceIndex($corporate_id, $service_code)
|
||||||
|
{
|
||||||
|
$corporate = Corporate::findOrFail($corporate_id);
|
||||||
|
$corporateService = CorporateService::query()
|
||||||
|
->where('corporate_id', $corporate_id)
|
||||||
|
->where('service_code', $service_code)
|
||||||
|
->with(['configs', 'service',
|
||||||
|
'specialities' => function($speciality) {
|
||||||
|
$speciality->where('status', 'active');
|
||||||
|
},
|
||||||
|
'specialities.speciality'])
|
||||||
|
->first();
|
||||||
|
// $service = CorporateServiceConfigResource::make($corporateService);
|
||||||
|
$specialities = Speciality::get();
|
||||||
|
|
||||||
|
return response()->json(
|
||||||
|
[
|
||||||
|
'corporate' => $corporate,
|
||||||
|
'service' => CorporateServiceConfigResource::make($corporateService),
|
||||||
|
'specialities' => $specialities,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function corporateServiceUpdate(Request $request, $corporate_id, $service_code)
|
||||||
|
{
|
||||||
|
// $corporate = Corporate::findOrFail($corporate_id);
|
||||||
|
$corporateService = CorporateService::query()
|
||||||
|
->where('corporate_id', $corporate_id)
|
||||||
|
->where('service_code', $service_code)
|
||||||
|
// ->with('configs', 'service')
|
||||||
|
->first();
|
||||||
|
$corporateService->fill([
|
||||||
|
'status' => $request->status == 'active' ? 'active' : 'inactive'
|
||||||
|
]);
|
||||||
|
$corporateService->save();
|
||||||
|
|
||||||
|
return response()->json($corporateService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function corporateServiceSpecialityUpdate(Request $request, $corporate_id, $service_code)
|
||||||
|
{
|
||||||
|
$corporateService = CorporateService::query()
|
||||||
|
->where('corporate_id', $corporate_id)
|
||||||
|
->where('service_code', $service_code)
|
||||||
|
->first();
|
||||||
|
CorporateServiceSpeciality::updateOrCreate([
|
||||||
|
'corporate_service_id' => $corporateService->id,
|
||||||
|
'speciality_id' => $request->speciality_id,
|
||||||
|
], [
|
||||||
|
'corporate_service_id' => $corporateService->id,
|
||||||
|
'speciality_id' => $request->speciality_id,
|
||||||
|
'status' => $request->status
|
||||||
|
]);
|
||||||
|
|
||||||
|
$selected_specialities = CorporateServiceSpeciality::query()
|
||||||
|
->where('corporate_service_id', $corporateService->id)
|
||||||
|
->where('status', 'active')
|
||||||
|
->with('speciality')
|
||||||
|
->get()
|
||||||
|
->pluck('speciality.name', 'speciality.id');
|
||||||
|
|
||||||
|
return response()->json($selected_specialities);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,10 @@ Route::prefix('internal')->group(function () {
|
|||||||
Route::post('corporates/{corporate_id}/diagnosis-exclusions/import', [DiagnosisExclusionController::class, 'import']);
|
Route::post('corporates/{corporate_id}/diagnosis-exclusions/import', [DiagnosisExclusionController::class, 'import']);
|
||||||
|
|
||||||
Route::get('corporates/{corporate_id}/services', [CorporateServiceController::class, 'index']);
|
Route::get('corporates/{corporate_id}/services', [CorporateServiceController::class, 'index']);
|
||||||
Route::post('corporates/{corporate_id}/services', [CorporateServiceController::class, 'update']);
|
Route::put('corporates/{corporate_id}/services', [CorporateServiceController::class, 'update']);
|
||||||
|
Route::get('corporates/{corporate_id}/services/{service_code}', [CorporateServiceController::class, 'corporateServiceIndex']);
|
||||||
|
Route::put('corporates/{corporate_id}/services/{service_code}', [CorporateServiceController::class, 'corporateServiceUpdate']);
|
||||||
|
Route::post('corporates/{corporate_id}/services/{service_code}/specialities', [CorporateServiceController::class, 'corporateServiceSpecialityUpdate']);
|
||||||
|
|
||||||
Route::get('corporates/{corporate_id}/formulariums', [CorporateFormulariumController::class, 'index']);
|
Route::get('corporates/{corporate_id}/formulariums', [CorporateFormulariumController::class, 'index']);
|
||||||
Route::put('corporates/{corporate_id}/formulariums/{formularium_id}/{action}', [CorporateFormulariumController::class, 'updateStatus']);
|
Route::put('corporates/{corporate_id}/formulariums/{formularium_id}/{action}', [CorporateFormulariumController::class, 'updateStatus']);
|
||||||
|
|||||||
@@ -509,42 +509,6 @@ class MemberEnrollmentService
|
|||||||
$member->active = false;
|
$member->active = false;
|
||||||
|
|
||||||
$member->save();
|
$member->save();
|
||||||
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(strtotime($row['member_expiry_date']))) {
|
|
||||||
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_INVALID'), 0, null, $row);
|
|
||||||
}
|
|
||||||
|
|
||||||
$memberPolicy->save();
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "5": // Member Renewal Policy (without card)
|
case "5": // Member Renewal Policy (without card)
|
||||||
$memberPolicy = MemberPolicy::query()
|
$memberPolicy = MemberPolicy::query()
|
||||||
@@ -684,9 +648,6 @@ class MemberEnrollmentService
|
|||||||
}
|
}
|
||||||
|
|
||||||
throw new ImportRowException(__('MODE 7 NOT HANDLED PROPERLY'), 0, null, $row);
|
throw new ImportRowException(__('MODE 7 NOT HANDLED PROPERLY'), 0, null, $row);
|
||||||
break;
|
|
||||||
case "8": // Member Information Update (With Replacement Card)
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "9": // Member Reactivation and Personal information update (Without replacement Card)
|
case "9": // Member Reactivation and Personal information update (Without replacement Card)
|
||||||
$memberPolicy = MemberPolicy::query()
|
$memberPolicy = MemberPolicy::query()
|
||||||
@@ -716,29 +677,77 @@ class MemberEnrollmentService
|
|||||||
|
|
||||||
$memberPolicy->save();
|
$memberPolicy->save();
|
||||||
break;
|
break;
|
||||||
|
case "13": // Advance Renewal with OLD Card No. (NO PRINT)
|
||||||
|
// ASDASDASD
|
||||||
|
throw new ImportRowException(__('MODE 13 NOT HANDLED PROPERLY'), 0, null, $row);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// THESE MODES BELOW ARE DISABLED
|
||||||
|
case "4": // Member Update Start and End Date
|
||||||
|
throw new ImportRowException(__('MODE 4 NOT HANDLED PROPERLY, TRY TO USE MODE 2'), 0, null, $row);
|
||||||
|
break;
|
||||||
|
$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(strtotime($row['member_expiry_date']))) {
|
||||||
|
throw new ImportRowException(__('enrollment.MEMBER_EXPIRY_DATE_INVALID'), 0, null, $row);
|
||||||
|
}
|
||||||
|
|
||||||
|
$memberPolicy->save();
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "8": // Member Information Update (With Replacement Card)
|
||||||
|
throw new ImportRowException(__('MODE 8 NOT HANDLED PROPERLY, TRY TO USE MODE 2'), 0, null, $row);
|
||||||
|
break;
|
||||||
// case "10": // No Information Available
|
// case "10": // No Information Available
|
||||||
|
|
||||||
// break;
|
// break;
|
||||||
case "11": // Advance Renewal with OLD Card No. (PRINT)
|
case "11": // Advance Renewal with OLD Card No. (PRINT)
|
||||||
|
|
||||||
throw new ImportRowException(__('MODE 11 NOT HANDLED PROPERLY'), 0, null, $row);
|
throw new ImportRowException(__('MODE 11 NOT HANDLED PROPERLY, TRY TO USE MODE 13'), 0, null, $row);
|
||||||
break;
|
break;
|
||||||
case "12": // Advance Renewal iwh NEW Card No. (PRINT)
|
case "12": // Advance Renewal iwh NEW Card No. (PRINT)
|
||||||
|
|
||||||
throw new ImportRowException(__('MODE 12 NOT HANDLED PROPERLY'), 0, null, $row);
|
throw new ImportRowException(__('MODE 12 NOT HANDLED PROPERLY, TRY TO USE MODE 13'), 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;
|
break;
|
||||||
// case "14": // No Information Available
|
// case "14": // No Information Available
|
||||||
|
|
||||||
// break;
|
// break;
|
||||||
case "15": // Lost Card / Change Card with new card number (Print) (Rarely Used)
|
case "15": // Lost Card / Change Card with new card number (Print) (Rarely Used)
|
||||||
|
|
||||||
throw new ImportRowException(__('MODE 15 NOT HANDLED PROPERLY'), 0, null, $row);
|
throw new ImportRowException(__('MODE 15 NOT HANDLED PROPERLY, TRY TO USE MODE 2'), 0, null, $row);
|
||||||
break;
|
break;
|
||||||
case "16": // Endorsement Plan OLD Card No. (NO PRINT)
|
case "16": // Endorsement Plan OLD Card No. (NO PRINT)
|
||||||
|
throw new ImportRowException(__('MODE 16 NOT HANDLED PROPERLY, TRY TO USE MODE 2'), 0, null, $row);
|
||||||
|
break;
|
||||||
$plan = CorporatePlan::query()
|
$plan = CorporatePlan::query()
|
||||||
->where('corporate_id', $corporate->id)
|
->where('corporate_id', $corporate->id)
|
||||||
->where('code', $row['plan_id'])
|
->where('code', $row['plan_id'])
|
||||||
@@ -767,11 +776,9 @@ class MemberEnrollmentService
|
|||||||
]), 0, null, $row);
|
]), 0, null, $row);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ImportRowException(__('MODE 16 NOT HANDLED PROPERLY'), 0, null, $row);
|
|
||||||
break;
|
|
||||||
case "17": // Endorsement Plan OLD Card No. (PRINT)
|
case "17": // Endorsement Plan OLD Card No. (PRINT)
|
||||||
|
|
||||||
throw new ImportRowException(__('MODE 17 NOT HANDLED PROPERLY'), 0, null, $row);
|
throw new ImportRowException(__('MODE 17 NOT HANDLED PROPERLY, TRY TO USE MODE 2'), 0, null, $row);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ImportRowException(__("enrollment.MODE_UNAVAILABLE"), 0, null, $row);
|
throw new ImportRowException(__("enrollment.MODE_UNAVAILABLE"), 0, null, $row);
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ class CorporateServiceConfigResource extends JsonResource
|
|||||||
'status' => $this->status,
|
'status' => $this->status,
|
||||||
'name' => $this->service->name,
|
'name' => $this->service->name,
|
||||||
'description' => $this->service->description,
|
'description' => $this->service->description,
|
||||||
'configurations' => $this->configs->pluck('value', 'name')
|
'configurations' => $this->configs->pluck('value', 'name'),
|
||||||
|
'selected_specialities' => $this->specialities->pluck('speciality.name', 'speciality_id')
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,4 +31,19 @@ class CorporateService extends Model
|
|||||||
{
|
{
|
||||||
return $this->hasOne(Service::class, 'code', 'service_code');
|
return $this->hasOne(Service::class, 'code', 'service_code');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function specialities()
|
||||||
|
{
|
||||||
|
return $this->hasMany(CorporateServiceSpeciality::class, 'corporate_service_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scopeFilter($query, array $filters)
|
||||||
|
{
|
||||||
|
if (!empty($filters['search'])) {
|
||||||
|
$query->where('service_code', 'LIKE', '%'.$filters['search'].'%')
|
||||||
|
->orWhereHas('service', function($service) use ($filters) {
|
||||||
|
$service->where('name', 'LIKE', '%'.$filters['search'].'%');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
34
app/Models/CorporateServiceSpeciality.php
Normal file
34
app/Models/CorporateServiceSpeciality.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Traits\Blameable;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class CorporateServiceSpeciality extends Model
|
||||||
|
{
|
||||||
|
use HasFactory, SoftDeletes, Blameable;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'corporate_service_id',
|
||||||
|
'speciality_id',
|
||||||
|
'status'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function corporateService()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(CorporateService::class, 'corporate_service_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function corporate()
|
||||||
|
{
|
||||||
|
return $this->hasOneThrough(Corporate::class, CorporateService::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function speciality()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Speciality::class, 'speciality_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
23
app/Models/Speciality.php
Normal file
23
app/Models/Speciality.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Traits\Blameable;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class Speciality extends Model
|
||||||
|
{
|
||||||
|
use HasFactory, SoftDeletes, Blameable;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'code',
|
||||||
|
'name'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $guarded = [
|
||||||
|
'code',
|
||||||
|
'name'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
"psr/simple-cache": "^1.0"
|
"psr/simple-cache": "^1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"barryvdh/laravel-debugbar": "^3.7",
|
||||||
"barryvdh/laravel-ide-helper": "^2.12",
|
"barryvdh/laravel-ide-helper": "^2.12",
|
||||||
"fakerphp/faker": "^1.9.1",
|
"fakerphp/faker": "^1.9.1",
|
||||||
"laravel/sail": "^1.0.1",
|
"laravel/sail": "^1.0.1",
|
||||||
|
|||||||
152
composer.lock
generated
152
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "f4f7a646aaed46ea86bc501ff51dbe38",
|
"content-hash": "b90f9f090c04c5bbe673dadc0237e57d",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "box/spout",
|
"name": "box/spout",
|
||||||
@@ -5710,6 +5710,90 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
|
{
|
||||||
|
"name": "barryvdh/laravel-debugbar",
|
||||||
|
"version": "v3.7.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/barryvdh/laravel-debugbar.git",
|
||||||
|
"reference": "3372ed65e6d2039d663ed19aa699956f9d346271"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/3372ed65e6d2039d663ed19aa699956f9d346271",
|
||||||
|
"reference": "3372ed65e6d2039d663ed19aa699956f9d346271",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"illuminate/routing": "^7|^8|^9",
|
||||||
|
"illuminate/session": "^7|^8|^9",
|
||||||
|
"illuminate/support": "^7|^8|^9",
|
||||||
|
"maximebf/debugbar": "^1.17.2",
|
||||||
|
"php": ">=7.2.5",
|
||||||
|
"symfony/finder": "^5|^6"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"mockery/mockery": "^1.3.3",
|
||||||
|
"orchestra/testbench-dusk": "^5|^6|^7",
|
||||||
|
"phpunit/phpunit": "^8.5|^9.0",
|
||||||
|
"squizlabs/php_codesniffer": "^3.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.6-dev"
|
||||||
|
},
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"Barryvdh\\Debugbar\\ServiceProvider"
|
||||||
|
],
|
||||||
|
"aliases": {
|
||||||
|
"Debugbar": "Barryvdh\\Debugbar\\Facades\\Debugbar"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"src/helpers.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Barryvdh\\Debugbar\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Barry vd. Heuvel",
|
||||||
|
"email": "barryvdh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP Debugbar integration for Laravel",
|
||||||
|
"keywords": [
|
||||||
|
"debug",
|
||||||
|
"debugbar",
|
||||||
|
"laravel",
|
||||||
|
"profiler",
|
||||||
|
"webprofiler"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/barryvdh/laravel-debugbar/issues",
|
||||||
|
"source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.7.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://fruitcake.nl",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/barryvdh",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2022-07-11T09:26:42+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "barryvdh/laravel-ide-helper",
|
"name": "barryvdh/laravel-ide-helper",
|
||||||
"version": "v2.12.3",
|
"version": "v2.12.3",
|
||||||
@@ -6640,6 +6724,72 @@
|
|||||||
},
|
},
|
||||||
"time": "2022-05-02T13:58:40+00:00"
|
"time": "2022-05-02T13:58:40+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "maximebf/debugbar",
|
||||||
|
"version": "v1.18.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/maximebf/php-debugbar.git",
|
||||||
|
"reference": "0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6",
|
||||||
|
"reference": "0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^7.1|^8",
|
||||||
|
"psr/log": "^1|^2|^3",
|
||||||
|
"symfony/var-dumper": "^2.6|^3|^4|^5|^6"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^7.5.20 || ^9.4.2",
|
||||||
|
"twig/twig": "^1.38|^2.7|^3.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"kriswallsmith/assetic": "The best way to manage assets",
|
||||||
|
"monolog/monolog": "Log using Monolog",
|
||||||
|
"predis/predis": "Redis storage"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.17-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"DebugBar\\": "src/DebugBar/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Maxime Bouroumeau-Fuseau",
|
||||||
|
"email": "maxime.bouroumeau@gmail.com",
|
||||||
|
"homepage": "http://maximebf.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Barry vd. Heuvel",
|
||||||
|
"email": "barryvdh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Debug bar in the browser for php application",
|
||||||
|
"homepage": "https://github.com/maximebf/php-debugbar",
|
||||||
|
"keywords": [
|
||||||
|
"debug",
|
||||||
|
"debugbar"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/maximebf/php-debugbar/issues",
|
||||||
|
"source": "https://github.com/maximebf/php-debugbar/tree/v1.18.0"
|
||||||
|
},
|
||||||
|
"time": "2021-12-27T18:49:48+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "mockery/mockery",
|
"name": "mockery/mockery",
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('specialities', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('code')->nullable();
|
||||||
|
$table->string('name')->nullable();
|
||||||
|
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->unsignedBigInteger('created_by')->nullable()->index();
|
||||||
|
$table->unsignedBigInteger('updated_by')->nullable()->index();
|
||||||
|
$table->unsignedBigInteger('deleted_by')->nullable()->index();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('specialities');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('corporate_service_specialities', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('corporate_service_id');
|
||||||
|
$table->foreignId('speciality_id');
|
||||||
|
$table->string('status')->default('active');
|
||||||
|
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
|
||||||
|
$table->foreignId('created_by')->nullable();
|
||||||
|
$table->foreignId('updated_by')->nullable();
|
||||||
|
$table->foreignId('deleted_by')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('corporate_service_specialities');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -50,7 +50,7 @@ class IcdSeeder extends Seeder
|
|||||||
$chunks[] = $row_data;
|
$chunks[] = $row_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($chunks && count($chunks) == 1000) {
|
if ($chunks && count($chunks) == 100) {
|
||||||
Icd::insert($chunks);
|
Icd::insert($chunks);
|
||||||
$chunks = [];
|
$chunks = [];
|
||||||
}
|
}
|
||||||
|
|||||||
234
database/seeders/SpecialitiesSeeder.php
Normal file
234
database/seeders/SpecialitiesSeeder.php
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Models\Speciality;
|
||||||
|
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
|
class SpecialitiesSeeder extends Seeder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the database seeds.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$specialities = array(
|
||||||
|
array(
|
||||||
|
'code' => '1',
|
||||||
|
'name' => 'Akupunktur',
|
||||||
|
'image' => 'image/specialities/akupunktur.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '2',
|
||||||
|
'name' => 'Anak',
|
||||||
|
'image' => 'image/specialities/anak.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '3',
|
||||||
|
'name' => 'Andrologi',
|
||||||
|
'image' => 'image/specialities/andrologi.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '4',
|
||||||
|
'name' => 'Anestesi',
|
||||||
|
'image' => 'image/specialities/anestesi.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '5',
|
||||||
|
'name' => 'Bedah Anak',
|
||||||
|
'image' => 'image/specialities/bedah_anak.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '6',
|
||||||
|
'name' => 'Bedah Digestif',
|
||||||
|
'image' => 'image/specialities/bedah_digestif.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '7',
|
||||||
|
'name' => 'Bedah Mulut',
|
||||||
|
'image' => 'image/specialities/bedah_mulut.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '8',
|
||||||
|
'name' => 'Bedah Onkologi',
|
||||||
|
'image' => 'image/specialities/bedah_onkologi.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '9',
|
||||||
|
'name' => 'Bedah Orthopedi',
|
||||||
|
'image' => 'image/specialities/bedah_orthopedi.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '10',
|
||||||
|
'name' => 'Bedah Plastik & Rekonstruksi',
|
||||||
|
'image' => 'image/specialities/bedah_plastik_dan_rekonstruksi.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '11',
|
||||||
|
'name' => 'Bedah Saraf',
|
||||||
|
'image' => 'image/specialities/bedah_saraf.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '12',
|
||||||
|
'name' => 'Bedah Thorak & Kardiovaskuler',
|
||||||
|
'image' => 'image/specialities/bedah_thorak_dan_kardiovaskuler.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '13',
|
||||||
|
'name' => 'Bedah Umum',
|
||||||
|
'image' => 'image/specialities/bedah_umum.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '14',
|
||||||
|
'name' => 'Bedah Vaskuler',
|
||||||
|
'image' => 'image/specialities/bedah_vaskuler.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '15',
|
||||||
|
'name' => 'Dokter Gigi',
|
||||||
|
'image' => 'image/specialities/dokter_gigi.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '16',
|
||||||
|
'name' => 'Fisik & Rehabilitasi',
|
||||||
|
'image' => 'image/specialities/fisik_dan_rehabilitasi.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '17',
|
||||||
|
'name' => 'Gastroenterologi Hepatologi',
|
||||||
|
'image' => 'image/specialities/gastroenterologi_hepatologi.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '18',
|
||||||
|
'name' => 'Ginjal Hipertensi',
|
||||||
|
'image' => 'image/specialities/ginjal_hipertensi.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '19',
|
||||||
|
'name' => 'Gizi Klinik',
|
||||||
|
'image' => 'image/specialities/gizi_klinik.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '20',
|
||||||
|
'name' => 'Hematologi Onkologi',
|
||||||
|
'image' => 'image/specialities/hematologi_onkologi.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '21',
|
||||||
|
'name' => 'Jantung & Pembuluh Darah',
|
||||||
|
'image' => 'image/specialities/jantung_dan_pembuluh_darah.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '22',
|
||||||
|
'name' => 'Kardio Vaskuler',
|
||||||
|
'image' => 'image/specialities/kardio_vaskuler.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '23',
|
||||||
|
'name' => 'Kebidanan & Kandungan',
|
||||||
|
'image' => 'image/specialities/kebidanan_dan_kandungan.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '24',
|
||||||
|
'name' => 'Kesehatan Jiwa',
|
||||||
|
'image' => 'image/specialities/kesehatan_jiwa.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '25',
|
||||||
|
'name' => 'Kulit & Kelamin',
|
||||||
|
'image' => 'image/specialities/kulit_dan_kelamin.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '26',
|
||||||
|
'name' => 'Laboratorium',
|
||||||
|
'image' => 'image/specialities/laboratorium.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '27',
|
||||||
|
'name' => 'Mata',
|
||||||
|
'image' => 'image/specialities/mata.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '28',
|
||||||
|
'name' => 'Okupasi',
|
||||||
|
'image' => 'image/specialities/okupasi.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '29',
|
||||||
|
'name' => 'Paru',
|
||||||
|
'image' => 'image/specialities/paru.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '30',
|
||||||
|
'name' => 'Patologi Klinik',
|
||||||
|
'image' => 'image/specialities/patologi_klinik.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '31',
|
||||||
|
'name' => 'Penyakit Dalam',
|
||||||
|
'image' => 'image/specialities/penyakit_dalam.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '32',
|
||||||
|
'name' => 'Psikolog',
|
||||||
|
'image' => 'image/specialities/psikolog.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '33',
|
||||||
|
'name' => 'Radiolog',
|
||||||
|
'image' => 'image/specialities/radiolog.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '34',
|
||||||
|
'name' => 'Rehabilitasi Medik',
|
||||||
|
'image' => 'image/specialities/rehabilitasi_medik.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '35',
|
||||||
|
'name' => 'Rheumatologi',
|
||||||
|
'image' => 'image/specialities/rheumatologi.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '36',
|
||||||
|
'name' => 'Saraf',
|
||||||
|
'image' => 'image/specialities/saraf.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '37',
|
||||||
|
'name' => 'THT',
|
||||||
|
'image' => 'image/specialities/tht.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '38',
|
||||||
|
'name' => 'Umum',
|
||||||
|
'image' => 'image/specialities/umum.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '39',
|
||||||
|
'name' => 'Urologi',
|
||||||
|
'image' => 'image/specialities/urologi.png',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'code' => '40',
|
||||||
|
'name' => 'Lain-Lain',
|
||||||
|
'image' => 'image/specialities/lain_lain.png',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Speciality::truncate();
|
||||||
|
|
||||||
|
foreach ($specialities as $speciality) {
|
||||||
|
$speciality['code'] = "SP".str_pad($speciality['code'], 4, 0, STR_PAD_LEFT);
|
||||||
|
unset($speciality['image']);
|
||||||
|
Speciality::updateOrCreate(
|
||||||
|
[
|
||||||
|
'code' => $speciality['code'],
|
||||||
|
],
|
||||||
|
$speciality
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -171,3 +171,13 @@ export type Benefit = {
|
|||||||
show_benefit_item : string;
|
show_benefit_item : string;
|
||||||
show_benefit_value : string;
|
show_benefit_value : string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CorporateService = {
|
||||||
|
id?: string | number;
|
||||||
|
corporate_id?: string | number;
|
||||||
|
description?: string;
|
||||||
|
name?: string;
|
||||||
|
service_code: string;
|
||||||
|
status: string;
|
||||||
|
configurations: any;
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,20 +35,10 @@ export default function Divisions() {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Grid container spacing={2}>
|
<Card>
|
||||||
<Grid item xs={8}>
|
<CorporateTabNavigations position={'benefits'} />
|
||||||
<Card>
|
<DivisionsList />
|
||||||
<CorporateTabNavigations position={'benefits'} />
|
</Card>
|
||||||
<DivisionsList />
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={4}>
|
|
||||||
<Card sx={{ p: 2 }}>
|
|
||||||
Corporate Detail Goes Here
|
|
||||||
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs";
|
||||||
|
import Page from "../../../components/Page";
|
||||||
|
import useSettings from "../../../hooks/useSettings";
|
||||||
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
|
import axios from '../../../utils/axios';
|
||||||
|
import { useSnackbar } from 'notistack';
|
||||||
|
import CorporatePlanForm from './Form';
|
||||||
|
import { CorporatePlan } from '../../../@types/corporates';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default function PlanCreate() {
|
||||||
|
const { themeStretch } = useSettings();
|
||||||
|
const { corporate_id, id } = useParams();
|
||||||
|
const [ currentCorporatePlan, setCurrentCorporatePlan ] = useState<CorporatePlan>();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const isEdit = !!id;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isEdit) {
|
||||||
|
axios.get('/corporates/'+corporate_id+'/divisions/'+id+'/edit')
|
||||||
|
.then((res) => {
|
||||||
|
setCurrentCorporatePlan(res.data);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
if (err.response.status === 404) {
|
||||||
|
navigate('/404');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [corporate_id, id]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page title="Create Corporate Division">
|
||||||
|
<HeaderBreadcrumbs
|
||||||
|
heading={'Create Corporate Division'}
|
||||||
|
links={[
|
||||||
|
{
|
||||||
|
name: 'Corporates',
|
||||||
|
href: '/corporates',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Corporate Name',
|
||||||
|
href: '/corporates/'+corporate_id,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Division',
|
||||||
|
href: '/corporates/'+corporate_id+'/divisions',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: !isEdit ? 'Create' : 'Edit',
|
||||||
|
href: '/corporates/'+corporate_id+'/divisions/'+id,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<CorporatePlanForm isEdit={isEdit} currentCorporatePlan={currentCorporatePlan}/>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
}
|
||||||
129
frontend/dashboard/src/pages/Corporates/ClaimHistory/Form.tsx
Normal file
129
frontend/dashboard/src/pages/Corporates/ClaimHistory/Form.tsx
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
import * as Yup from 'yup';
|
||||||
|
import { LoadingButton } from "@mui/lab";
|
||||||
|
import { Card, Grid, Stack, Typography } from "@mui/material";
|
||||||
|
import { CorporatePlan } from "../../../@types/corporates";
|
||||||
|
import { FormProvider, RHFSwitch, RHFTextField } from "../../../components/hook-form";
|
||||||
|
import { useEffect, useMemo } from 'react';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { yupResolver } from '@hookform/resolvers/yup';
|
||||||
|
import { useSnackbar } from 'notistack';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
import axios from '../../../utils/axios';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
isEdit: boolean;
|
||||||
|
currentCorporatePlan?: CorporatePlan;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function CorporatePlanForm({ isEdit, currentCorporatePlan }: Props) {
|
||||||
|
|
||||||
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { corporate_id } = useParams();
|
||||||
|
|
||||||
|
const NewCorporatePlanSchema = Yup.object().shape({
|
||||||
|
name: Yup.string().required('Name is required'),
|
||||||
|
code: Yup.string().required('Corporate Code is required'),
|
||||||
|
});
|
||||||
|
|
||||||
|
const defaultValues = useMemo(
|
||||||
|
() => ({
|
||||||
|
name: currentCorporatePlan?.name || '',
|
||||||
|
code: currentCorporatePlan?.code || '',
|
||||||
|
active: currentCorporatePlan?.active === 1 ? true : false,
|
||||||
|
}),
|
||||||
|
[currentCorporatePlan]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isEdit && currentCorporatePlan) {
|
||||||
|
reset(defaultValues);
|
||||||
|
}
|
||||||
|
if (!isEdit) {
|
||||||
|
reset(defaultValues);
|
||||||
|
}
|
||||||
|
}, [isEdit, currentCorporatePlan]);
|
||||||
|
|
||||||
|
const methods = useForm({
|
||||||
|
resolver: yupResolver(NewCorporatePlanSchema),
|
||||||
|
defaultValues,
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
reset,
|
||||||
|
watch,
|
||||||
|
control,
|
||||||
|
setValue,
|
||||||
|
getValues,
|
||||||
|
setError,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { isSubmitting },
|
||||||
|
} = methods;
|
||||||
|
|
||||||
|
|
||||||
|
const onSubmit = async (data: any) => {
|
||||||
|
if (!isEdit) {
|
||||||
|
await axios
|
||||||
|
.post('/corporates/' + corporate_id + '/divisions', data)
|
||||||
|
.then((res) => {
|
||||||
|
enqueueSnackbar('Division created successfully', { variant: 'success' });
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
navigate('/corporates/' + corporate_id + '/divisions', { replace: true });
|
||||||
|
})
|
||||||
|
.catch(({ response }) => {
|
||||||
|
if (response.status === 422) {
|
||||||
|
for (const [key, value] of Object.entries(response.data.errors)) {
|
||||||
|
setError(key, { message: value[0] });
|
||||||
|
enqueueSnackbar(value[0] ?? 'Failed Processing Request', { variant: 'error' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
enqueueSnackbar('Create Failed : '+ response.data.message, { variant: 'error' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await axios
|
||||||
|
.put('/corporates/' + corporate_id + '/divisions/' + currentCorporatePlan?.id , data)
|
||||||
|
.then((res) => {
|
||||||
|
enqueueSnackbar('Division updated successfully', { variant: 'success' });
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
navigate('/corporates/' + corporate_id + '/divisions/' , { replace: true });
|
||||||
|
})
|
||||||
|
.catch(({ response }) => {
|
||||||
|
enqueueSnackbar('Update Failed : '+ response.data.message, { variant: 'error' });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={8}>
|
||||||
|
<Card sx={{ p: 2 }}>
|
||||||
|
<Stack spacing={3}>
|
||||||
|
|
||||||
|
<Typography variant="h6">Division Detail</Typography>
|
||||||
|
|
||||||
|
<RHFTextField name="name" label="Name" />
|
||||||
|
|
||||||
|
<RHFTextField name="code" label="Code" />
|
||||||
|
|
||||||
|
<LoadingButton type="submit" variant="contained" size="large" fullWidth={true} loading={isSubmitting}>
|
||||||
|
{ isEdit? 'Update' : 'Create' }
|
||||||
|
</LoadingButton>
|
||||||
|
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={4}>
|
||||||
|
<Card sx={{ p:2 }}>
|
||||||
|
|
||||||
|
<RHFSwitch name="active" label="Active" />
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</FormProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { Card, Grid, Typography } 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 { corporate_id } = useParams();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page title="Claim History">
|
||||||
|
|
||||||
|
<HeaderBreadcrumbs
|
||||||
|
heading={'Claim History'}
|
||||||
|
links={[
|
||||||
|
{
|
||||||
|
name: 'Corporates',
|
||||||
|
href: '/corporates',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Corporate Name',
|
||||||
|
href: '/corporates/'+corporate_id,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Claim History',
|
||||||
|
href: '/corporates/'+corporate_id+'/claim-histories',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<CorporateTabNavigations position={'claim-histories'} />
|
||||||
|
<Typography sx={{ m: 4 }}>Feature Not Implemented Yet</Typography>
|
||||||
|
</Card>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
}
|
||||||
234
frontend/dashboard/src/pages/Corporates/ClaimHistory/List.tsx
Normal file
234
frontend/dashboard/src/pages/Corporates/ClaimHistory/List.tsx
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
// @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, { ChangeEvent, Component, useEffect, useRef, useState } from 'react';
|
||||||
|
import useSettings from '../../../hooks/useSettings';
|
||||||
|
import { Link, useNavigate, useParams, useSearchParams } from 'react-router-dom';
|
||||||
|
// components
|
||||||
|
import axios from '../../../utils/axios';
|
||||||
|
import { CorporatePlan } from '../../../@types/corporates';
|
||||||
|
import { LaravelPaginatedData } from '../../../@types/paginated-data';
|
||||||
|
import BasePagination from '../../../components/BasePagination';
|
||||||
|
|
||||||
|
export default function PlanList() {
|
||||||
|
const { themeStretch } = useSettings();
|
||||||
|
const { corporate_id } = useParams();
|
||||||
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
function SearchInput(props: any) {
|
||||||
|
// SEARCH
|
||||||
|
const searchInput = useRef<HTMLInputElement>(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 (
|
||||||
|
<form onSubmit={handleSubmit} style={{ width: '100%' }}>
|
||||||
|
<TextField id="search-input" ref={searchInput} label="Search" variant="outlined" fullWidth onChange={handleSearchChange} value={searchText}/>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called on every row to map the data to the columns
|
||||||
|
function createData( plan: CorporatePlan ): CorporatePlan {
|
||||||
|
return {
|
||||||
|
...plan,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the every row of the table
|
||||||
|
function Row(props: { row: ReturnType<typeof createData> }) {
|
||||||
|
const { row } = props;
|
||||||
|
const [open, setOpen] = React.useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<TableRow sx={{ '& > *': { borderBottom: 'unset' } }}>
|
||||||
|
<TableCell>
|
||||||
|
<IconButton
|
||||||
|
aria-label="expand row"
|
||||||
|
size="small"
|
||||||
|
onClick={() => setOpen(!open)}
|
||||||
|
>
|
||||||
|
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
|
||||||
|
</IconButton>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">{row.id}</TableCell>
|
||||||
|
<TableCell align="left">{row.code}</TableCell>
|
||||||
|
<TableCell align="left">{row.name}</TableCell>
|
||||||
|
<TableCell align="left">{row.description}</TableCell>
|
||||||
|
<TableCell align="right"><Button variant="outlined" color="success" size="small">Active</Button></TableCell>
|
||||||
|
<TableCell align="right"><Link to={`/corporates/${row.corporate_id}/divisions/${row.id}/edit`}><Button variant="outlined" color="success" size="small">Edit</Button></Link></TableCell>
|
||||||
|
</TableRow>
|
||||||
|
{/* COLLAPSIBLE ROW */}
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={10}>
|
||||||
|
<Collapse in={open} timeout="auto" unmountOnExit>
|
||||||
|
<Box sx={{ borderBottom: 1 }}>
|
||||||
|
<Typography variant="body2" gutterBottom component="div">
|
||||||
|
No Extra Data
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
{false && <Box sx={{ margin: 1 }}>
|
||||||
|
<Typography variant="h6" gutterBottom component="div">
|
||||||
|
Rules
|
||||||
|
</Typography>
|
||||||
|
<Table size="small" aria-label="purchases">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell>Date</TableCell>
|
||||||
|
<TableCell>Customer</TableCell>
|
||||||
|
<TableCell align="right">Amount</TableCell>
|
||||||
|
<TableCell align="right">Total price ($)</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{/* {row.history ? row.history.map((historyRow) => ( */}
|
||||||
|
<TableRow key={row.id}>
|
||||||
|
<TableCell component="th" scope="row">{row.start} - {row.end}</TableCell>
|
||||||
|
<TableCell>{row.start}</TableCell>
|
||||||
|
<TableCell align="right">{row.start}</TableCell>
|
||||||
|
<TableCell align="right">{row.start}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
{/* ))
|
||||||
|
: (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={8}>No Data</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)
|
||||||
|
} */}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</Box>}
|
||||||
|
</Collapse>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dummy Default Data
|
||||||
|
const [dataTableIsLoading, setDataTableLoading] = React.useState(true);
|
||||||
|
const [dataTableData, setDataTableData] = React.useState<LaravelPaginatedData>({
|
||||||
|
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 : any | null = null) => {
|
||||||
|
setDataTableLoading(true);
|
||||||
|
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
||||||
|
const response = await axios.get('/corporates/'+corporate_id+'/divisions', { params: filter });
|
||||||
|
// console.log(response.data);
|
||||||
|
setDataTableLoading(false);
|
||||||
|
|
||||||
|
setDataTableData(response.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const headStyle = {
|
||||||
|
fontWeight: 'bold',
|
||||||
|
};
|
||||||
|
|
||||||
|
const applyFilter = async (searchFilter: any) => {
|
||||||
|
await loadDataTableData({ "search" : searchFilter });
|
||||||
|
setSearchParams({ "search" : searchFilter });
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePageChange = (event : ChangeEvent, value: number) => {
|
||||||
|
const filter = Object.fromEntries([...searchParams.entries(), ["page", value]]);
|
||||||
|
loadDataTableData(filter);
|
||||||
|
setSearchParams(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadDataTableData();
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack>
|
||||||
|
<Stack direction={'row'} spacing={2} sx={{ p: 2 }}>
|
||||||
|
<SearchInput onSearch={applyFilter}/>
|
||||||
|
<Link to={`/corporates/${corporate_id}/divisions/create`}>
|
||||||
|
<Button
|
||||||
|
component="button"
|
||||||
|
id="upload-button"
|
||||||
|
variant='outlined'
|
||||||
|
startIcon={<AddIcon />} sx={{ p: 1.8 }}
|
||||||
|
>
|
||||||
|
Create
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
{/* The Main Table */}
|
||||||
|
<TableContainer component={Paper}>
|
||||||
|
<Table aria-label="collapsible table">
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={headStyle} align="left" />
|
||||||
|
<TableCell style={headStyle} align="left">ID</TableCell>
|
||||||
|
<TableCell style={headStyle} align="left">Code</TableCell>
|
||||||
|
<TableCell style={headStyle} align="left">Name</TableCell>
|
||||||
|
<TableCell style={headStyle} align="left">Description</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
{dataTableIsLoading ?
|
||||||
|
(
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={8} align="center">Loading</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
) : (
|
||||||
|
dataTableData.data.length == 0 ?
|
||||||
|
(
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={8} align="center">No Data</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
) : (
|
||||||
|
<TableBody>
|
||||||
|
{dataTableData.data.map(row => (
|
||||||
|
<Row key={row.code} row={row} />
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
<BasePagination paginationData={dataTableData} onPageChange={handlePageChange}/>
|
||||||
|
</Card>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Tab, Tabs } from "@mui/material";
|
import { Tab, Tabs } from "@mui/material";
|
||||||
import { useTheme } from "@mui/system";
|
import { useTheme } from "@mui/system";
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { Link, useParams } from "react-router-dom";
|
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
position: string
|
position: string
|
||||||
@@ -9,6 +9,7 @@ type Props = {
|
|||||||
|
|
||||||
export default function CorporateTabNavigations({ position }: Props) {
|
export default function CorporateTabNavigations({ position }: Props) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const { corporate_id } = useParams();
|
const { corporate_id } = useParams();
|
||||||
|
|
||||||
@@ -73,13 +74,13 @@ export default function CorporateTabNavigations({ position }: Props) {
|
|||||||
<Tabs
|
<Tabs
|
||||||
theme={theme}
|
theme={theme}
|
||||||
value={currentTab}
|
value={currentTab}
|
||||||
onChange={(event, newValue) => false}
|
// onChange={(event, newValue) => false}
|
||||||
variant="scrollable"
|
variant="scrollable"
|
||||||
scrollButtons
|
scrollButtons
|
||||||
allowScrollButtonsMobile
|
allowScrollButtonsMobile
|
||||||
aria-label="scrollable force tabs example"
|
aria-label="scrollable force tabs example"
|
||||||
>
|
>
|
||||||
{mainTabItems.map((tabItem, index) => (<Tab key={index} label={(<Link to={"/corporates/"+corporate_id+"/"+mainTabItems[index].path} style={{ textDecoration: 'none', color: 'black' }}>{tabItem.label}</Link>)} />))}
|
{mainTabItems.map((tabItem, index) => (<Tab key={index} onClick={() => { navigate("/corporates/"+corporate_id+"/"+mainTabItems[index].path) }}label={tabItem.label}/>))}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,9 +35,8 @@ export default function Divisions() {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<CorporateTabNavigations position={'diagnosis-exclusions'} />
|
|
||||||
|
|
||||||
<Card>
|
<Card>
|
||||||
|
<CorporateTabNavigations position={'diagnosis-exclusions'} />
|
||||||
<List />
|
<List />
|
||||||
</Card>
|
</Card>
|
||||||
</Page>
|
</Page>
|
||||||
|
|||||||
@@ -34,20 +34,10 @@ export default function Divisions() {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Grid container spacing={2}>
|
<Card>
|
||||||
<Grid item xs={8}>
|
<CorporateTabNavigations position={'divisions'} />
|
||||||
<Card>
|
<DivisionsList />
|
||||||
<CorporateTabNavigations position={'divisions'} />
|
</Card>
|
||||||
<DivisionsList />
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={4}>
|
|
||||||
<Card sx={{ p: 2 }}>
|
|
||||||
Corporate Detail Goes Here
|
|
||||||
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// @mui
|
// @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 { 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, Input, Grid } from '@mui/material';
|
||||||
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
||||||
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
@@ -44,26 +44,66 @@ export default function PlanList() {
|
|||||||
function SearchInput(props: any) {
|
function SearchInput(props: any) {
|
||||||
// SEARCH
|
// SEARCH
|
||||||
const searchInput = useRef<HTMLInputElement>(null);
|
const searchInput = useRef<HTMLInputElement>(null);
|
||||||
|
// const filterForm = useRef();
|
||||||
const [searchText, setSearchText] = useState("");
|
const [searchText, setSearchText] = useState("");
|
||||||
|
const [searchStatus, setSearchStatus] = useState("active");
|
||||||
|
|
||||||
const handleSearchChange = (event: any) => {
|
const handleSearchChange = (event: any) => {
|
||||||
const newSearchText = event.target.value ?? ''
|
const newSearchText = event.target.value ?? ''
|
||||||
setSearchText(newSearchText);
|
setSearchText(newSearchText);
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSubmit = (event: any) => {
|
const handleStatusChange = (event: any) => {
|
||||||
event.preventDefault();
|
const newSearchStatus = event.target.value ?? ''
|
||||||
props.onSearch(searchText); // Trigger to Parent
|
console.log('changing to', newSearchStatus)
|
||||||
|
setSearchStatus(newSearchStatus)
|
||||||
|
// console.log(searchStatus);
|
||||||
|
|
||||||
|
const searchFilter = {
|
||||||
|
"search" : searchText,
|
||||||
|
"status" : newSearchStatus
|
||||||
|
};
|
||||||
|
|
||||||
|
props.onSearch(searchFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
const handleSubmit = (event?: any) => {
|
||||||
// console.log('Search Input: useEffect')
|
event?.preventDefault();
|
||||||
|
const searchFilter = {
|
||||||
|
"search" : searchText,
|
||||||
|
"status" : searchStatus
|
||||||
|
};
|
||||||
|
|
||||||
|
props.onSearch(searchFilter); // Trigger to Parent
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
setSearchText(searchParams.get('search') ?? '');
|
setSearchText(searchParams.get('search') ?? '');
|
||||||
|
setSearchStatus(searchParams.get('status') ?? searchStatus ?? 'active');
|
||||||
}, [searchParams])
|
}, [searchParams])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit} style={{ width: '100%' }}>
|
<form id="search-form" onSubmit={handleSubmit} style={{ width: '100%' }}>
|
||||||
<TextField id="search-input" ref={searchInput} label="Search" variant="outlined" fullWidth onChange={handleSearchChange} value={searchText}/>
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={9}>
|
||||||
|
<TextField id="search-input" ref={searchInput} label="Search" variant="outlined" fullWidth onChange={handleSearchChange} value={searchText}/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid item xs={3}>
|
||||||
|
<Select
|
||||||
|
label="Status"
|
||||||
|
value={searchStatus}
|
||||||
|
onChange={handleStatusChange}
|
||||||
|
sx={{ width: '100%' }}
|
||||||
|
>
|
||||||
|
<MenuItem value="active">Active</MenuItem>
|
||||||
|
<MenuItem value="inactive">Inactive</MenuItem>
|
||||||
|
<MenuItem value="all">All</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</Grid>
|
||||||
|
{/* ITS FUCKING MAGIC, SUBMIT BY ENTER WORKING IF THIS BUTTON IS AVAILABLE */}
|
||||||
|
<Button type='submit' variant="outlined" sx={{ p: 1.8, display: 'none' }}>Search</Button>
|
||||||
|
</Grid>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -171,8 +211,8 @@ export default function PlanList() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const applyFilter = async (searchFilter: any) => {
|
const applyFilter = async (searchFilter: any) => {
|
||||||
await loadDataTableData({ "search" : searchFilter });
|
await loadDataTableData(searchFilter);
|
||||||
setSearchParams({ "search" : searchFilter });
|
setSearchParams(searchFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePageChange = (event : ChangeEvent, value: number) => {
|
const handlePageChange = (event : ChangeEvent, value: number) => {
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs";
|
||||||
|
import Page from "../../../components/Page";
|
||||||
|
import useSettings from "../../../hooks/useSettings";
|
||||||
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
|
import axios from '../../../utils/axios';
|
||||||
|
import { useSnackbar } from 'notistack';
|
||||||
|
import CorporatePlanForm from './Form';
|
||||||
|
import { CorporatePlan } from '../../../@types/corporates';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default function PlanCreate() {
|
||||||
|
const { themeStretch } = useSettings();
|
||||||
|
const { corporate_id, id } = useParams();
|
||||||
|
const [ currentCorporatePlan, setCurrentCorporatePlan ] = useState<CorporatePlan>();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const isEdit = !!id;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isEdit) {
|
||||||
|
axios.get('/corporates/'+corporate_id+'/divisions/'+id+'/edit')
|
||||||
|
.then((res) => {
|
||||||
|
setCurrentCorporatePlan(res.data);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
if (err.response.status === 404) {
|
||||||
|
navigate('/404');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [corporate_id, id]);
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page title="Create Corporate Division">
|
||||||
|
<HeaderBreadcrumbs
|
||||||
|
heading={'Create Corporate Division'}
|
||||||
|
links={[
|
||||||
|
{
|
||||||
|
name: 'Corporates',
|
||||||
|
href: '/corporates',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Corporate Name',
|
||||||
|
href: '/corporates/'+corporate_id,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Division',
|
||||||
|
href: '/corporates/'+corporate_id+'/divisions',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: !isEdit ? 'Create' : 'Edit',
|
||||||
|
href: '/corporates/'+corporate_id+'/divisions/'+id,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<CorporatePlanForm isEdit={isEdit} currentCorporatePlan={currentCorporatePlan}/>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
}
|
||||||
129
frontend/dashboard/src/pages/Corporates/Hospital/Form.tsx
Normal file
129
frontend/dashboard/src/pages/Corporates/Hospital/Form.tsx
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
import * as Yup from 'yup';
|
||||||
|
import { LoadingButton } from "@mui/lab";
|
||||||
|
import { Card, Grid, Stack, Typography } from "@mui/material";
|
||||||
|
import { CorporatePlan } from "../../../@types/corporates";
|
||||||
|
import { FormProvider, RHFSwitch, RHFTextField } from "../../../components/hook-form";
|
||||||
|
import { useEffect, useMemo } from 'react';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { yupResolver } from '@hookform/resolvers/yup';
|
||||||
|
import { useSnackbar } from 'notistack';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
import axios from '../../../utils/axios';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
isEdit: boolean;
|
||||||
|
currentCorporatePlan?: CorporatePlan;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function CorporatePlanForm({ isEdit, currentCorporatePlan }: Props) {
|
||||||
|
|
||||||
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { corporate_id } = useParams();
|
||||||
|
|
||||||
|
const NewCorporatePlanSchema = Yup.object().shape({
|
||||||
|
name: Yup.string().required('Name is required'),
|
||||||
|
code: Yup.string().required('Corporate Code is required'),
|
||||||
|
});
|
||||||
|
|
||||||
|
const defaultValues = useMemo(
|
||||||
|
() => ({
|
||||||
|
name: currentCorporatePlan?.name || '',
|
||||||
|
code: currentCorporatePlan?.code || '',
|
||||||
|
active: currentCorporatePlan?.active === 1 ? true : false,
|
||||||
|
}),
|
||||||
|
[currentCorporatePlan]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isEdit && currentCorporatePlan) {
|
||||||
|
reset(defaultValues);
|
||||||
|
}
|
||||||
|
if (!isEdit) {
|
||||||
|
reset(defaultValues);
|
||||||
|
}
|
||||||
|
}, [isEdit, currentCorporatePlan]);
|
||||||
|
|
||||||
|
const methods = useForm({
|
||||||
|
resolver: yupResolver(NewCorporatePlanSchema),
|
||||||
|
defaultValues,
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
reset,
|
||||||
|
watch,
|
||||||
|
control,
|
||||||
|
setValue,
|
||||||
|
getValues,
|
||||||
|
setError,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { isSubmitting },
|
||||||
|
} = methods;
|
||||||
|
|
||||||
|
|
||||||
|
const onSubmit = async (data: any) => {
|
||||||
|
if (!isEdit) {
|
||||||
|
await axios
|
||||||
|
.post('/corporates/' + corporate_id + '/divisions', data)
|
||||||
|
.then((res) => {
|
||||||
|
enqueueSnackbar('Division created successfully', { variant: 'success' });
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
navigate('/corporates/' + corporate_id + '/divisions', { replace: true });
|
||||||
|
})
|
||||||
|
.catch(({ response }) => {
|
||||||
|
if (response.status === 422) {
|
||||||
|
for (const [key, value] of Object.entries(response.data.errors)) {
|
||||||
|
setError(key, { message: value[0] });
|
||||||
|
enqueueSnackbar(value[0] ?? 'Failed Processing Request', { variant: 'error' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
enqueueSnackbar('Create Failed : '+ response.data.message, { variant: 'error' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await axios
|
||||||
|
.put('/corporates/' + corporate_id + '/divisions/' + currentCorporatePlan?.id , data)
|
||||||
|
.then((res) => {
|
||||||
|
enqueueSnackbar('Division updated successfully', { variant: 'success' });
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
navigate('/corporates/' + corporate_id + '/divisions/' , { replace: true });
|
||||||
|
})
|
||||||
|
.catch(({ response }) => {
|
||||||
|
enqueueSnackbar('Update Failed : '+ response.data.message, { variant: 'error' });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<Grid container spacing={2}>
|
||||||
|
<Grid item xs={8}>
|
||||||
|
<Card sx={{ p: 2 }}>
|
||||||
|
<Stack spacing={3}>
|
||||||
|
|
||||||
|
<Typography variant="h6">Division Detail</Typography>
|
||||||
|
|
||||||
|
<RHFTextField name="name" label="Name" />
|
||||||
|
|
||||||
|
<RHFTextField name="code" label="Code" />
|
||||||
|
|
||||||
|
<LoadingButton type="submit" variant="contained" size="large" fullWidth={true} loading={isSubmitting}>
|
||||||
|
{ isEdit? 'Update' : 'Create' }
|
||||||
|
</LoadingButton>
|
||||||
|
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={4}>
|
||||||
|
<Card sx={{ p:2 }}>
|
||||||
|
|
||||||
|
<RHFSwitch name="active" label="Active" />
|
||||||
|
</Card>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</FormProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
43
frontend/dashboard/src/pages/Corporates/Hospital/Index.tsx
Normal file
43
frontend/dashboard/src/pages/Corporates/Hospital/Index.tsx
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { Card, Grid, Typography } 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 { corporate_id } = useParams();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page title="Hospitals">
|
||||||
|
|
||||||
|
<HeaderBreadcrumbs
|
||||||
|
heading={'Hospitals'}
|
||||||
|
links={[
|
||||||
|
{
|
||||||
|
name: 'Corporates',
|
||||||
|
href: '/corporates',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Corporate Name',
|
||||||
|
href: '/corporates/'+corporate_id,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Hospitals',
|
||||||
|
href: '/corporates/'+corporate_id+'/hospitals',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<CorporateTabNavigations position={'hospitals'} />
|
||||||
|
<Typography sx={{ m:4 }}>Feature Not Implemented Yet</Typography>
|
||||||
|
</Card>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
}
|
||||||
234
frontend/dashboard/src/pages/Corporates/Hospital/List.tsx
Normal file
234
frontend/dashboard/src/pages/Corporates/Hospital/List.tsx
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
// @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, { ChangeEvent, Component, useEffect, useRef, useState } from 'react';
|
||||||
|
import useSettings from '../../../hooks/useSettings';
|
||||||
|
import { Link, useNavigate, useParams, useSearchParams } from 'react-router-dom';
|
||||||
|
// components
|
||||||
|
import axios from '../../../utils/axios';
|
||||||
|
import { CorporatePlan } from '../../../@types/corporates';
|
||||||
|
import { LaravelPaginatedData } from '../../../@types/paginated-data';
|
||||||
|
import BasePagination from '../../../components/BasePagination';
|
||||||
|
|
||||||
|
export default function PlanList() {
|
||||||
|
const { themeStretch } = useSettings();
|
||||||
|
const { corporate_id } = useParams();
|
||||||
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
function SearchInput(props: any) {
|
||||||
|
// SEARCH
|
||||||
|
const searchInput = useRef<HTMLInputElement>(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 (
|
||||||
|
<form onSubmit={handleSubmit} style={{ width: '100%' }}>
|
||||||
|
<TextField id="search-input" ref={searchInput} label="Search" variant="outlined" fullWidth onChange={handleSearchChange} value={searchText}/>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called on every row to map the data to the columns
|
||||||
|
function createData( plan: CorporatePlan ): CorporatePlan {
|
||||||
|
return {
|
||||||
|
...plan,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the every row of the table
|
||||||
|
function Row(props: { row: ReturnType<typeof createData> }) {
|
||||||
|
const { row } = props;
|
||||||
|
const [open, setOpen] = React.useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<TableRow sx={{ '& > *': { borderBottom: 'unset' } }}>
|
||||||
|
<TableCell>
|
||||||
|
<IconButton
|
||||||
|
aria-label="expand row"
|
||||||
|
size="small"
|
||||||
|
onClick={() => setOpen(!open)}
|
||||||
|
>
|
||||||
|
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
|
||||||
|
</IconButton>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="left">{row.id}</TableCell>
|
||||||
|
<TableCell align="left">{row.code}</TableCell>
|
||||||
|
<TableCell align="left">{row.name}</TableCell>
|
||||||
|
<TableCell align="left">{row.description}</TableCell>
|
||||||
|
<TableCell align="right"><Button variant="outlined" color="success" size="small">Active</Button></TableCell>
|
||||||
|
<TableCell align="right"><Link to={`/corporates/${row.corporate_id}/divisions/${row.id}/edit`}><Button variant="outlined" color="success" size="small">Edit</Button></Link></TableCell>
|
||||||
|
</TableRow>
|
||||||
|
{/* COLLAPSIBLE ROW */}
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={10}>
|
||||||
|
<Collapse in={open} timeout="auto" unmountOnExit>
|
||||||
|
<Box sx={{ borderBottom: 1 }}>
|
||||||
|
<Typography variant="body2" gutterBottom component="div">
|
||||||
|
No Extra Data
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
{false && <Box sx={{ margin: 1 }}>
|
||||||
|
<Typography variant="h6" gutterBottom component="div">
|
||||||
|
Rules
|
||||||
|
</Typography>
|
||||||
|
<Table size="small" aria-label="purchases">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell>Date</TableCell>
|
||||||
|
<TableCell>Customer</TableCell>
|
||||||
|
<TableCell align="right">Amount</TableCell>
|
||||||
|
<TableCell align="right">Total price ($)</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{/* {row.history ? row.history.map((historyRow) => ( */}
|
||||||
|
<TableRow key={row.id}>
|
||||||
|
<TableCell component="th" scope="row">{row.start} - {row.end}</TableCell>
|
||||||
|
<TableCell>{row.start}</TableCell>
|
||||||
|
<TableCell align="right">{row.start}</TableCell>
|
||||||
|
<TableCell align="right">{row.start}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
{/* ))
|
||||||
|
: (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={8}>No Data</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)
|
||||||
|
} */}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</Box>}
|
||||||
|
</Collapse>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dummy Default Data
|
||||||
|
const [dataTableIsLoading, setDataTableLoading] = React.useState(true);
|
||||||
|
const [dataTableData, setDataTableData] = React.useState<LaravelPaginatedData>({
|
||||||
|
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 : any | null = null) => {
|
||||||
|
setDataTableLoading(true);
|
||||||
|
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
||||||
|
const response = await axios.get('/corporates/'+corporate_id+'/divisions', { params: filter });
|
||||||
|
// console.log(response.data);
|
||||||
|
setDataTableLoading(false);
|
||||||
|
|
||||||
|
setDataTableData(response.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const headStyle = {
|
||||||
|
fontWeight: 'bold',
|
||||||
|
};
|
||||||
|
|
||||||
|
const applyFilter = async (searchFilter: any) => {
|
||||||
|
await loadDataTableData({ "search" : searchFilter });
|
||||||
|
setSearchParams({ "search" : searchFilter });
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePageChange = (event : ChangeEvent, value: number) => {
|
||||||
|
const filter = Object.fromEntries([...searchParams.entries(), ["page", value]]);
|
||||||
|
loadDataTableData(filter);
|
||||||
|
setSearchParams(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadDataTableData();
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack>
|
||||||
|
<Stack direction={'row'} spacing={2} sx={{ p: 2 }}>
|
||||||
|
<SearchInput onSearch={applyFilter}/>
|
||||||
|
<Link to={`/corporates/${corporate_id}/divisions/create`}>
|
||||||
|
<Button
|
||||||
|
component="button"
|
||||||
|
id="upload-button"
|
||||||
|
variant='outlined'
|
||||||
|
startIcon={<AddIcon />} sx={{ p: 1.8 }}
|
||||||
|
>
|
||||||
|
Create
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
{/* The Main Table */}
|
||||||
|
<TableContainer component={Paper}>
|
||||||
|
<Table aria-label="collapsible table">
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell style={headStyle} align="left" />
|
||||||
|
<TableCell style={headStyle} align="left">ID</TableCell>
|
||||||
|
<TableCell style={headStyle} align="left">Code</TableCell>
|
||||||
|
<TableCell style={headStyle} align="left">Name</TableCell>
|
||||||
|
<TableCell style={headStyle} align="left">Description</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
{dataTableIsLoading ?
|
||||||
|
(
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={8} align="center">Loading</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
) : (
|
||||||
|
dataTableData.data.length == 0 ?
|
||||||
|
(
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={8} align="center">No Data</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
) : (
|
||||||
|
<TableBody>
|
||||||
|
{dataTableData.data.map(row => (
|
||||||
|
<Row key={row.code} row={row} />
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
<BasePagination paginationData={dataTableData} onPageChange={handlePageChange}/>
|
||||||
|
</Card>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -34,20 +34,11 @@ export default function Divisions() {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Grid container spacing={2}>
|
<Card>
|
||||||
<Grid item xs={8}>
|
<CorporateTabNavigations position={'plans'} />
|
||||||
<Card>
|
<DivisionsList />
|
||||||
<CorporateTabNavigations position={'plans'} />
|
</Card>
|
||||||
<DivisionsList />
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={4}>
|
|
||||||
<Card sx={{ p: 2 }}>
|
|
||||||
Corporate Detail Goes Here
|
|
||||||
|
|
||||||
</Card>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import { Card, Collapse, Divider, Grid, Stack, Typography } from "@mui/material";
|
import { Box, Card, Checkbox, Collapse, Divider, FormControlLabel, Grid, Modal, Paper, Stack, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from "@mui/material";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs";
|
import HeaderBreadcrumbs from "../../../components/HeaderBreadcrumbs";
|
||||||
@@ -9,134 +9,91 @@ import Page from "../../../components/Page";
|
|||||||
import useSettings from "../../../hooks/useSettings";
|
import useSettings from "../../../hooks/useSettings";
|
||||||
import CorporateTabNavigations from "../CorporateTabNavigations";
|
import CorporateTabNavigations from "../CorporateTabNavigations";
|
||||||
import DivisionsList from "./List";
|
import DivisionsList from "./List";
|
||||||
import { useMemo, useState } from 'react';
|
import { ChangeEvent, useEffect, useMemo, useState } from 'react';
|
||||||
|
import axios from '../../../utils/axios';
|
||||||
|
import { CorporateService } from '../../../@types/corporates';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function Divisions() {
|
export default function Divisions() {
|
||||||
const { themeStretch } = useSettings();
|
const { themeStretch } = useSettings();
|
||||||
|
|
||||||
const { corporate_id } = useParams();
|
const { corporate_id, service_code } = useParams();
|
||||||
|
|
||||||
const NewDivisionSchema = Yup.object().shape({
|
const [service, setService] = useState<CorporateService>({
|
||||||
name: Yup.string().required('Name is required'),
|
"configurations" : {},
|
||||||
code: Yup.string().required('Corporate Code is required'),
|
"corporate_id": "null",
|
||||||
active: Yup.boolean().required('Corporate Status is required'),
|
"name" : "",
|
||||||
|
"description" : "",
|
||||||
|
"service_code" : "",
|
||||||
|
"status" : "active"
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultValues = useMemo(
|
const [specialities, setSpecialities] = useState([])
|
||||||
() => ({
|
|
||||||
code: '',
|
|
||||||
}),
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
const methods = useForm({
|
useEffect(() => {
|
||||||
resolver: yupResolver(NewDivisionSchema),
|
axios.get('/corporates/'+corporate_id+'/services/'+service_code)
|
||||||
defaultValues,
|
.then((res) => {
|
||||||
});
|
setService(res.data.service)
|
||||||
|
setSpecialities(res.data.specialities)
|
||||||
|
});
|
||||||
|
}, [])
|
||||||
|
|
||||||
const {
|
|
||||||
reset,
|
|
||||||
watch,
|
|
||||||
control,
|
|
||||||
setValue,
|
|
||||||
getValues,
|
|
||||||
setError,
|
|
||||||
handleSubmit,
|
|
||||||
formState: { isSubmitting },
|
|
||||||
} = methods;
|
|
||||||
|
|
||||||
const onSubmit = async (data: any) => {
|
const handleConfigChange = (event: ChangeEvent<HTMLInputElement>, service: any) => {
|
||||||
console.log(data);
|
axios.put(`/corporates/${corporate_id}/services`, {
|
||||||
|
service_code: service.service_code,
|
||||||
|
config_name: event.target.name,
|
||||||
|
config_value: event.target.checked
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
let newConfigurations = service.configurations
|
||||||
|
newConfigurations[res.data.name] = res.data.value == true
|
||||||
|
|
||||||
|
setService({
|
||||||
|
...service,
|
||||||
|
configurations: { ...newConfigurations }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleToggleSpeciality = (event: ChangeEvent<HTMLInputElement>, service: any, speciality: any) => {
|
||||||
|
console.log('Changing Service ', service, 'and', speciality)
|
||||||
|
axios.post(`/corporates/${corporate_id}/services/${service_code}/specialities`, {
|
||||||
|
// service_code: service.service_code,
|
||||||
|
speciality_id: speciality.id,
|
||||||
|
status: event.target.checked ? 'active' : 'inactive'
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setService({
|
||||||
|
...service,
|
||||||
|
selected_specialities : res.data
|
||||||
|
})
|
||||||
|
// let newConfigurations = service.configurations
|
||||||
|
// newConfigurations[res.data.name] = res.data.value == true
|
||||||
|
|
||||||
|
// setService({
|
||||||
|
// ...service,
|
||||||
|
// configurations: { ...newConfigurations }
|
||||||
|
// })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const specialityModalStyle = {
|
||||||
|
position: 'absolute' as 'absolute',
|
||||||
|
top: '50%',
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translate(-50%, -50%)',
|
||||||
|
width: '80%',
|
||||||
|
maxHeight: '80%',
|
||||||
|
overflowY: 'scroll',
|
||||||
|
bgcolor: 'background.paper',
|
||||||
|
border: '2px solid gray',
|
||||||
|
boxShadow: 24,
|
||||||
|
p: 4,
|
||||||
};
|
};
|
||||||
|
const [specialityModal, setSpecialityModal] = useState(false)
|
||||||
|
|
||||||
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 (
|
return (
|
||||||
<Page title="Create Benefit">
|
<Page title="Create Benefit">
|
||||||
@@ -151,15 +108,15 @@ export default function Divisions() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Corporate Name',
|
name: 'Corporate Name',
|
||||||
href: '/corporates/'+id,
|
href: '/corporates/'+corporate_id,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Benefits',
|
name: 'Services',
|
||||||
href: '/corporates/'+id+'/benefits',
|
href: '/corporates/'+corporate_id+'/services',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Create',
|
name: service.name ?? '-',
|
||||||
href: '/corporates/'+id+'/benefits/create',
|
href: '/corporates/'+corporate_id+'/services/'+service_code,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
@@ -168,71 +125,239 @@ export default function Divisions() {
|
|||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<Card sx={{ p: 2 }}>
|
<Card sx={{ p: 2 }}>
|
||||||
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
|
{/* <FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}> */}
|
||||||
<Stack spacing={3}>
|
<Box sx={{ borderBottom: 1 }}>
|
||||||
|
<Stack>
|
||||||
|
|
||||||
<Typography variant="h6">Benefit Detail</Typography>
|
<TableContainer sx={{ mb:4 }}>
|
||||||
|
<Table sx={{ minWidth: 650 }} size="small">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={4} sx={{ py: 1 }} align="center">General Practitioner</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={2}>External Doctor</TableCell>
|
||||||
|
<TableCell colSpan={2}>Internal Doctor</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell>
|
||||||
|
<FormControlLabel control={(
|
||||||
|
<Checkbox
|
||||||
|
checked={service?.configurations?.gp_external_doctor_online == '1'}
|
||||||
|
onChange={(event) => {handleConfigChange(event, service)}}
|
||||||
|
name="gp_external_doctor_online" />
|
||||||
|
)}
|
||||||
|
label="Online" />
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<FormControlLabel control={(
|
||||||
|
<Checkbox
|
||||||
|
checked={service?.configurations?.gp_external_doctor_offline == '1'}
|
||||||
|
onChange={(event) => {handleConfigChange(event, service)}}
|
||||||
|
name="gp_external_doctor_offline" />
|
||||||
|
)}
|
||||||
|
label="Offline" />
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<FormControlLabel control={(
|
||||||
|
<Checkbox
|
||||||
|
checked={service?.configurations?.gp_internal_doctor_online == '1'}
|
||||||
|
onChange={(event) => {handleConfigChange(event, service)}}
|
||||||
|
name="gp_internal_doctor_online" />
|
||||||
|
)}
|
||||||
|
label="Online" />
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<FormControlLabel control={(
|
||||||
|
<Checkbox
|
||||||
|
checked={service?.configurations?.gp_internal_doctor_offline == '1'}
|
||||||
|
onChange={(event) => {handleConfigChange(event, service)}}
|
||||||
|
name="gp_internal_doctor_offline" />
|
||||||
|
)}
|
||||||
|
label="Offline" />
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
|
||||||
<RHFTextField name="name" label="Benefit Name" />
|
<TableContainer sx={{ mb:4 }}>
|
||||||
|
<Table sx={{ minWidth: 650 }} size="small">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={4} sx={{ py: 1 }} align="center">Specialist Practitioner</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={2}>External Doctor</TableCell>
|
||||||
|
<TableCell colSpan={2}>Internal Doctor</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell>
|
||||||
|
<FormControlLabel control={(
|
||||||
|
<Checkbox
|
||||||
|
checked={service?.configurations?.sp_external_doctor_online == '1'}
|
||||||
|
onChange={(event) => {handleConfigChange(event, service)}}
|
||||||
|
name="sp_external_doctor_online" />
|
||||||
|
)}
|
||||||
|
label="Online" />
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<FormControlLabel control={(
|
||||||
|
<Checkbox
|
||||||
|
checked={service?.configurations?.sp_external_doctor_offline == '1'}
|
||||||
|
onChange={(event) => {handleConfigChange(event, service)}}
|
||||||
|
name="sp_external_doctor_offline" />
|
||||||
|
)}
|
||||||
|
label="Offline" />
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<FormControlLabel control={(
|
||||||
|
<Checkbox
|
||||||
|
checked={service?.configurations?.sp_internal_doctor_online == '1'}
|
||||||
|
onChange={(event) => {handleConfigChange(event, service)}}
|
||||||
|
name="sp_internal_doctor_online" />
|
||||||
|
)}
|
||||||
|
label="Online" />
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<FormControlLabel control={(
|
||||||
|
<Checkbox
|
||||||
|
checked={service?.configurations?.sp_internal_doctor_offline == '1'}
|
||||||
|
onChange={(event) => {handleConfigChange(event, service)}}
|
||||||
|
name="sp_internal_doctor_offline" />
|
||||||
|
)}
|
||||||
|
label="Offline" />
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={4}>
|
||||||
|
<Typography onClick={() => { setSpecialityModal(true) }}>
|
||||||
|
Specialities : ({service.selected_specialities ? Object.keys(service.selected_specialities).length : '0'})
|
||||||
|
</Typography>
|
||||||
|
<Typography>{service.selected_specialities ? '{'+Object.values(service.selected_specialities).join(', ')+'}' : ''}</Typography>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
|
||||||
<RHFTextField name="code" label="Benefit Code" />
|
<Modal
|
||||||
|
open={specialityModal}
|
||||||
|
onClose={() => { setSpecialityModal(false) }}
|
||||||
|
aria-labelledby="modal-modal-title"
|
||||||
|
aria-describedby="modal-modal-description"
|
||||||
|
>
|
||||||
|
<Box sx={specialityModalStyle}>
|
||||||
|
<Typography id="modal-modal-title" variant="h6" component="h2" sx={{ pb: 4 }}>
|
||||||
|
Specialities
|
||||||
|
</Typography>
|
||||||
|
<TableContainer component={Paper}>
|
||||||
|
<Table sx={{ minWidth: 650 }} aria-label="simple table">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell />
|
||||||
|
<TableCell>Nama Spesialisasi</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{specialities.map((row) => (
|
||||||
|
<TableRow
|
||||||
|
key={row.name}
|
||||||
|
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
|
||||||
|
>
|
||||||
|
<TableCell>
|
||||||
|
<Checkbox
|
||||||
|
checked={ Object.keys(service.selected_specialities).includes(String(row.id)) }
|
||||||
|
onChange={(event) => {handleToggleSpeciality(event, service, row)}}
|
||||||
|
name="vitamins" />
|
||||||
|
</TableCell>
|
||||||
|
<TableCell component="th" scope="row">
|
||||||
|
{row.name}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</Box>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
<Typography variant="h6">Benefit Configuration</Typography>
|
<TableContainer sx={{ mb:4 }}>
|
||||||
|
<Table sx={{ minWidth: 650 }} size="small">
|
||||||
<Divider orientation="horizontal" flexItem />
|
<TableHead>
|
||||||
<Stack spacing={3} divider={<Divider orientation="horizontal" flexItem />}>
|
<TableRow>
|
||||||
<Stack spacing={2}>
|
<TableCell colSpan={4} sx={{ py: 1 }} align="center">Medicine</TableCell>
|
||||||
<RHFCheckbox name="a" label='Outpatient'/>
|
</TableRow>
|
||||||
{benefits.map(row => (
|
</TableHead>
|
||||||
<Collapse in={true} timeout="auto" unmountOnExit >
|
<TableBody>
|
||||||
<Typography>{row.category}</Typography>
|
<TableRow>
|
||||||
<Grid container>
|
<TableCell width={'25%'}>
|
||||||
{row.childs.map(benefit => (
|
<FormControlLabel control={(
|
||||||
<Grid item xs={6}>
|
<Checkbox
|
||||||
<RHFCheckbox name={benefit.code} label={benefit.name}/>
|
checked={service?.configurations?.vitamins == '1'}
|
||||||
</Grid>
|
onChange={(event) => {handleConfigChange(event, service)}}
|
||||||
))}
|
name="vitamins" />
|
||||||
</Grid>
|
)}
|
||||||
</Collapse>
|
label="Vitamins" />
|
||||||
))}
|
</TableCell>
|
||||||
<Typography>Admin Fee</Typography>
|
<TableCell width={'25%'}>
|
||||||
<Grid container>
|
<FormControlLabel control={(
|
||||||
{benefits.map(row => (
|
<Checkbox
|
||||||
<Grid item xs={4}>
|
checked={service?.configurations?.delivery_fee == '1'}
|
||||||
<RHFCheckbox name="cat" label={row.category}/>
|
onChange={(event) => {handleConfigChange(event, service)}}
|
||||||
</Grid>
|
name="delivery_fee" />
|
||||||
))}
|
)}
|
||||||
</Grid>
|
label="Delivery Fee" />
|
||||||
</Stack>
|
</TableCell>
|
||||||
|
<TableCell width={'25%'}/>
|
||||||
|
<TableCell width={'25%'}/>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
|
||||||
|
<TableContainer sx={{ mb:4 }}>
|
||||||
|
<Table sx={{ minWidth: 650 }} size="small">
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={4} sx={{ py: 1 }} align="center">Free Admin Fee</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell width={'25%'}>
|
||||||
|
<FormControlLabel control={(
|
||||||
|
<Checkbox
|
||||||
|
checked={service?.configurations?.general_practitioner_fee == '1'}
|
||||||
|
onChange={(event) => {handleConfigChange(event, service)}}
|
||||||
|
name="general_practitioner_fee" />
|
||||||
|
)}
|
||||||
|
label="General Practitioner" />
|
||||||
|
</TableCell>
|
||||||
|
<TableCell width={'25%'}>
|
||||||
|
<FormControlLabel control={(
|
||||||
|
<Checkbox
|
||||||
|
checked={service?.configurations?.specialist_practitioner_fee == '1'}
|
||||||
|
onChange={(event) => {handleConfigChange(event, service)}}
|
||||||
|
name="specialist_practitioner_fee" />
|
||||||
|
)}
|
||||||
|
label="Specialist Practitioner" />
|
||||||
|
</TableCell>
|
||||||
|
<TableCell width={'25%'}/>
|
||||||
|
<TableCell width={'25%'}/>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
|
||||||
|
|
||||||
<Stack spacing={2}>
|
|
||||||
<RHFCheckbox name="a" label='Inpatient'/>
|
|
||||||
{benefits.map(row => (
|
|
||||||
<Collapse in={true} timeout="auto" unmountOnExit >
|
|
||||||
<Typography>{row.category}</Typography>
|
|
||||||
<Grid container>
|
|
||||||
{row.childs.map(benefit => (
|
|
||||||
<Grid item xs={6}>
|
|
||||||
<RHFCheckbox name={benefit.code} label={benefit.name}/>
|
|
||||||
</Grid>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
</Collapse>
|
|
||||||
))}
|
|
||||||
<Typography>Admin Fee</Typography>
|
|
||||||
<Grid container>
|
|
||||||
{benefits.map(row => (
|
|
||||||
<Grid item xs={4}>
|
|
||||||
<RHFCheckbox name="cat" label={row.category}/>
|
|
||||||
</Grid>
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
</Stack>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
|
</Box>
|
||||||
</Stack>
|
{/* </FormProvider> */}
|
||||||
</FormProvider>
|
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import CancelIcon from '@mui/icons-material/Cancel';
|
|||||||
// hooks
|
// hooks
|
||||||
import React, { ChangeEvent, Component, useEffect, useMemo, useRef, useState } from 'react';
|
import React, { ChangeEvent, Component, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import useSettings from '../../../hooks/useSettings';
|
import useSettings from '../../../hooks/useSettings';
|
||||||
import { useParams, useSearchParams } from 'react-router-dom';
|
import { Link, useParams, useSearchParams } from 'react-router-dom';
|
||||||
// components
|
// components
|
||||||
import axios from '../../../utils/axios';
|
import axios from '../../../utils/axios';
|
||||||
import { LaravelPaginatedData } from '../../../@types/paginated-data';
|
import { LaravelPaginatedData } from '../../../@types/paginated-data';
|
||||||
@@ -19,12 +19,34 @@ import { useForm } from 'react-hook-form';
|
|||||||
import { yupResolver } from '@hookform/resolvers/yup';
|
import { yupResolver } from '@hookform/resolvers/yup';
|
||||||
import { RHFCheckbox } from '../../../components/hook-form';
|
import { RHFCheckbox } from '../../../components/hook-form';
|
||||||
import { CheckBox } from '@mui/icons-material';
|
import { CheckBox } from '@mui/icons-material';
|
||||||
|
import { CorporateService } from '../../../@types/corporates';
|
||||||
|
|
||||||
export default function List() {
|
export default function List() {
|
||||||
const { themeStretch } = useSettings();
|
const { themeStretch } = useSettings();
|
||||||
const { corporate_id } = useParams();
|
const { corporate_id } = useParams();
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
const [importResult, setImportResult] = useState(null);
|
const [importResult, setImportResult] = useState(null);
|
||||||
|
|
||||||
|
|
||||||
|
// Dummy Default Data
|
||||||
|
const [dataTableIsLoading, setDataTableLoading] = useState(true);
|
||||||
|
const [dataTableLastRequest, setDataTableLastRequest] = useState(0);
|
||||||
|
const [dataTableResponseState, setDataTableResponseState] = useState('idle');
|
||||||
|
const [dataTableData, setDataTableData] = useState<LaravelPaginatedData>({
|
||||||
|
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
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
function SearchInput(props: any) {
|
function SearchInput(props: any) {
|
||||||
// SEARCH
|
// SEARCH
|
||||||
@@ -68,9 +90,9 @@ export default function List() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Called on every row to map the data to the columns
|
// Called on every row to map the data to the columns
|
||||||
function createData( icd: Icd ): Icd {
|
function createData( corporateService: CorporateService ): CorporateService {
|
||||||
return {
|
return {
|
||||||
...icd,
|
...corporateService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,17 +104,35 @@ export default function List() {
|
|||||||
const handleConfigChange = (event: ChangeEvent<HTMLInputElement>, service: any) => {
|
const handleConfigChange = (event: ChangeEvent<HTMLInputElement>, service: any) => {
|
||||||
console.log( event.target.name ,event.target.checked, service);
|
console.log( event.target.name ,event.target.checked, service);
|
||||||
|
|
||||||
axios.post(`/corporates/${corporate_id}/services`, {
|
axios.put(`/corporates/${corporate_id}/services`, {
|
||||||
service_code: service.service_code,
|
service_code: service.service_code,
|
||||||
config_name: event.target.name,
|
config_name: event.target.name,
|
||||||
config_value: event.target.checked
|
config_value: event.target.checked
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleActivate = (service: any, status: string) => {
|
||||||
|
axios.put(`/corporates/${corporate_id}/services/${service.service_code}`, {
|
||||||
|
service_code: service.service_code,
|
||||||
|
status
|
||||||
|
}).then((res) => {
|
||||||
|
setDataTableData({
|
||||||
|
...dataTableData,
|
||||||
|
data: dataTableData.data.map((service) => {
|
||||||
|
let updatedService = service
|
||||||
|
if (row.id == service.id) {
|
||||||
|
updatedService.status = res.data.status
|
||||||
|
}
|
||||||
|
return updatedService
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<TableRow sx={{ '& > *': { borderBottom: 'unset' } }}>
|
<TableRow sx={{ '& > *': { borderBottom: 'unset' } }}>
|
||||||
<TableCell>
|
{/* <TableCell>
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label="expand row"
|
aria-label="expand row"
|
||||||
size="small"
|
size="small"
|
||||||
@@ -100,14 +140,20 @@ export default function List() {
|
|||||||
>
|
>
|
||||||
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
|
{open ? <KeyboardArrowDownIcon /> : <KeyboardArrowRightIcon />}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</TableCell>
|
</TableCell> */}
|
||||||
|
<TableCell align="left">{row.service_code}</TableCell>
|
||||||
<TableCell align="left">{row.name}</TableCell>
|
<TableCell align="left">{row.name}</TableCell>
|
||||||
|
|
||||||
<TableCell align="right"><Button variant="outlined" color="success" size="small">Active</Button></TableCell>
|
<TableCell align="right">
|
||||||
<TableCell align="right"><Button variant="outlined" color="error" size="small">Disable</Button></TableCell>
|
{( row.status == 'active' && <Button variant="outlined" color="success" size="small" onClick={() => { handleActivate(row, 'inactive') }}>Active</Button> )}
|
||||||
|
{( row.status == 'inactive' && <Button variant="outlined" color="error" size="small" onClick={() => { handleActivate(row, 'active') }}>Inactive</Button> )}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="right">
|
||||||
|
<Link to={`/corporates/${corporate_id}/services/${row.service_code}`}><Button variant="outlined" color="primary" size="small">Config</Button></ Link>
|
||||||
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
{/* COLLAPSIBLE ROW */}
|
{/* COLLAPSIBLE ROW */}
|
||||||
<TableRow>
|
{false && <TableRow>
|
||||||
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={99}>
|
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={99}>
|
||||||
<Collapse in={open} timeout="auto" unmountOnExit>
|
<Collapse in={open} timeout="auto" unmountOnExit>
|
||||||
<Box sx={{ borderBottom: 1 }}>
|
<Box sx={{ borderBottom: 1 }}>
|
||||||
@@ -223,29 +269,11 @@ export default function List() {
|
|||||||
</Collapse>
|
</Collapse>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dummy Default Data
|
|
||||||
const [dataTableIsLoading, setDataTableLoading] = useState(true);
|
|
||||||
const [dataTableLastRequest, setDataTableLastRequest] = useState(0);
|
|
||||||
const [dataTableResponseState, setDataTableResponseState] = useState('idle');
|
|
||||||
const [dataTableData, setDataTableData] = useState<LaravelPaginatedData>({
|
|
||||||
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 : any | null = null) => {
|
const loadDataTableData = async (appliedFilter : any | null = null) => {
|
||||||
setDataTableLoading(true);
|
setDataTableLoading(true);
|
||||||
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
const filter = appliedFilter ? appliedFilter : Object.fromEntries([...searchParams.entries()]);
|
||||||
@@ -423,7 +451,8 @@ export default function List() {
|
|||||||
<Table aria-label="collapsible table">
|
<Table aria-label="collapsible table">
|
||||||
<TableBody>
|
<TableBody>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell style={headStyle} align="left" width={10}/>
|
{/* <TableCell style={headStyle} align="left" width={10}/> */}
|
||||||
|
<TableCell style={headStyle} align="left">Code</TableCell>
|
||||||
<TableCell style={headStyle} align="left">Service</TableCell>
|
<TableCell style={headStyle} align="left">Service</TableCell>
|
||||||
|
|
||||||
<TableCell style={headStyle} align="right" width={30}>Status</TableCell>
|
<TableCell style={headStyle} align="right" width={30}>Status</TableCell>
|
||||||
|
|||||||
@@ -118,6 +118,10 @@ export default function Router() {
|
|||||||
path: 'corporates/:corporate_id/services',
|
path: 'corporates/:corporate_id/services',
|
||||||
element: <CorporateServices />,
|
element: <CorporateServices />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'corporates/:corporate_id/services/:service_code',
|
||||||
|
element: <CorporateServicesCreate />,
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: 'corporates/:corporate_id/plans/create',
|
path: 'corporates/:corporate_id/plans/create',
|
||||||
@@ -173,6 +177,16 @@ export default function Router() {
|
|||||||
element: <DiagnosisExclusions />,
|
element: <DiagnosisExclusions />,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: 'corporates/:corporate_id/hospitals',
|
||||||
|
element: <CorporateHospitals />,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
path: 'corporates/:corporate_id/claim-history',
|
||||||
|
element: <CorporateClaimHistories />,
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: 'master/diagnosis',
|
path: 'master/diagnosis',
|
||||||
element: <MasterDiagnosis />,
|
element: <MasterDiagnosis />,
|
||||||
@@ -269,3 +283,7 @@ const MasterFormularium = Loadable(lazy(() => import('../pages/Master/Formulariu
|
|||||||
const MasterFormulariumCreate = Loadable(lazy(() => import('../pages/Master/Formularium/Create')));
|
const MasterFormulariumCreate = Loadable(lazy(() => import('../pages/Master/Formularium/Create')));
|
||||||
|
|
||||||
const CorporateServices = Loadable(lazy(() => import('../pages/Corporates/Services/Index')));
|
const CorporateServices = Loadable(lazy(() => import('../pages/Corporates/Services/Index')));
|
||||||
|
const CorporateServicesCreate = Loadable(lazy(() => import('../pages/Corporates/Services/Create')));
|
||||||
|
|
||||||
|
const CorporateHospitals = Loadable(lazy(() => import('../pages/Corporates/Hospital/Index')));
|
||||||
|
const CorporateClaimHistories = Loadable(lazy(() => import('../pages/Corporates/ClaimHistory/Index')));
|
||||||
|
|||||||
2
storage/debugbar/.gitignore
vendored
Normal file
2
storage/debugbar/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
Reference in New Issue
Block a user