diff --git a/app/graphql/types/teams/membership_type.rb b/app/graphql/types/teams/membership_type.rb
index 1ea64f575..491f2f494 100644
--- a/app/graphql/types/teams/membership_type.rb
+++ b/app/graphql/types/teams/membership_type.rb
@@ -6,6 +6,7 @@ class MembershipType < Types::BaseObject
field :created_at, GraphQL::Types::ISO8601DateTime, null: false
field :effort_percentage, Float
field :end_date, GraphQL::Types::ISO8601Date
+ field :expected_hour_value, Float
field :hours_per_month, Integer
field :id, ID, null: false
field :member_role, Integer, null: false
diff --git a/app/models/membership.rb b/app/models/membership.rb
index 9a2318044..0b76605b8 100644
--- a/app/models/membership.rb
+++ b/app/models/membership.rb
@@ -98,6 +98,12 @@ def stages_to_work_on
stages_to_work_on
end
+ def expected_hour_value
+ return 0 if hours_per_month.zero?
+
+ monthly_payment / hours_per_month
+ end
+
def monthly_payment
return 0 if team_member.monthly_payment.blank?
diff --git a/app/spa/src/components/ProjectDemandsCharts.tsx b/app/spa/src/components/ProjectDemandsCharts.tsx
index 65c76c439..1b32e835b 100644
--- a/app/spa/src/components/ProjectDemandsCharts.tsx
+++ b/app/spa/src/components/ProjectDemandsCharts.tsx
@@ -164,7 +164,7 @@ const ProjectDemandsCharts = ({
t("charts_tab.project_charts.demands_burn_up_label_ideal"),
t("charts_tab.project_charts.demands_burn_up_label_delivered"),
project.demandsBurnup
- )
+ )
const projectHoursBurnupChartData = buildBurnupData(
t("charts_tab.project_charts.hours_burn_up_label_scope"),
@@ -172,7 +172,7 @@ const ProjectDemandsCharts = ({
t("charts_tab.project_charts.hours_burn_up_label_delivered"),
project.hoursBurnup
)
-
+
const leadTimeP80ChartData = [
{
id: project.name,
diff --git a/app/spa/src/components/TeamMemberDashboardCharts.tsx b/app/spa/src/components/TeamMemberDashboardCharts.tsx
index e64e4c93c..7629d7342 100644
--- a/app/spa/src/components/TeamMemberDashboardCharts.tsx
+++ b/app/spa/src/components/TeamMemberDashboardCharts.tsx
@@ -85,15 +85,16 @@ const TeamMemberDashboardCharts = ({
const lineChartData = [
{
id: teamMember.name,
- data: teamMember.teamMemberConsolidationList? teamMember.teamMemberConsolidationList.map(
- ({ valuePerHourPerformed, consolidationDate }) => {
-
- return {
- x: String(consolidationDate || ''),
- y: Number(valuePerHourPerformed || 0),
- }
- }
- ) : [],
+ data: teamMember.teamMemberConsolidationList
+ ? teamMember.teamMemberConsolidationList.map(
+ ({ valuePerHourPerformed, consolidationDate }) => {
+ return {
+ x: String(consolidationDate || ""),
+ y: Number(valuePerHourPerformed || 0),
+ }
+ }
+ )
+ : [],
},
]
@@ -158,22 +159,20 @@ const TeamMemberDashboardCharts = ({
/>
)}
- {projectHoursData && (
+ {projectHoursData && (
- (
-
- ),
- }}
- />
-
+ (
+
+ ),
+ }}
+ />
+
)}
)
diff --git a/app/spa/src/components/TeamMemberDashboardTables.tsx b/app/spa/src/components/TeamMemberDashboardTables.tsx
index 0c38f2be5..61b4f7c95 100644
--- a/app/spa/src/components/TeamMemberDashboardTables.tsx
+++ b/app/spa/src/components/TeamMemberDashboardTables.tsx
@@ -24,13 +24,13 @@ const TeamMemberDashboardTables = ({
const [searchParams, setSearchParams] = useSearchParams()
const normalizeQueryStringFilters = (filters: FieldValues) =>
- Object.keys(filters)
- .filter((key) => {
- return String(filters[key]).length > 0 && filters[key] !== "null"
- })
- .reduce>((acc, el) => {
- return { ...acc, [el]: filters[el] }
- }, {})
+ Object.keys(filters)
+ .filter((key) => {
+ return String(filters[key]).length > 0 && filters[key] !== "null"
+ })
+ .reduce>((acc, el) => {
+ return { ...acc, [el]: filters[el] }
+ }, {})
const demandShortestLeadTime =
teamMember.demandShortestLeadTime?.leadtime || 0
@@ -130,23 +130,25 @@ const TeamMemberDashboardTables = ({
t("dashboard.latestEfforts.effortValue"),
]
- const latestEffortsRows = teamMember?.demandEffortsList?.demandEfforts?.map((effort) => [
-
- {effort.team?.name}
- ,
- ,
- ,
-
- {effort.demandExternalId}
- ,
- `${(effort.effortValue || 0).toFixed(2)}`,
- ])
+ const latestEffortsRows = teamMember?.demandEffortsList?.demandEfforts?.map(
+ (effort) => [
+
+ {effort.team?.name}
+ ,
+ ,
+ ,
+
+ {effort.demandExternalId}
+ ,
+ `${(effort.effortValue || 0).toFixed(2)}`,
+ ]
+ )
const latestProjectsRows =
teamMember.projectsList?.projects?.map((project) => [
@@ -230,21 +232,23 @@ const TeamMemberDashboardTables = ({
{searchParams && (
- setSearchParams({
- ...normalizeQueryStringFilters(effortsFilters || {}),
- pageNumber: String(newPage + 1),
- }),
- }}
- />
+ title={t("dashboard.latestEfforts.title")}
+ subtitle={`${t("dashboard.latestEfforts.effortsValueSum")} ${
+ teamMember?.demandEffortsList?.effortsValueSum || 0
+ }`}
+ headerCells={latestEffortsHeader}
+ rows={latestEffortsRows || []}
+ pagination={{
+ count: teamMember?.demandEffortsList?.demandEffortsCount || 0,
+ rowsPerPage: 10,
+ page: effortsFilters.pageNumber - 1,
+ onPageChange: (_, newPage: number) =>
+ setSearchParams({
+ ...normalizeQueryStringFilters(effortsFilters || {}),
+ pageNumber: String(newPage + 1),
+ }),
+ }}
+ />
)}
diff --git a/app/spa/src/components/ui/DateLocale.tsx b/app/spa/src/components/ui/DateLocale.tsx
index 26814b9bd..855218e8b 100644
--- a/app/spa/src/components/ui/DateLocale.tsx
+++ b/app/spa/src/components/ui/DateLocale.tsx
@@ -8,7 +8,7 @@ type DateLocaleProps = {
isPtBr?: boolean
}
-const DateLocale = ({ date, time, isPtBr = true}: DateLocaleProps) => {
+const DateLocale = ({ date, time, isPtBr = true }: DateLocaleProps) => {
const dateFormat = isPtBr ? "dd/MM/yyyy" : "MM/dd/yyyy"
const format = time ? `${dateFormat} HH:mm` : dateFormat
diff --git a/app/spa/src/modules/team/team.types.ts b/app/spa/src/modules/team/team.types.ts
index b4e872e5a..795bd87cb 100644
--- a/app/spa/src/modules/team/team.types.ts
+++ b/app/spa/src/modules/team/team.types.ts
@@ -9,7 +9,6 @@ import { Demand } from "../demand/demand.types"
import { ProjectConsolidation } from "../project/projectConsolidation.types"
import { ReplenishingConsolidation } from "../replenishing/replenishingConsolidation.types"
-
export type TeamMembersHourlyRate = {
periodDate?: string
valuePerHourPerformed?: number
@@ -66,6 +65,8 @@ export type MembershipEfficiencyData = {
realizedMoneyInMonth?: number
avgHoursPerDemand?: number
cardsCount?: number
+ expectedHourValue?: number
+ realizedHourValue?: number
}
export type Membership = {
@@ -75,10 +76,10 @@ export type Membership = {
teamMemberName?: string
hoursPerMonth?: number
effortPercentage?: number
+ expectedHourValue?: number
startDate?: string
endDate?: string
memberRole?: number
memberRoleDescription?: string
teamMembersHourlyRateList?: TeamMembersHourlyRate[]
-
}
diff --git a/app/spa/src/modules/teamMember/teamMember.types.ts b/app/spa/src/modules/teamMember/teamMember.types.ts
index 00b903a6d..d82c12d72 100644
--- a/app/spa/src/modules/teamMember/teamMember.types.ts
+++ b/app/spa/src/modules/teamMember/teamMember.types.ts
@@ -47,10 +47,12 @@ export type TeamMember = {
yAxisProjectsNames: string[]
}
demandEfforts?: DemandEffort[]
- demandEffortsList?: {
- demandEfforts?: DemandEffort[]
- demandEffortsCount?: number
- effortsValueSum?: number
- }
+ demandEffortsList?: DemandEffortsList
teamMemberConsolidationList?: TeamMemberConsolidation[]
}
+
+type DemandEffortsList = {
+ demandEfforts?: DemandEffort[]
+ demandEffortsCount?: number
+ effortsValueSum?: number
+}
diff --git a/app/spa/src/pages/TeamMembers/TeamMemberDashboard.tsx b/app/spa/src/pages/TeamMembers/TeamMemberDashboard.tsx
index 430bfb880..3c9370733 100644
--- a/app/spa/src/pages/TeamMembers/TeamMemberDashboard.tsx
+++ b/app/spa/src/pages/TeamMembers/TeamMemberDashboard.tsx
@@ -11,7 +11,12 @@ import TeamMemberDashboardCharts from "../../components/TeamMemberDashboardChart
import { FieldValues } from "react-hook-form"
const TEAM_MEMBER_QUERY = gql`
- query TeamMember($id: ID!, $fromDate: ISO8601Date, $untilDate: ISO8601Date, $pageNumber: Int) {
+ query TeamMember(
+ $id: ID!
+ $fromDate: ISO8601Date
+ $untilDate: ISO8601Date
+ $pageNumber: Int
+ ) {
teamMember(id: $id) {
id
name
@@ -116,7 +121,11 @@ const TEAM_MEMBER_QUERY = gql`
slug
}
}
- demandEfforts(fromDate: $fromDate, untilDate: $untilDate, pageNumber: $pageNumber) {
+ demandEfforts(
+ fromDate: $fromDate
+ untilDate: $untilDate
+ pageNumber: $pageNumber
+ ) {
id
effortValue
effortMoney
@@ -141,35 +150,39 @@ const TEAM_MEMBER_QUERY = gql`
automaticUpdate
membershipEffortPercentage
}
- teamMemberConsolidationList{
+ teamMemberConsolidationList {
consolidationDate
valuePerHourPerformed
}
- demandEffortsList(fromDate: $fromDate, untilDate: $untilDate, pageNumber: $pageNumber) {
- demandEfforts{
- id
- effortValue
- effortMoney
- startTimeToComputation
- finishTimeToComputation
- stagePercentage
- pairingPercentage
- managementPercentage
- totalBlocked
- mainEffortInTransition
- stage
- who
- team {
+ demandEffortsList(
+ fromDate: $fromDate
+ untilDate: $untilDate
+ pageNumber: $pageNumber
+ ) {
+ demandEfforts {
id
- name
- }
- createdAt
- updatedAt
- demandId
- demandExternalId
- memberRole
- automaticUpdate
- membershipEffortPercentage
+ effortValue
+ effortMoney
+ startTimeToComputation
+ finishTimeToComputation
+ stagePercentage
+ pairingPercentage
+ managementPercentage
+ totalBlocked
+ mainEffortInTransition
+ stage
+ who
+ team {
+ id
+ name
+ }
+ createdAt
+ updatedAt
+ demandId
+ demandExternalId
+ memberRole
+ automaticUpdate
+ membershipEffortPercentage
}
demandEffortsCount
effortsValueSum
@@ -207,7 +220,7 @@ const TeamMemberDashboard = () => {
id: Number(teamMemberId),
fromDate: effortsQueryFilters.fromDate,
untilDate: effortsQueryFilters.untilDate,
- pageNumber: (effortsQueryFilters.pageNumber || 1),
+ pageNumber: effortsQueryFilters.pageNumber || 1,
},
})
const companySlug = me?.currentCompany?.slug
diff --git a/app/spa/src/pages/Teams/TeamDashboard.tsx b/app/spa/src/pages/Teams/TeamDashboard.tsx
index 249f543da..2499161f5 100644
--- a/app/spa/src/pages/Teams/TeamDashboard.tsx
+++ b/app/spa/src/pages/Teams/TeamDashboard.tsx
@@ -29,7 +29,6 @@ import TeamBasicPage from "../../modules/team/components/TeamBasicPage"
import { Team } from "../../modules/team/team.types"
import MemberGeneralInfo from "./MemberGeneralInfo"
-
const TEAM_DASHBOARD_QUERY = gql`
query TeamDashboard($teamId: ID!, $startDate: ISO8601Date, $endDate: ISO8601Date) {
team(id: $teamId) {
@@ -205,19 +204,24 @@ const TeamDashboard = () => {
},
]
-const lineChartMembershipData = team?.memberships? team?.memberships?.map((membership)=> {
- const seila = { id: membership?.teamMemberName? membership.teamMemberName : "",
- data: membership?.teamMembersHourlyRateList? membership?.teamMembersHourlyRateList?.map(
- ( teamMembersHourlyRate ) => {
- return {
- x: String(teamMembersHourlyRate.periodDate || ''),
- y: String(teamMembersHourlyRate.valuePerHourPerformed || 0),
+ const lineChartMembershipData = team?.memberships
+ ? team?.memberships?.map((membership) => {
+ const seila = {
+ id: membership?.teamMemberName ? membership.teamMemberName : "",
+ data: membership?.teamMembersHourlyRateList
+ ? membership?.teamMembersHourlyRateList?.map(
+ (teamMembersHourlyRate) => {
+ return {
+ x: String(teamMembersHourlyRate.periodDate || ""),
+ y: String(teamMembersHourlyRate.valuePerHourPerformed || 0),
+ }
+ }
+ )
+ : [],
}
- }
-
- ) : []}
- return seila
-}):[]
+ return seila
+ })
+ : []
return (
- (
diff --git a/spec/models/membership_spec.rb b/spec/models/membership_spec.rb
index c41f0d263..4c9ed3948 100644
--- a/spec/models/membership_spec.rb
+++ b/spec/models/membership_spec.rb
@@ -396,4 +396,24 @@
end
end
end
+
+ describe '#expected_hour_value' do
+ context 'with hours per month' do
+ it 'returns the monthly payment divided by the hours per month' do
+ team_member = Fabricate :team_member, hours_per_month: 160, monthly_payment: 10_000
+ membership = Fabricate :membership, team_member: team_member, hours_per_month: 100
+
+ expect(membership.expected_hour_value).to eq 62.5
+ end
+ end
+
+ context 'without hours per month' do
+ it 'returns zero' do
+ team_member = Fabricate :team_member, hours_per_month: 160, monthly_payment: 10_000
+ membership = Fabricate :membership, team_member: team_member, hours_per_month: 0
+
+ expect(membership.expected_hour_value).to eq 0
+ end
+ end
+ end
end