From a347a57fa9ed52c63a4c0e6dc4345f0c5ac1c5ae Mon Sep 17 00:00:00 2001 From: Maksim Sviridov Date: Fri, 14 Jul 2023 15:52:16 +0300 Subject: [PATCH] fix(GoalCriteria): calc achieve progress through all criteria --- src/components/CriteriaForm/CriteriaForm.tsx | 4 +- src/schema/criteria.ts | 2 +- trpc/queries/goals.ts | 42 ++++++++++++++++---- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/components/CriteriaForm/CriteriaForm.tsx b/src/components/CriteriaForm/CriteriaForm.tsx index c4b2b6e46..aff90ad0f 100644 --- a/src/components/CriteriaForm/CriteriaForm.tsx +++ b/src/components/CriteriaForm/CriteriaForm.tsx @@ -211,7 +211,7 @@ export const CriteriaForm: React.FC = ({ onSubmit, goalId, va goalId, title: '', weight: '', - goalAsGriteria: null, + goalAsGriteria: undefined, }, }); @@ -229,7 +229,7 @@ export const CriteriaForm: React.FC = ({ onSubmit, goalId, va reset({ title: '', weight: '', - goalAsGriteria: null, + goalAsGriteria: undefined, goalId, }); }, [goalId, reset]); diff --git a/src/schema/criteria.ts b/src/schema/criteria.ts index e8a3c1544..8dd909aa6 100644 --- a/src/schema/criteria.ts +++ b/src/schema/criteria.ts @@ -16,7 +16,7 @@ export const criteriaSchema = z.object({ .object({ id: z.string(), }) - .nullish(), + .optional(), }); export const updateCriteriaState = z.object({ diff --git a/trpc/queries/goals.ts b/trpc/queries/goals.ts index 89b7e6857..601b89ebe 100644 --- a/trpc/queries/goals.ts +++ b/trpc/queries/goals.ts @@ -1,4 +1,4 @@ -import { Estimate, EstimateToGoal, Goal, Prisma, StateType } from '@prisma/client'; +import { Estimate, EstimateToGoal, Goal, GoalAchieveCriteria, Prisma, State, StateType } from '@prisma/client'; import { QueryWithFilters } from '../../src/schema/common'; @@ -433,6 +433,38 @@ export const goalDeepQuery = { }, } as const; +const maxPossibleCriteriaWeight = 100; + +const calcAchievedWeight = (list: (GoalAchieveCriteria & { goalAsCriteria: Goal & { state: State } })[]): number => { + const { achivedWithWeight, comletedWithoutWeight, anyWithoutWeight, allWeight } = list.reduce( + (acc, value) => { + acc.allWeight += value.weight; + + if (!value.weight) { + acc.anyWithoutWeight += 1; + } + if (value.isDone || (value.goalAsCriteria && value.goalAsCriteria.state?.type === StateType.Completed)) { + acc.achivedWithWeight += value.weight; + + if (!value.weight) { + acc.comletedWithoutWeight += 1; + } + } + + return acc; + }, + { achivedWithWeight: 0, comletedWithoutWeight: 0, anyWithoutWeight: 0, allWeight: 0 }, + ); + + const remainingtWeight = maxPossibleCriteriaWeight - allWeight; + const quantityByWeightlessCriteria = remainingtWeight / anyWithoutWeight; + + return Math.min( + achivedWithWeight + Math.ceil(quantityByWeightlessCriteria * comletedWithoutWeight), + maxPossibleCriteriaWeight, + ); +}; + export const addCalclulatedGoalsFields = (goal: any, activityId: string) => { const _isOwner = goal.ownerId === activityId; const _isParticipant = goal.participants?.some((participant: any) => participant?.id === activityId); @@ -442,13 +474,7 @@ export const addCalclulatedGoalsFields = (goal: any, activityId: string) => { const _lastEstimate = goal.estimate?.length ? goal.estimate[goal.estimate.length - 1].estimate : undefined; const _shortId = `${goal.projectId}-${goal.scopeId}`; const _hasAchievementCriteria = goal.goalAchiveCriteria?.length; - const _achivedCriteriaWeight = goal.goalAchiveCriteria?.reduce((sum: number, curr: any) => { - if (curr.isDone || (curr.goalAsCriteria && curr.goalAsCriteria.state?.type === StateType.Completed)) { - return sum + curr.weight; - } - - return sum; - }, 0); + const _achivedCriteriaWeight = calcAchievedWeight(goal.goalAchiveCriteria ?? []); let parentOwner = false; function checkParent(project?: any) {