diff --git a/electron/decoder/constants.js b/electron/decoder/constants.js index a371c13..9b6963c 100644 --- a/electron/decoder/constants.js +++ b/electron/decoder/constants.js @@ -19,13 +19,13 @@ function ChangeOfRuleSet({ const prevRuleSet = RuleSets.find( (r) => prevDateMoment.isSameOrAfter(r.range[0]) && - prevDateMoment.isSameOrBefore(r.range[1]) + prevDateMoment.isBefore(r.range[1]) ); const newRuleSet = RuleSets.find( (r) => newDateMoment.isSameOrAfter(r.range[0]) && - newDateMoment.isSameOrBefore(r.range[1]) + newDateMoment.isBefore(r.range[1]) ); return prevRuleSet?.title !== newRuleSet?.title; @@ -35,8 +35,7 @@ function WhichRulesetToApply(close_date) { const DateMoment = moment(close_date); const newRuleSet = RuleSets.find( (r) => - DateMoment.isSameOrAfter(r.range[0]) && - DateMoment.isSameOrBefore(r.range[1]) + DateMoment.isSameOrAfter(r.range[0]) && DateMoment.isBefore(r.range[1]) ); console.log("Using ruleset:", newRuleSet); diff --git a/hasura/metadata/databases/default/tables/public_targets.yaml b/hasura/metadata/databases/default/tables/public_targets.yaml new file mode 100644 index 0000000..b1ca38d --- /dev/null +++ b/hasura/metadata/databases/default/tables/public_targets.yaml @@ -0,0 +1,19 @@ +table: + name: targets + schema: public +select_permissions: + - role: user + permission: + columns: + - effective_date + - end_date + - ageGte + - ageLt + - target + - group + - ins_co + - name + - created_at + - updated_at + - id + filter: {} diff --git a/hasura/metadata/databases/default/tables/tables.yaml b/hasura/metadata/databases/default/tables/tables.yaml index 154b182..f56e07a 100644 --- a/hasura/metadata/databases/default/tables/tables.yaml +++ b/hasura/metadata/databases/default/tables/tables.yaml @@ -4,5 +4,6 @@ - "!include public_joblines.yaml" - "!include public_jobs.yaml" - "!include public_notifications.yaml" +- "!include public_targets.yaml" - "!include public_users.yaml" - "!include public_veh_groups.yaml" diff --git a/hasura/metadata/metrics_config.yaml b/hasura/metadata/metrics_config.yaml new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/hasura/metadata/metrics_config.yaml @@ -0,0 +1 @@ +{} diff --git a/hasura/migrations/default/1676488105185_create_table_public_targets/down.sql b/hasura/migrations/default/1676488105185_create_table_public_targets/down.sql new file mode 100644 index 0000000..533e37c --- /dev/null +++ b/hasura/migrations/default/1676488105185_create_table_public_targets/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."targets"; diff --git a/hasura/migrations/default/1676488105185_create_table_public_targets/up.sql b/hasura/migrations/default/1676488105185_create_table_public_targets/up.sql new file mode 100644 index 0000000..3fb758a --- /dev/null +++ b/hasura/migrations/default/1676488105185_create_table_public_targets/up.sql @@ -0,0 +1,17 @@ +CREATE TABLE "public"."targets" ("id" uuid NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), "ins_co" text NOT NULL, "name" text NOT NULL, "group" text NOT NULL, "effective_date" date NOT NULL, "end_date" date, "ageLt" numeric NOT NULL, "ageGte" numeric NOT NULL, "target" numeric NOT NULL, PRIMARY KEY ("id") , UNIQUE ("id")); +CREATE OR REPLACE FUNCTION "public"."set_current_timestamp_updated_at"() +RETURNS TRIGGER AS $$ +DECLARE + _new record; +BEGIN + _new := NEW; + _new."updated_at" = NOW(); + RETURN _new; +END; +$$ LANGUAGE plpgsql; +CREATE TRIGGER "set_public_targets_updated_at" +BEFORE UPDATE ON "public"."targets" +FOR EACH ROW +EXECUTE PROCEDURE "public"."set_current_timestamp_updated_at"(); +COMMENT ON TRIGGER "set_public_targets_updated_at" ON "public"."targets" +IS 'trigger to set value of column "updated_at" to current timestamp on row update'; diff --git a/hasura/migrations/default/1676488620153_alter_table_public_targets_alter_column_ageLt/down.sql b/hasura/migrations/default/1676488620153_alter_table_public_targets_alter_column_ageLt/down.sql new file mode 100644 index 0000000..6bc23db --- /dev/null +++ b/hasura/migrations/default/1676488620153_alter_table_public_targets_alter_column_ageLt/down.sql @@ -0,0 +1 @@ +alter table "public"."targets" alter column "ageLt" set not null; diff --git a/hasura/migrations/default/1676488620153_alter_table_public_targets_alter_column_ageLt/up.sql b/hasura/migrations/default/1676488620153_alter_table_public_targets_alter_column_ageLt/up.sql new file mode 100644 index 0000000..bc9369c --- /dev/null +++ b/hasura/migrations/default/1676488620153_alter_table_public_targets_alter_column_ageLt/up.sql @@ -0,0 +1 @@ +alter table "public"."targets" alter column "ageLt" drop not null; diff --git a/hasura/migrations/default/1676488728163_alter_table_public_targets_alter_column_id/down.sql b/hasura/migrations/default/1676488728163_alter_table_public_targets_alter_column_id/down.sql new file mode 100644 index 0000000..ed5819e --- /dev/null +++ b/hasura/migrations/default/1676488728163_alter_table_public_targets_alter_column_id/down.sql @@ -0,0 +1 @@ +ALTER TABLE "public"."targets" ALTER COLUMN "id" drop default; diff --git a/hasura/migrations/default/1676488728163_alter_table_public_targets_alter_column_id/up.sql b/hasura/migrations/default/1676488728163_alter_table_public_targets_alter_column_id/up.sql new file mode 100644 index 0000000..3d9904a --- /dev/null +++ b/hasura/migrations/default/1676488728163_alter_table_public_targets_alter_column_id/up.sql @@ -0,0 +1 @@ +alter table "public"."targets" alter column "id" set default gen_random_uuid(); diff --git a/src/components/molecules/shop-settings-form/shop-settings-form.molecule.jsx b/src/components/molecules/shop-settings-form/shop-settings-form.molecule.jsx index 173a4d8..5eed2e9 100644 --- a/src/components/molecules/shop-settings-form/shop-settings-form.molecule.jsx +++ b/src/components/molecules/shop-settings-form/shop-settings-form.molecule.jsx @@ -1,4 +1,3 @@ -import { DeleteFilled } from "@ant-design/icons"; import { Button, Form, @@ -6,10 +5,9 @@ import { InputNumber, Popconfirm, Select, - Typography, + Typography } from "antd"; import React, { useState } from "react"; -import FormListMoveArrows from "../../atoms/form-list-move-arrows/form-list-move-arrows.atom"; import LayoutFormRow from "../../atoms/layout-form-row/layout-form-row.atom"; export default function ShopSettingsFormMolecule({ form, saveLoading }) { @@ -57,19 +55,6 @@ export default function ShopSettingsFormMolecule({ form, saveLoading }) { > - - Group Definitions - - {(fields, { add, remove, move }) => { - return ( -
- {fields.map((field, index) => ( - - - - - - - - - - - - - - - - - -
- { - remove(field.name); - }} - /> - -
-
-
- ))} - - - -
- ); - }} -
+ ); } diff --git a/src/components/organisms/jobs-detail/jobs-detail.organism.jsx b/src/components/organisms/jobs-detail/jobs-detail.organism.jsx index 4c67bc6..29c7864 100644 --- a/src/components/organisms/jobs-detail/jobs-detail.organism.jsx +++ b/src/components/organisms/jobs-detail/jobs-detail.organism.jsx @@ -33,6 +33,7 @@ export function JobsDetailOrganism({ selectedJobId, setSelectedJobTargetPc }) { setSelectedJobTargetPc({ group: data.jobs_by_pk && data.jobs_by_pk.group, v_age: data.jobs_by_pk && data.jobs_by_pk.v_age, + close_date: data.jobs_by_pk && data.jobs_by_pk.close_date, }); }, [data, setSelectedJobTargetPc]); diff --git a/src/graphql/bodyshop.queries.js b/src/graphql/bodyshop.queries.js index 8ab325c..d19b207 100644 --- a/src/graphql/bodyshop.queries.js +++ b/src/graphql/bodyshop.queries.js @@ -9,6 +9,17 @@ export const QUERY_BODYSHOP = gql` groups ppd_diff_alert } + targets { + id + ins_co + name + group + ageLt + ageGte + target + effective_date + end_date + } } `; @@ -16,7 +27,7 @@ export const UPDATE_SHOP = gql` mutation UPDATE_SHOP($id: uuid, $shop: bodyshops_set_input!) { update_bodyshops(where: { id: { _eq: $id } }, _set: $shop) { returning { - id + id shopname targets accepted_ins_co diff --git a/src/redux/application/application.actions.js b/src/redux/application/application.actions.js index e38f2b8..f2b54e7 100644 --- a/src/redux/application/application.actions.js +++ b/src/redux/application/application.actions.js @@ -29,9 +29,9 @@ export const setSelectedJobId = (jobId) => ({ type: ApplicationActionTypes.SET_SELECTED_JOB_ID, payload: jobId, }); -export const setSelectedJobTargetPc = ({ group, v_age }) => ({ +export const setSelectedJobTargetPc = ({ group, v_age,close_date }) => ({ type: ApplicationActionTypes.SET_SELECTED_JOB_TARGET_PC, - payload: { group, v_age }, + payload: { group, v_age, close_date }, }); export const setSelectedJobTargetPcSuccess = (pct) => ({ diff --git a/src/redux/application/application.sagas.js b/src/redux/application/application.sagas.js index c56bb37..849e0f5 100644 --- a/src/redux/application/application.sagas.js +++ b/src/redux/application/application.sagas.js @@ -10,10 +10,10 @@ export function* onSetTargetPc() { ); } export function* CalculateTarget({ payload }) { - const { group, v_age } = payload; + const { group, v_age, close_date } = payload; const targets = yield select((state) => state.user.bodyshop.targets); - yield put(setSelectedJobTargetPcSuccess(GetJobTarget(group, v_age, targets))); + yield put(setSelectedJobTargetPcSuccess(GetJobTarget({group, v_age, targets, close_date}))); // const targetsForGroup = targets.filter((t) => t.group === group); // if (!targetsForGroup) return 0; // const targetPc = targetsForGroup.filter( diff --git a/src/redux/reporting/reporting.sagas.js b/src/redux/reporting/reporting.sagas.js index 0c9677b..20202ea 100644 --- a/src/redux/reporting/reporting.sagas.js +++ b/src/redux/reporting/reporting.sagas.js @@ -109,7 +109,7 @@ export function* handleCalculateScoreCard({ payload: jobs }) { jobRpsDollars, true ); - const jobTarget = GetJobTarget(job.group, job.v_age, targets); + const jobTarget = GetJobTarget({group:job.group, v_age:job.v_age, targets,close_date: job.close_date}); scoreCard.shopRpsTotalDollars = scoreCard.shopRpsTotalDollars.add( jobRpsDollars ); diff --git a/src/redux/user/user.actions.js b/src/redux/user/user.actions.js index db83b3e..86806df 100644 --- a/src/redux/user/user.actions.js +++ b/src/redux/user/user.actions.js @@ -53,6 +53,10 @@ export const setBodyshop = (bodyshop) => ({ type: UserActionTypes.SET_SHOP_DETAILS, payload: bodyshop, }); +export const setTargets = (targets) => ({ + type: UserActionTypes.SET_TARGETS, + payload: targets, +}); export const setLocalFingerprint = (fingerprint) => ({ type: UserActionTypes.SET_LOCAL_FINGERPRINT, diff --git a/src/redux/user/user.reducer.js b/src/redux/user/user.reducer.js index 0c46460..3556742 100644 --- a/src/redux/user/user.reducer.js +++ b/src/redux/user/user.reducer.js @@ -6,6 +6,7 @@ const INITIAL_STATE = { //language: "en-US" }, bodyshop: null, + targets: null, fingerprint: null, error: null, conflict: false, @@ -20,6 +21,8 @@ const INITIAL_STATE = { const userReducer = (state = INITIAL_STATE, action) => { switch (action.type) { + case UserActionTypes.SET_TARGETS: + return { ...state, targets: action.payload }; case UserActionTypes.SET_NOTIFICATIONS: return { ...state, notifications: action.payload }; case UserActionTypes.SET_SHOP_DETAILS: diff --git a/src/redux/user/user.sagas.js b/src/redux/user/user.sagas.js index df43a64..763a548 100644 --- a/src/redux/user/user.sagas.js +++ b/src/redux/user/user.sagas.js @@ -5,24 +5,28 @@ import { all, call, delay, put, takeLatest } from "redux-saga/effects"; import { auth, getCurrentUser, - updateCurrentUser + updateCurrentUser, } from "../../firebase/firebase.utils"; import { QUERY_BODYSHOP, - QUERY_NOTIFICATIONS + QUERY_NOTIFICATIONS, } from "../../graphql/bodyshop.queries"; import client from "../../graphql/GraphQLClient"; import { UPSERT_USER } from "../../graphql/user.queries"; import ipcTypes from "../../ipc.types"; import { - checkForNotification, sendPasswordResetFailure, + checkForNotification, + sendPasswordResetFailure, sendPasswordResetSuccess, - setBodyshop, setNotification, signInFailure, + setBodyshop, + setNotification, + setTargets, + signInFailure, signInSuccess, signOutFailure, signOutSuccess, unauthorizedUser, - updateUserDetailsSuccess + updateUserDetailsSuccess, } from "./user.actions"; import UserActionTypes from "./user.types"; @@ -153,6 +157,12 @@ export function* signInSuccessSaga({ payload }) { console.log("No bodyshop has been associated."); yield put(setBodyshop(false)); } + if (shop.data.targets.length > 0) { + yield put(setTargets(shop.data.targets)); + } else { + console.log("No bodyshop has been associated."); + yield put(setTargets(null)); + } // LogRocket.identify(payload.email); // if (!payload.email.includes("@imex.")) yield put(setInstanceId(payload.uid)); // yield logImEXEvent("redux_sign_in_success"); @@ -177,7 +187,7 @@ export function* checkForNotificationSaga() { } yield delay(4 * 60 * 60 * 1000); yield put(checkForNotification()); -} +} export function* onSendPasswordResetStart() { yield takeLatest( diff --git a/src/redux/user/user.types.js b/src/redux/user/user.types.js index a007723..54b5486 100644 --- a/src/redux/user/user.types.js +++ b/src/redux/user/user.types.js @@ -29,5 +29,6 @@ const UserActionTypes = { SET_AUTH_LEVEL: "SET_AUTH_LEVEL", CHECK_FOR_NOTIFICATION: "CHECK_FOR_NOTIFICATION", SET_NOTIFICATIONS: "SET_NOTIFICATIONS", + SET_TARGETS: "SET_TARGETS", }; -export default UserActionTypes; +export default UserActionTypes; diff --git a/src/util/GetJobTarget.js b/src/util/GetJobTarget.js index df93f1a..61a949f 100644 --- a/src/util/GetJobTarget.js +++ b/src/util/GetJobTarget.js @@ -1,11 +1,39 @@ -export default function GetJobTarget(group, v_age, targets) { - const targetsForGroup = targets.filter((t) => t.group === group); - if (!targetsForGroup) return 0; - const targetPc = targetsForGroup.filter( +import { store } from "../redux/store"; +import { WhichRulesetToApply } from "./constants"; + +export default function GetJobTarget({ group, v_age, targets, close_date }) { + // //Old Validation + // const targetsForGroup = targets.filter((t) => t.group === group); + // console.log( + // "🚀 ~ file: GetJobTarget.js:7 ~ GetJobTarget ~ targetsForGroup", + // targetsForGroup + // ); + // if (!targetsForGroup) { + // console.log("Result:", 0); + // } + // const targetPc = targetsForGroup.filter( + // (t) => t.ageGte <= v_age && (t.ageLt ? t.ageLt > v_age : true) + // ); + // if (targetPc.length === 0) console.log("Result:", 1); + // else if (targetPc.length === 1) console.log("Result: ", targetPc[0].target); + // else { + // console.log("Result:", 1); + // } + + //V2 Check + const newTargets = store.getState().user.targets; + const rulesToApply = WhichRulesetToApply(close_date); + const newTargetsForGroup = newTargets.filter( + (t) => t.name === rulesToApply && t.group === group + ); + + if (!newTargetsForGroup) return 0; + const newTargetPc = newTargetsForGroup.filter( (t) => t.ageGte <= v_age && (t.ageLt ? t.ageLt > v_age : true) ); - if (targetPc.length === 0) return 1; - else if (targetPc.length === 1) return targetPc[0].target; + + if (newTargetPc.length === 0) return 1; + else if (newTargetPc.length === 1) return newTargetPc[0].target; else { return 1; } diff --git a/src/util/constants.js b/src/util/constants.js index f52b405..db79c7d 100644 --- a/src/util/constants.js +++ b/src/util/constants.js @@ -19,24 +19,29 @@ export function ChangeOfRuleSet({ const prevRuleSet = RuleSets.find( (r) => prevDateMoment.isSameOrAfter(r.range[0]) && - prevDateMoment.isSameOrBefore(r.range[1]) + prevDateMoment.isBefore(r.range[1]) ); const newRuleSet = RuleSets.find( (r) => newDateMoment.isSameOrAfter(r.range[0]) && - newDateMoment.isSameOrBefore(r.range[1]) + newDateMoment.isBefore(r.range[1]) ); return prevRuleSet?.title !== newRuleSet?.title; } -export function WhichRulesetToApply({ DateMoment = moment() }) { +export function WhichRulesetToApply(close_date) { + const DateMoment = close_date ? moment(close_date) : moment(); + console.log( + "🚀 ~ file: constants.js:36 ~ WhichRulesetToApply ~ DateMoment", + DateMoment + ); const newRuleSet = RuleSets.find( (r) => - DateMoment.isSameOrAfter(r.range[0]) && - DateMoment.isSameOrBefore(r.range[1]) + DateMoment.isSameOrAfter(r.range[0]) && DateMoment.isBefore(r.range[1]) ); + console.log("Using ruleset:", newRuleSet); return newRuleSet?.title; } diff --git a/update-targets.md b/update-targets.md new file mode 100644 index 0000000..d7ece4b --- /dev/null +++ b/update-targets.md @@ -0,0 +1,371 @@ + +mutation ($list: [targets_insert_input!]!) +{ + insert_targets(objects: $list){ + affected_rows + } +} + +Variables: +{"list": [ + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 0, + "ageLt": 3, + "group": "Group 1", + "target": 0.021 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 3, + "ageLt": 6, + "group": "Group 1", + "target": 0.072 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 6, + "ageLt": null, + "group": "Group 1", + "target": 0.105 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 0, + "ageLt": 3, + "group": "Group 2", + "target": 0.04 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 3, + "ageLt": 6, + "group": "Group 2", + "target": 0.117 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 6, + "ageLt": null, + "group": "Group 2", + "target": 0.187 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 0, + "ageLt": 3, + "group": "Group 3", + "target": 0.067 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 3, + "ageLt": 6, + "group": "Group 3", + "target": 0.166 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 6, + "ageLt": null, + "group": "Group 3", + "target": 0.232 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 0, + "ageLt": 3, + "group": "Group 4", + "target": 0.083 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 3, + "ageLt": 6, + "group": "Group 4", + "target": 0.195 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 6, + "ageLt": null, + "group": "Group 4", + "target": 0.274 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 0, + "ageLt": 3, + "group": "Group 5", + "target": 0.114 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 3, + "ageLt": 6, + "group": "Group 5", + "target": 0.25 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 6, + "ageLt": null, + "group": "Group 5", + "target": 0.307 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 0, + "ageLt": 3, + "group": "Group 6", + "target": 0.096 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 3, + "ageLt": 6, + "group": "Group 6", + "target": 0.256 + }, + { + "ins_co": "MPI", + "name": "V1", + "effective_date": "2019-01-01", + "end_date": "2023-03-31", + "ageGte": 6, + "ageLt": null, + "group": "Group 6", + "target": 0.318 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 0, + "ageLt": 3, + "group": "Group 1", + "target": 0.023 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 3, + "ageLt": 6, + "group": "Group 1", + "target": 0.077 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 6, + "ageLt": null, + "group": "Group 1", + "target": 0.109 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 0, + "ageLt": 3, + "group": "Group 2", + "target": 0.045 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 3, + "ageLt": 6, + "group": "Group 2", + "target": 0.125 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 6, + "ageLt": null, + "group": "Group 2", + "target": 0.193 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 0, + "ageLt": 3, + "group": "Group 3", + "target": 0.075 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 3, + "ageLt": 6, + "group": "Group 3", + "target": 0.176 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 6, + "ageLt": null, + "group": "Group 3", + "target": 0.238 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 0, + "ageLt": 3, + "group": "Group 4", + "target": 0.094 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 3, + "ageLt": 6, + "group": "Group 4", + "target": 0.205 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 6, + "ageLt": null, + "group": "Group 4", + "target": 0.281 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 0, + "ageLt": 3, + "group": "Group 5", + "target": 0.128 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 3, + "ageLt": 6, + "group": "Group 5", + "target": 0.259 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 6, + "ageLt": null, + "group": "Group 5", + "target": 0.313 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 0, + "ageLt": 3, + "group": "Group 6", + "target": 0.123 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 3, + "ageLt": 6, + "group": "Group 6", + "target": 0.262 + }, + { + "ins_co": "MPI", + "name": "V2", + "effective_date": "2023-04-01", + "end_date": null, + "ageGte": 6, + "ageLt": null, + "group": "Group 6", + "target": 0.32 + } + ]} \ No newline at end of file