From 2215f61db4f8dae15e21bd90832fcfae8cbd1ef5 Mon Sep 17 00:00:00 2001 From: R Date: Thu, 1 Sep 2022 16:03:52 +0700 Subject: [PATCH] Parent Corporate --- .../Controllers/Api/CorporateController.php | 44 ++++++---- app/Models/Corporate.php | 12 +++ ...2_06_16_045414_create_corporates_table.php | 2 + database/seeders/DatabaseSeeder.php | 5 +- frontend/dashboard/index.html | 2 +- frontend/dashboard/package.json | 2 + frontend/dashboard/pnpm-lock.yaml | 80 +++++++++++++++++++ .../dashboard/src/pages/Corporates/Form.tsx | 62 +++++++++++++- .../src/pages/Corporates/Formularium/List.tsx | 2 +- 9 files changed, 190 insertions(+), 21 deletions(-) diff --git a/Modules/Internal/Http/Controllers/Api/CorporateController.php b/Modules/Internal/Http/Controllers/Api/CorporateController.php index 42e09651..2a83db60 100644 --- a/Modules/Internal/Http/Controllers/Api/CorporateController.php +++ b/Modules/Internal/Http/Controllers/Api/CorporateController.php @@ -34,8 +34,10 @@ class CorporateController extends Controller ->withCount([ 'employees', 'corporatePlans', - 'corporateBenefits' + 'corporateBenefits', + 'subCorporates' ]) + ->where('type', 'corporate') ->paginate(10); return $corporates; @@ -47,7 +49,16 @@ class CorporateController extends Controller */ public function create() { - return view('internal::create'); + $corporateGroups = Corporate::whereNull('parent_id')->get()->map(function($corporate) { + return [ + 'value' => $corporate->id, + 'label' => $corporate->name, + ]; + }); + + return response()->json([ + 'corporate_groups' => $corporateGroups + ]); } /** @@ -75,19 +86,22 @@ class CorporateController extends Controller DB::beginTransaction(); $newCorporate = Corporate::create($request->all()); - $newCorporate->policies()->create([ - 'code' => $request->policy_code ?? NULL, - 'total_premi' => $request->policy_total_premi ?? NULL, - 'minimal_deposit_percentage' => $request->policy_minimal_deposit_percentage ?? NULL, - 'minimal_deposit_net' => $request->policy_minimal_deposit_net ?? NULL, - 'minimal_alert_percentage' => $request->policy_minimal_alert_percentage ?? NULL, - 'minimal_alert_net' => $request->policy_minimal_alert_net ?? NULL, - 'minimal_stop_service_percentage' => $request->policy_stop_service_percentage ?? NULL, - 'minimal_stop_service_net' => $request->policy_stop_service_net ?? NULL, - 'start' => $request->policy_start ?? NULL, - 'end' => $request->policy_end ?? NULL, - 'active' => $request->policy_active ?? true, - ]); + if ($request->has('policy_code') && !empty($request->policy_code)) { + // dd($request->policy_code, 'fuck you'); + $newCorporate->policies()->create([ + 'code' => $request->policy_code ?? NULL, + 'total_premi' => $request->policy_total_premi ?? NULL, + 'minimal_deposit_percentage' => $request->policy_minimal_deposit_percentage ?? NULL, + 'minimal_deposit_net' => $request->policy_minimal_deposit_net ?? NULL, + 'minimal_alert_percentage' => $request->policy_minimal_alert_percentage ?? NULL, + 'minimal_alert_net' => $request->policy_minimal_alert_net ?? NULL, + 'minimal_stop_service_percentage' => $request->policy_stop_service_percentage ?? NULL, + 'minimal_stop_service_net' => $request->policy_stop_service_net ?? NULL, + 'start' => $request->policy_start ?? NULL, + 'end' => $request->policy_end ?? NULL, + 'active' => $request->policy_active ?? true, + ]); + } DB::commit(); } catch (\Exception $e) { diff --git a/app/Models/Corporate.php b/app/Models/Corporate.php index 7014f21e..561af4a6 100644 --- a/app/Models/Corporate.php +++ b/app/Models/Corporate.php @@ -12,6 +12,8 @@ class Corporate extends Model use HasFactory, SoftDeletes, Blameable; protected $fillable = [ + 'type', + 'parent_id', 'code', 'name', 'welcome_message', @@ -89,4 +91,14 @@ class Corporate extends Model { return $this->hasMany(CorporateService::class, 'corporate_id'); } + + public function parent() + { + return $this->belongsTo(Corporate::class, 'parent_id'); + } + + public function subCorporates() + { + return $this->hasMany(Corporate::class, 'parent_id'); + } } diff --git a/database/migrations/2022_06_16_045414_create_corporates_table.php b/database/migrations/2022_06_16_045414_create_corporates_table.php index 3ec14ab8..4cb97f2c 100644 --- a/database/migrations/2022_06_16_045414_create_corporates_table.php +++ b/database/migrations/2022_06_16_045414_create_corporates_table.php @@ -15,6 +15,8 @@ return new class extends Migration { Schema::create('corporates', function (Blueprint $table) { $table->id(); + $table->string('type')->nullable(); + $table->foreignId('parent_id')->nullable(); $table->string('code'); $table->string('name')->nullable(); $table->text('welcome_message')->nullable(); diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 50983d57..4e971203 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -18,7 +18,10 @@ class DatabaseSeeder extends Seeder $this->call([ DummyMemberSeeder::class, - DummyCorporateSeeder::class + DrugSeeder::class, + IcdSeeder::class, + ServiceSeeder::class, + SpecialitiesSeeder::class, ]); } } diff --git a/frontend/dashboard/index.html b/frontend/dashboard/index.html index ee283328..3be7fb7d 100644 --- a/frontend/dashboard/index.html +++ b/frontend/dashboard/index.html @@ -19,7 +19,7 @@ - Minimal UI Kit + Dashboard diff --git a/frontend/dashboard/package.json b/frontend/dashboard/package.json index 9e818e9f..5b8b3314 100644 --- a/frontend/dashboard/package.json +++ b/frontend/dashboard/package.json @@ -50,6 +50,7 @@ "@mui/x-data-grid": "^5.14.0", "@mui/x-date-pickers": "5.0.0-beta.2", "@vitejs/plugin-react": "^1.3.2", + "apexcharts": "^3.35.5", "axios": "^0.27.2", "change-case": "^4.1.2", "csstype": "^3.1.0", @@ -63,6 +64,7 @@ "nprogress": "^0.2.0", "numeral": "^2.0.6", "react": "^17.0.2", + "react-apexcharts": "^1.4.0", "react-dom": "^17.0.2", "react-dropzone": "^14.2.2", "react-helmet-async": "^1.3.0", diff --git a/frontend/dashboard/pnpm-lock.yaml b/frontend/dashboard/pnpm-lock.yaml index 2cbd89c1..5eaf3fb5 100644 --- a/frontend/dashboard/pnpm-lock.yaml +++ b/frontend/dashboard/pnpm-lock.yaml @@ -26,6 +26,7 @@ specifiers: '@typescript-eslint/eslint-plugin': ^5.30.7 '@typescript-eslint/parser': ^5.30.7 '@vitejs/plugin-react': ^1.3.2 + apexcharts: ^3.35.5 axios: ^0.27.2 change-case: ^4.1.2 csstype: ^3.1.0 @@ -52,6 +53,7 @@ specifiers: numeral: ^2.0.6 prettier: ^2.7.1 react: ^17.0.2 + react-apexcharts: ^1.4.0 react-dom: ^17.0.2 react-dropzone: ^14.2.2 react-helmet-async: ^1.3.0 @@ -85,6 +87,7 @@ dependencies: '@mui/x-data-grid': 5.14.0_jme7ixtmk52br6jr4ylfw5kcgy '@mui/x-date-pickers': 5.0.0-beta.2_ehiw5wpabbvfr6l3cdf73755vi '@vitejs/plugin-react': 1.3.2 + apexcharts: 3.35.5 axios: 0.27.2 change-case: 4.1.2 csstype: 3.1.0 @@ -98,6 +101,7 @@ dependencies: nprogress: 0.2.0 numeral: 2.0.6 react: 17.0.2 + react-apexcharts: 1.4.0_vi3rbmehlu6egtlq2bz7addea4 react-dom: 17.0.2_react@17.0.2 react-dropzone: 14.2.2_react@17.0.2 react-helmet-async: 1.3.0_sfoxds7t5ydpegc3knd667wn6m @@ -2661,6 +2665,17 @@ packages: color-convert: 2.0.1 dev: true + /apexcharts/3.35.5: + resolution: {integrity: sha512-Bi3aq35xWntI71JlywXTBBAOhuKTbB4wijKw4ClkIAFV904YDkHPIJ8N9LcZq9fvVb0VX1AEmyOFBOB2Vwsuew==} + dependencies: + svg.draggable.js: 2.2.2 + svg.easing.js: 2.0.0 + svg.filter.js: 2.0.2 + svg.pathmorphing.js: 0.1.3 + svg.resize.js: 1.4.3 + svg.select.js: 3.0.1 + dev: false + /argparse/2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true @@ -4925,6 +4940,17 @@ packages: safe-buffer: 5.2.1 dev: true + /react-apexcharts/1.4.0_vi3rbmehlu6egtlq2bz7addea4: + resolution: {integrity: sha512-DrcMV4aAMrUG+n6412yzyATWEyCDWlpPBBhVbpzBC4PDeuYU6iF84SmExbck+jx5MUm4U5PM3/T307Mc3kzc9Q==} + peerDependencies: + apexcharts: ^3.18.0 + react: '>=0.13' + dependencies: + apexcharts: 3.35.5 + prop-types: 15.8.1 + react: 17.0.2 + dev: false + /react-dom/17.0.2_react@17.0.2: resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==} peerDependencies: @@ -5444,6 +5470,60 @@ packages: resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} dev: false + /svg.draggable.js/2.2.2: + resolution: {integrity: sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==} + engines: {node: '>= 0.8.0'} + dependencies: + svg.js: 2.7.1 + dev: false + + /svg.easing.js/2.0.0: + resolution: {integrity: sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==} + engines: {node: '>= 0.8.0'} + dependencies: + svg.js: 2.7.1 + dev: false + + /svg.filter.js/2.0.2: + resolution: {integrity: sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==} + engines: {node: '>= 0.8.0'} + dependencies: + svg.js: 2.7.1 + dev: false + + /svg.js/2.7.1: + resolution: {integrity: sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==} + dev: false + + /svg.pathmorphing.js/0.1.3: + resolution: {integrity: sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==} + engines: {node: '>= 0.8.0'} + dependencies: + svg.js: 2.7.1 + dev: false + + /svg.resize.js/1.4.3: + resolution: {integrity: sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==} + engines: {node: '>= 0.8.0'} + dependencies: + svg.js: 2.7.1 + svg.select.js: 2.1.2 + dev: false + + /svg.select.js/2.1.2: + resolution: {integrity: sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==} + engines: {node: '>= 0.8.0'} + dependencies: + svg.js: 2.7.1 + dev: false + + /svg.select.js/3.0.1: + resolution: {integrity: sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==} + engines: {node: '>= 0.8.0'} + dependencies: + svg.js: 2.7.1 + dev: false + /temp-dir/2.0.0: resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} engines: {node: '>=8'} diff --git a/frontend/dashboard/src/pages/Corporates/Form.tsx b/frontend/dashboard/src/pages/Corporates/Form.tsx index f6a02a4e..6942d5fd 100644 --- a/frontend/dashboard/src/pages/Corporates/Form.tsx +++ b/frontend/dashboard/src/pages/Corporates/Form.tsx @@ -3,7 +3,7 @@ import { useSnackbar } from 'notistack'; import { useNavigate } from 'react-router-dom'; import { useCallback, useEffect, useMemo, useState } from 'react'; // form -import { useForm } from 'react-hook-form'; +import { Controller, useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; // @mui import { styled } from '@mui/material/styles'; @@ -11,8 +11,15 @@ import { LoadingButton } from '@mui/lab'; import { Box, Card, + FormControl, FormHelperText, Grid, + InputLabel, + Menu, + MenuItem, + OutlinedInput, + Select, + SelectChangeEvent, Stack, Typography, } from '@mui/material'; @@ -29,6 +36,7 @@ import { RHFMultiCheckbox, RHFCheckbox, RHFCustomMultiCheckbox, + RHFSelect, } from '../../components/hook-form'; import { Corporate } from '../../@types/corporates'; import axios from '../../utils/axios'; @@ -52,6 +60,7 @@ type Props = { export default function CorporateForm({ isEdit, currentCorporate }: Props) { const navigate = useNavigate(); + const [corporate_groups, setCorporateGroups] = useState([]) // const [ errors, setErrors ] = useState<{ [key: string]: string }>({}); @@ -61,6 +70,11 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) { name: Yup.string().required('Name is required'), code: Yup.string().required('Corporate Code is required'), active: Yup.boolean().required('Corporate Status is required'), + type: Yup.string().required('Type is required'), + parent_id: Yup.string().when("type", { + is: 'subcorporate', + then: Yup.string().required("Corporate is required because type is Sub Corporate") + }) }); const defaultValues = useMemo( @@ -82,6 +96,7 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) { policy_start: currentCorporate?.current_policy?.start || '', policy_end: currentCorporate?.current_policy?.end || '', linking_rules: currentCorporate?.linking_rules || ['nrik', 'nik', 'member_id'], + type: currentCorporate?.type || 'corporate' }), // eslint-disable-next-line react-hooks/exhaustive-deps [currentCorporate] @@ -113,6 +128,14 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) { reset(defaultValues); } + axios.get('/corporates/create') + .then((res) => { + setCorporateGroups(res.data.corporate_groups) + }) + .catch((err) => { + enqueueSnackbar("Opps, failed to get Corporate Group List", "error") + }) + // eslint-disable-next-line react-hooks/exhaustive-deps }, [isEdit, currentCorporate]); @@ -222,6 +245,20 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) { "label" : "E-Mail" }, ] + + const types = [ + { + "value" : "corporate", + "label" : "Corporate" + }, + { + "value" : "subcorporate", + "label" : "Sub Corporate" + }, + ] + const handleTypeChange = (event: SelectChangeEvent) => { + setValue('type', event.target.value) + } return ( @@ -232,6 +269,25 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) { Corporate Profile + + + + ))} + + + {/* // TODO Use Autocomplete */} + {( values.type == 'subcorporate' && + + ))} + )} @@ -290,7 +346,7 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) { - + {( values.type == 'corporate' && {/* Policy Detail */} @@ -354,7 +410,7 @@ export default function CorporateForm({ isEdit, currentCorporate }: Props) { - + )} diff --git a/frontend/dashboard/src/pages/Corporates/Formularium/List.tsx b/frontend/dashboard/src/pages/Corporates/Formularium/List.tsx index 9f171f66..64bc80c2 100644 --- a/frontend/dashboard/src/pages/Corporates/Formularium/List.tsx +++ b/frontend/dashboard/src/pages/Corporates/Formularium/List.tsx @@ -116,7 +116,7 @@ export default function PlanList() { } const handleInactiveAction = (formularium : any) => { - enqueueSnackbar('Fuck yuo'), { variant: 'error' }); + enqueueSnackbar('Fuck yuo'), { variant: 'error' }; axios .put('/corporates/'+corporate_id+'/formulariums/'+formularium.id+'/activate') .then(() => {