diff --git a/Modules/Internal/Http/Controllers/Api/ClaimController.php b/Modules/Internal/Http/Controllers/Api/ClaimController.php index 4909f83d..876c2d82 100644 --- a/Modules/Internal/Http/Controllers/Api/ClaimController.php +++ b/Modules/Internal/Http/Controllers/Api/ClaimController.php @@ -2,10 +2,14 @@ namespace Modules\Internal\Http\Controllers\Api; +use App\Models\Benefit; use App\Models\Claim; +use App\Models\Icd; +use App\Models\Member; use Illuminate\Contracts\Support\Renderable; use Illuminate\Http\Request; use Illuminate\Routing\Controller; +use Modules\Internal\Services\ClaimService; class ClaimController extends Controller { @@ -21,6 +25,7 @@ class ClaimController extends Controller 'plan', 'benefit' ]) + ->latest() ->paginate(10); return response()->json($claims); @@ -42,7 +47,28 @@ class ClaimController extends Controller */ public function store(Request $request) { - // + $request->validate([ + 'diagnosis_id' => 'required', + 'member_id' => 'required', + 'total_claim' => 'required', + 'benefit_id' => 'required' + ]); + + // return response()->json($request->toArray()); + + $member = Member::find($request->member_id); + $benefit = Benefit::find($request->benefit_id); + $diagnosis = Icd::find($request->diagnosis_id); + + // Check Eligibility + $validation = ClaimService::checkMemberEligibility($member, $benefit, $diagnosis, $request->total_claim); + + // Store Claim + if ($validation['isEligible']) { + $claim = ClaimService::storeClaim($member, $diagnosis, $request->total_claim, $benefit); + } + + return response()->json($claim); } /** diff --git a/Modules/Internal/Http/Controllers/Api/MemberController.php b/Modules/Internal/Http/Controllers/Api/MemberController.php index f8defb31..96925c7b 100644 --- a/Modules/Internal/Http/Controllers/Api/MemberController.php +++ b/Modules/Internal/Http/Controllers/Api/MemberController.php @@ -15,7 +15,9 @@ class MemberController extends Controller */ public function index() { - return Member::paginate(); + return Member::query() + ->with('currentPlan') + ->paginate(); } /** @@ -77,4 +79,11 @@ class MemberController extends Controller { // } + + public function benefits($member_id) + { + $member = Member::findOrFail($member_id); + + return response()->json($member->currentPlan->benefits()->select(['description', 'code', 'id'])->get()); + } } diff --git a/Modules/Internal/Routes/api.php b/Modules/Internal/Routes/api.php index 57709300..c9eab7ed 100755 --- a/Modules/Internal/Routes/api.php +++ b/Modules/Internal/Routes/api.php @@ -96,8 +96,10 @@ Route::prefix('internal')->group(function () { Route::post('master/formulariums/import', [FormulariumController::class, 'import']); Route::get('members', [MemberController::class, 'index']); + Route::get('members/{member_id}/benefits', [MemberController::class, 'benefits']); Route::get('claims', [ClaimController::class, 'index']); + Route::post('claims', [ClaimController::class, 'store']); Route::post('check-limit', [ClaimController::class, 'checkLimit']); }); diff --git a/Modules/Internal/Services/ClaimService.php b/Modules/Internal/Services/ClaimService.php new file mode 100644 index 00000000..569cf8dd --- /dev/null +++ b/Modules/Internal/Services/ClaimService.php @@ -0,0 +1,115 @@ +currentPlan; + $policy = $member->currentPolicy; + $corporate = $policy->corporate; + + + $isEligible = true; + $validationErrors = []; + + // Eligibility Validation + + if (!in_array($member->marital_status, explode(',', $benefit->msc))) { + $validationErrors[] = [ + 'error' => 'msc', + 'message' => 'Only '.$benefit->msc + ]; + $isEligible = false; + } + + if (!in_array($member->gender_code, explode(',', $benefit->genders))) { + $validationErrors[] = [ + 'error' => 'genders', + 'message' => 'Only '.$benefit->genders + ]; + $isEligible = false; + } + + if (!empty($benefit->min_age) && $member->age < $benefit->min_age) { + $validationErrors[] = [ + 'error' => 'min_age', + 'message' => 'Minimum Age is '.$benefit->min_age + ]; + $isEligible = false; + } + + if (!empty($benefit->max_age) && $member->age > $benefit->max_age) { + $validationErrors[] = [ + 'error' => 'max_age', + 'message' => 'Maximum Age is '.$benefit->min_age + ]; + $isEligible = false; + } + + // TODO complete validations + + // Limit Validation + if ($totalClaim > 0) { + if (bcsub($corporate->limit_balance, $totalClaim) < 0) { + $validationErrors[] = [ + 'error' => 'corporate_limit', + 'message' => 'Corporate Limit cannot cover this' + ]; + $isEligible = false; + } + + if (bcsub($benefit->limit_amount, $totalClaim) < 0) { + $validationErrors[] = [ + 'error' => 'benefit_limit', + 'message' => 'Benefit Limit cannot cover this' + ]; + $isEligible = false; + } + + // TODO complete validations + + } + + return [ + 'isEligible' => $isEligible, + 'errors' => $validationErrors + ]; + } + + public static function storeClaim($member, $diagnosis, $totalClaim, $benefit) + { + try { + DB::beginTransaction(); + + $claim = Claim::create([ + 'member_id' => $member->id, + 'diagnosis_id' => $diagnosis->id, + 'total_claim' => $totalClaim, + 'currency' => 'IDR', + 'plan_id' => $member->currentPlan->id, + 'benefit_id' => $benefit->id, + ]); + + $policy = $member->currentPolicy; + $policy->limitJournals()->create([ + 'previous_balance' => $policy->limit_balance, + 'total_credit' => $totalClaim, + 'type' => 'credit', + 'balance' => bcsub($policy->limit_balance, $totalClaim), + 'description' => 'Log for Claim #'. $claim->code, + ]); + + DB::commit(); + return $claim; + } catch (\Exception $error) { + DB::rollBack(); + + return false; + } + } +} \ No newline at end of file diff --git a/Modules/Internal/Services/MemberEnrollmentService.php b/Modules/Internal/Services/MemberEnrollmentService.php index fc45e427..50a7c283 100755 --- a/Modules/Internal/Services/MemberEnrollmentService.php +++ b/Modules/Internal/Services/MemberEnrollmentService.php @@ -427,6 +427,7 @@ class MemberEnrollmentService // TODO validate corporate plan $plan = Plan::query() ->where('code', $row['plan_id']) + ->where('corporate_id', $corporate->id) ->first(); if (!$plan) { throw new ImportRowException(__('enrollment.PLAN_NOT_FOUND'), 0, null, $row); @@ -461,7 +462,7 @@ class MemberEnrollmentService ]); $member->memberPlans()->create([ - 'plan_id' => $plan->code, + 'plan_id' => $plan->id, 'status' => 'active', 'start' => Carbon::parse(strtotime($row['member_effective_date'])), 'end' => Carbon::parse(strtotime($row['member_expiry_date'])), diff --git a/app/Http/Controllers/Api/MemberController.php b/app/Http/Controllers/Api/MemberController.php index 164aa93b..97bcfd29 100755 --- a/app/Http/Controllers/Api/MemberController.php +++ b/app/Http/Controllers/Api/MemberController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; +use App\Models\Member; use Illuminate\Http\Request; class MemberController extends Controller diff --git a/app/Models/Claim.php b/app/Models/Claim.php index 39919309..5c5d6b63 100644 --- a/app/Models/Claim.php +++ b/app/Models/Claim.php @@ -4,6 +4,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Str; class Claim extends Model { @@ -19,6 +20,28 @@ class Claim extends Model 'benefit_id', ]; + protected $hidden = [ + 'created_at', + 'updated_at', + 'deleted_at', + 'created_by', + 'updated_by', + 'deleted_by', + ]; + + protected static function boot() + { + parent::boot(); + + static::creating(function ($model) { + try { + $model->code = (string) Str::orderedUuid(); // generate uuid + } catch (\Exception $e) { + abort(500, $e->getMessage()); + } + }); + } + public function member() { return $this->belongsTo(Member::class, 'member_id'); @@ -38,4 +61,5 @@ class Claim extends Model { return $this->belongsTo(Benefit::class, 'benefit_id'); } + } diff --git a/app/Models/Corporate.php b/app/Models/Corporate.php index d8147665..04ad740f 100755 --- a/app/Models/Corporate.php +++ b/app/Models/Corporate.php @@ -106,4 +106,9 @@ class Corporate extends Model { return $this->hasMany(Corporate::class, 'parent_id'); } + + public function getLimitBalanceAttribute() + { + return $this->currentPolicy->limit_balance; + } } diff --git a/app/Models/CorporatePolicy.php b/app/Models/CorporatePolicy.php index 1e8d99d5..7ccde342 100755 --- a/app/Models/CorporatePolicy.php +++ b/app/Models/CorporatePolicy.php @@ -34,6 +34,11 @@ class CorporatePolicy extends Model return $this->belongsTo(Corporate::class); } + public function limitJournals() + { + return $this->morphMany(LimitJournal::class, 'journalable'); + } + public function setCodeAttribute($value) { $this->attributes['code'] = !empty($value) ? $value : Str::upper(Str::random('6')); @@ -53,4 +58,11 @@ class CorporatePolicy extends Model { $this->attributes['end'] = !empty($value) ? Carbon::parse($value)->format('Y-m-d') : null; } + + public function getLimitBalanceAttribute() + { + $journal = $this->limitJournals()->latest()->first(); + + return $journal ? $journal->balance : (!empty($this->total_premi) ? $this->total_premi : "0"); + } } diff --git a/app/Models/Icd.php b/app/Models/Icd.php index 40115736..9dfa57ff 100755 --- a/app/Models/Icd.php +++ b/app/Models/Icd.php @@ -27,6 +27,15 @@ class Icd extends Model 'active' ]; + protected $hidden = [ + 'created_at', + 'updated_at', + 'deleted_at', + 'created_by', + 'updated_by', + 'deleted_by', + ]; + public function getTypeAttribute() { return 'ICD-'.$this->rev; diff --git a/app/Models/LimitJournal.php b/app/Models/LimitJournal.php index abba9b09..707715e9 100644 --- a/app/Models/LimitJournal.php +++ b/app/Models/LimitJournal.php @@ -11,7 +11,9 @@ class LimitJournal extends Model protected $fillable = [ 'journalable', - 'mutation', + 'previous_balance', + 'total_credit', + 'total_debit', 'type', 'balance', 'description', @@ -21,4 +23,15 @@ class LimitJournal extends Model { return $this->morphTo(); } + + public function setTotalCreditAttribute($value) + { + $this->attributes['total_credit'] = empty($value) ? 0 : $value; + } + + public function setTotalDebitAttribute($value) + { + $this->attributes['total_debit'] = empty($value) ? 0 : $value; + } + } diff --git a/app/Models/Member.php b/app/Models/Member.php index 759b47bd..dd499477 100755 --- a/app/Models/Member.php +++ b/app/Models/Member.php @@ -57,7 +57,20 @@ class Member extends Model "end_no_claim", ]; - protected $appends = ['full_name']; + protected $appends = [ + 'full_name', + 'age', + 'gender_code' + ]; + + protected $hidden = [ + 'created_at', + 'updated_at', + 'deleted_at', + 'created_by', + 'updated_by', + 'deleted_by', + ]; public function claims() { @@ -105,12 +118,12 @@ class Member extends Model public function plans() { - return $this->hasManyThrough(Plan::class, MemberPlan::class, 'member_id', 'code', 'id', 'plan_id'); + return $this->hasManyThrough(Plan::class, MemberPlan::class, 'member_id', 'id', 'id', 'plan_id'); } public function currentPlan() { - return $this->hasOneThrough(Plan::class, MemberPlan::class, 'member_id', 'code', 'id', 'plan_id')->latest(); + return $this->hasOneThrough(Plan::class, MemberPlan::class, 'member_id', 'id', 'id', 'plan_id')->latest(); } public function policies() @@ -120,7 +133,21 @@ class Member extends Model public function currentPolicy() { - return $this->hasOne(MemberPolicy::class, 'member_id', 'member_id')->where('status', 'active')->latestOfMany(); + return $this->hasOneThrough(CorporatePolicy::class, MemberPolicy::class, 'member_id', 'code', 'member_id', 'policy_id') + ->where('corporate_policies.start', '<', now()) + ->where('corporate_policies.end', '>', now()) + ->where('member_policies.start', '<', now()) + ->where('member_policies.end', '>', now()); + // return $this->hasOne(MemberPolicy::class, 'member_id', 'member_id')->where('status', 'active')->latestOfMany(); + } + + public function getAgeAttribute() + { + if ($this->birth_date) { + return Carbon::parse($this->birth_date)->diffInYears(now()); + } else { + return null; + } } public function getFullNameAttribute() @@ -137,6 +164,11 @@ class Member extends Model return implode(' ', $arr); } + public function getGenderCodeAttribute() + { + return $this->gender ? ($this->gender == 'female' ? 'F' : 'M') : $this->gender; + } + public function scopeFilter($query, array $filters) { $query->when($filters['search'] ?? false, function ($query, $search) { diff --git a/database/migrations/2022_11_23_140658_create_limit_journals_table.php b/database/migrations/2022_11_23_140658_create_limit_journals_table.php index ff82510a..3682ca24 100644 --- a/database/migrations/2022_11_23_140658_create_limit_journals_table.php +++ b/database/migrations/2022_11_23_140658_create_limit_journals_table.php @@ -16,7 +16,9 @@ return new class extends Migration Schema::create('limit_journals', function (Blueprint $table) { $table->id(); $table->morphs('journalable'); - $table->string('mutation'); + $table->string('previous_balance'); + $table->string('total_debit')->nullable()->comment('Should be in positive value'); + $table->string('total_credit')->nullable()->comment('Should be in negative value'); $table->string('type'); $table->string('balance'); $table->text('description'); diff --git a/frontend/client-portal/package.json b/frontend/client-portal/package.json index 0ee98044..15207f05 100755 --- a/frontend/client-portal/package.json +++ b/frontend/client-portal/package.json @@ -47,6 +47,7 @@ "@mui/lab": "5.0.0-alpha.80", "@mui/material": "^5.10.2", "@mui/system": "^5.10.2", + "@mui/utils": "^5.10.16", "@mui/x-data-grid": "^5.16.0", "@mui/x-date-pickers": "5.0.0-beta.2", "@vitejs/plugin-react": "^1.3.2", diff --git a/frontend/client-portal/pnpm-lock.yaml b/frontend/client-portal/pnpm-lock.yaml index f4c3bca4..7e4cba0c 100755 --- a/frontend/client-portal/pnpm-lock.yaml +++ b/frontend/client-portal/pnpm-lock.yaml @@ -15,6 +15,7 @@ specifiers: '@mui/lab': 5.0.0-alpha.80 '@mui/material': ^5.10.2 '@mui/system': ^5.10.2 + '@mui/utils': ^5.10.16 '@mui/x-data-grid': ^5.16.0 '@mui/x-date-pickers': 5.0.0-beta.2 '@types/lodash': ^4.14.184 @@ -85,6 +86,7 @@ dependencies: '@mui/lab': 5.0.0-alpha.80_vli2fzedtzvbon5ke6iprktoka '@mui/material': 5.10.2_mm2isjkwxtdnw3xlwl5r7b6ile '@mui/system': 5.10.2_ynexvg6j2j66sbh5giu7mkkh7u + '@mui/utils': 5.10.16_react@17.0.2 '@mui/x-data-grid': 5.16.0_r4jqxufjb3aftjrjm24vhpn4hm '@mui/x-date-pickers': 5.0.0-beta.2_y3fv7pzpxqpbmxcbzsros3kjnu '@vitejs/plugin-react': 1.3.2 @@ -1455,14 +1457,20 @@ packages: engines: {node: '>=6.9.0'} dependencies: core-js-pure: 3.25.0 - regenerator-runtime: 0.13.9 + regenerator-runtime: 0.13.11 dev: true /@babel/runtime/7.18.9: resolution: {integrity: sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==} engines: {node: '>=6.9.0'} dependencies: - regenerator-runtime: 0.13.9 + regenerator-runtime: 0.13.11 + + /@babel/runtime/7.20.6: + resolution: {integrity: sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.11 /@babel/template/7.18.10: resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} @@ -1554,7 +1562,7 @@ packages: '@babel/core': 7.18.13 '@babel/helper-module-imports': 7.18.6 '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.18.13 - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.20.6 '@emotion/hash': 0.9.0 '@emotion/memoize': 0.8.0 '@emotion/serialize': 1.1.0 @@ -1838,10 +1846,10 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.20.6 '@emotion/is-prop-valid': 1.2.0 '@mui/types': 7.1.5_@types+react@17.0.48 - '@mui/utils': 5.9.3_react@17.0.2 + '@mui/utils': 5.10.16_react@17.0.2 '@popperjs/core': 2.11.6 '@types/react': 17.0.48 clsx: 1.2.1 @@ -1862,10 +1870,10 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.20.6 '@emotion/is-prop-valid': 1.2.0 '@mui/types': 7.1.5_@types+react@17.0.48 - '@mui/utils': 5.9.3_react@17.0.2 + '@mui/utils': 5.10.16_react@17.0.2 '@popperjs/core': 2.11.6 '@types/react': 17.0.48 clsx: 1.2.1 @@ -1924,7 +1932,7 @@ packages: '@mui/base': 5.0.0-alpha.79_sk3eihvpffgp52mstba5zhq3vu '@mui/material': 5.10.2_mm2isjkwxtdnw3xlwl5r7b6ile '@mui/system': 5.10.2_ynexvg6j2j66sbh5giu7mkkh7u - '@mui/utils': 5.9.3_react@17.0.2 + '@mui/utils': 5.10.16_react@17.0.2 '@mui/x-date-pickers': 5.0.0-alpha.0_ktjudfp74mtqzmc2e56ri5vvri '@types/react': 17.0.48 clsx: 1.2.1 @@ -1964,7 +1972,7 @@ packages: '@mui/core-downloads-tracker': 5.10.2 '@mui/system': 5.10.2_ynexvg6j2j66sbh5giu7mkkh7u '@mui/types': 7.1.5_@types+react@17.0.48 - '@mui/utils': 5.9.3_react@17.0.2 + '@mui/utils': 5.10.16_react@17.0.2 '@types/react': 17.0.48 '@types/react-transition-group': 4.4.5 clsx: 1.2.1 @@ -1986,8 +1994,8 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.18.9 - '@mui/utils': 5.9.3_react@17.0.2 + '@babel/runtime': 7.20.6 + '@mui/utils': 5.10.16_react@17.0.2 '@types/react': 17.0.48 prop-types: 15.8.1 react: 17.0.2 @@ -2006,7 +2014,7 @@ packages: '@emotion/styled': optional: true dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.20.6 '@emotion/cache': 11.10.3 '@emotion/react': 11.10.0_u65opluo5sjgh3eblfliq6jsnm '@emotion/styled': 11.10.0_mpqqkyoc5j3vv2sg2f5vubqi7u @@ -2037,7 +2045,7 @@ packages: '@mui/private-theming': 5.9.3_skqlhrap4das3cz5b6iqdn2lqi '@mui/styled-engine': 5.10.2_2av45khroaevmcc27aulpaf2sy '@mui/types': 7.1.5_@types+react@17.0.48 - '@mui/utils': 5.9.3_react@17.0.2 + '@mui/utils': 5.10.16_react@17.0.2 '@types/react': 17.0.48 clsx: 1.2.1 csstype: 3.1.0 @@ -2056,13 +2064,13 @@ packages: '@types/react': 17.0.48 dev: false - /@mui/utils/5.9.3_react@17.0.2: - resolution: {integrity: sha512-l0N5bcrenE9hnwZ/jPecpIRqsDFHkPXoFUcmkgysaJwVZzJ3yQkGXB47eqmXX5yyGrSc6HksbbqXEaUya+siew==} + /@mui/utils/5.10.16_react@17.0.2: + resolution: {integrity: sha512-3MB/SGsgiiu9Z55CFmAfiONUoR7AAue/H4F6w3mc2LnhFQCsoVvXhioDPcsiRpUMIQr34jDPzGXdCuqWooPCXQ==} engines: {node: '>=12.0.0'} peerDependencies: react: ^17.0.0 || ^18.0.0 dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.20.6 '@types/prop-types': 15.7.5 '@types/react-is': 17.0.3 prop-types: 15.8.1 @@ -2082,7 +2090,7 @@ packages: '@babel/runtime': 7.18.9 '@mui/material': 5.10.2_mm2isjkwxtdnw3xlwl5r7b6ile '@mui/system': 5.10.2_ynexvg6j2j66sbh5giu7mkkh7u - '@mui/utils': 5.9.3_react@17.0.2 + '@mui/utils': 5.10.16_react@17.0.2 clsx: 1.2.1 prop-types: 15.8.1 react: 17.0.2 @@ -2117,7 +2125,7 @@ packages: '@date-io/moment': 2.15.0 '@mui/material': 5.10.2_mm2isjkwxtdnw3xlwl5r7b6ile '@mui/system': 5.10.2_ynexvg6j2j66sbh5giu7mkkh7u - '@mui/utils': 5.9.3_react@17.0.2 + '@mui/utils': 5.10.16_react@17.0.2 clsx: 1.2.1 date-fns: 2.29.2 prop-types: 15.8.1 @@ -2165,7 +2173,7 @@ packages: '@emotion/styled': 11.10.0_mpqqkyoc5j3vv2sg2f5vubqi7u '@mui/material': 5.10.2_mm2isjkwxtdnw3xlwl5r7b6ile '@mui/system': 5.10.2_ynexvg6j2j66sbh5giu7mkkh7u - '@mui/utils': 5.9.3_react@17.0.2 + '@mui/utils': 5.10.16_react@17.0.2 '@types/react-transition-group': 4.4.5 clsx: 1.2.1 date-fns: 2.29.2 @@ -2708,7 +2716,7 @@ packages: resolution: {integrity: sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==} engines: {node: '>=6.0'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.20.6 '@babel/runtime-corejs3': 7.18.9 dev: true @@ -2798,7 +2806,7 @@ packages: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.20.6 cosmiconfig: 7.0.1 resolve: 1.22.1 @@ -3192,7 +3200,7 @@ packages: /dom-helpers/5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.20.6 csstype: 3.1.0 dev: false @@ -5100,7 +5108,7 @@ packages: react: '>=16.6.0' react-dom: '>=16.6.0' dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.20.6 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 @@ -5127,13 +5135,13 @@ packages: resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} dev: true - /regenerator-runtime/0.13.9: - resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==} + /regenerator-runtime/0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} /regenerator-transform/0.15.0: resolution: {integrity: sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==} dependencies: - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.20.6 dev: true /regexp.prototype.flags/1.4.3: @@ -5846,7 +5854,7 @@ packages: '@apideck/better-ajv-errors': 0.3.6_ajv@8.11.0 '@babel/core': 7.18.13 '@babel/preset-env': 7.18.10_@babel+core@7.18.13 - '@babel/runtime': 7.18.9 + '@babel/runtime': 7.20.6 '@rollup/plugin-babel': 5.3.1_2uin6pbxavst3oir53roxbd5qi '@rollup/plugin-node-resolve': 11.2.1_rollup@2.78.1 '@rollup/plugin-replace': 2.4.2_rollup@2.78.1 diff --git a/frontend/dashboard/src/components/dialogs/MemberSelectDialog.tsx b/frontend/dashboard/src/components/dialogs/MemberSelectDialog.tsx index 3d336714..3d1662af 100644 --- a/frontend/dashboard/src/components/dialogs/MemberSelectDialog.tsx +++ b/frontend/dashboard/src/components/dialogs/MemberSelectDialog.tsx @@ -251,7 +251,7 @@ export default function MemberSelectDialog({ const getContent = () => (
- + (null); const NewClaimSchema = Yup.object().shape({ - name: Yup.string().required('Name is required'), - diagnosis_id: Yup.string().required('Diagnosis is required'), - total_claim: Yup.string().required('Total Claim is required'), + member_id: Yup.string().required('Please select Member'), + total_claim: Yup.number().typeError('Claim should be a number').min(1, 'Claim cannot 0').required('Total Claim is required'), + diagnosis: Yup.object().required('Choose Diagnosis'), + benefit: Yup.object().required('Please Select Benefit') }); const defaultValues = useMemo( () => ({ - name: '', + member_id: null, + benefit_id: null, diagnosis_id: null, total_claim: 0, + benefit: null }), [] ); @@ -50,13 +57,41 @@ export default function Create() { } = methods; const onSubmit = async (data: any) => { - console.log(data); + axios.post('claims', getValues()) + .then(function(res) { + console.log('SUCCESS', res) + enqueueSnackbar('Success Creating Claim', { variant: 'success' }) + navigate('/claims'); + }) + .catch(function (err) { + console.log('ERROR CUK', err.data) + enqueueSnackbar('Failed Creating Claim', { variant: 'error' }) + }) }; + const [memberBenefits, setMemberBenefits] = useState([]); + const getMemberBenefits = (member) => { + axios.get(`members/${member.id}/benefits`) + .then( (res) => { + setMemberBenefits(res.data); + }) + .catch( (err) => { + enqueueSnackbar('Failed getting member benefits', { variant: 'error' }) + }) + } + const [isMemberDialogOpen, setIsMemberDialogOpen] = useState(false); const memberSelected = (selectedMember: any) => { + // Reset Selected Benefit + setMemberBenefits([]); + setValue('benefit_id', null); + setValue('benefit', null); + setMember(selectedMember); + setValue('member_id', selectedMember.id) + + getMemberBenefits(selectedMember) }; const [diagnosis, setDiagnosis] = useState([]); @@ -76,16 +111,12 @@ export default function Create() { }, []) - const [isEligible, setIsEligible] = useState(false) - - useEffect(() => { - setIsEligible(false) - console.log('member change') - }, [member]) + const [isEligible, setIsEligible] = useState(null) const [isCheckingLimit, setIsCheckingLimit] = useState(false) const checkLimit = (event) => { event.preventDefault(); + console.log(getValues('diagnosis_id')) if (!member || !getValues('diagnosis_id')) { enqueueSnackbar('Please Check the Data', { variant: 'error' }) @@ -109,6 +140,10 @@ export default function Create() { setIsCheckingLimit(false) }) } + + const headStyle = { + fontWeight: 'bold' + }; return ( @@ -136,41 +171,115 @@ export default function Create() { Member - - + {setIsMemberDialogOpen(true)}} /> - + {/* - + */} { member && ( -
- Plan : {JSON.stringify(member)} -
-
- Benefit : -
-
- Another : -
+ + + + + + Name + {member.full_name} + + + DOB + {member.birth_date} ({member.age + ' years'}) + + + Marital Status + {member.marital_status} + + + Record Type + {member.record_type} + + + Principal ID + {member.principal_id} ({member.relation_with_principal}) + + +
+
+ + + + + Plan + {member.current_plan.code} + + + Active + {member.current_plan.start} - {member.current_plan.end} (Active) + + + Corporate Limit + {fCurrency(0)} / {fCurrency(member.current_plan.limit_rules)} + + + Plan Usage + {fCurrency(0)} / {fCurrency(member.current_plan.limit_rules)} + + +
+
+
)} - + + ( + + option ? `#${option.id} (${option.code}) ${option.description}` : '' + } + value={value || ''} + onChange={(event: any, newValue: any) => { + setValue('benefit_id', newValue?.id) + onChange(newValue); + }} + renderInput={(params) => ( + { + // if (event.key === 'Enter') + // searchDiagnosis(event.target.value) + // }} + /> + )} + /> + )} + /> + { setValue('diagnosis_id', newValue?.id) + // setValue('diagnosis', newValue) onChange(newValue); }} renderInput={(params) => ( - { - searchDiagnosis(event.target.value) + onKeyPress={(event) => { + if (event.key === 'Enter') + searchDiagnosis(event.target.value) }} /> )} @@ -200,10 +312,86 @@ export default function Create() { )} /> + { isCheckingLimit && ( + + {/* Checking */} + + + + Please Wait, Checking Eligibilty + + + + )} + { false && isCheckingLimit == false && isEligible == null && ( + + {/* No Data Selected */} + + + + Please Select Diagnosis ! + + + + )} + { (!isCheckingLimit && isEligible !== null) && isEligible && ( + + {/* Eligible */} + + + + Diagnosis is Eligible + + + + 125.000.000 / 125.000.000 + + + )} + { (!isCheckingLimit && isEligible !== null) && !isEligible && ( + + {/* Not Eligible */} + + + + Not Eligible + + + + 125.000.000 / 125.000.000 + + + )} + + + + + Create Claim + { isEligible === true ? ( - + Create Claim ) : ( diff --git a/frontend/dashboard/src/pages/Claims/Index.tsx b/frontend/dashboard/src/pages/Claims/Index.tsx index 0c5ba319..15c2d7d8 100755 --- a/frontend/dashboard/src/pages/Claims/Index.tsx +++ b/frontend/dashboard/src/pages/Claims/Index.tsx @@ -14,6 +14,7 @@ export default function Claims() { {row.code} - {row.member.full_name} - {row.plan.code} - {row.benefit.code} - ({row.diagnosis.code}) {row.diagnosis.name} + {row.member?.full_name} + {row.plan?.code} + {row.benefit?.code} + ({row.diagnosis?.code}) {row.diagnosis?.name} {fCurrency(row.total_claim)} {/* */}