Skip to content

Commit

Permalink
feat: added hour value to membership data
Browse files Browse the repository at this point in the history
  • Loading branch information
celsoMartins committed Dec 6, 2023
1 parent fc5ba62 commit 533c8bd
Show file tree
Hide file tree
Showing 16 changed files with 105 additions and 20 deletions.
1 change: 1 addition & 0 deletions app/graphql/types/teams/membership_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class MembershipType < Types::BaseObject
field :id, ID, null: false
field :member_role, Integer, null: false
field :member_role_description, String, null: false
field :realized_hour_value, Float
field :start_date, GraphQL::Types::ISO8601Date, null: false
field :team, Types::Teams::TeamType, null: false
field :team_id, Integer, null: false
Expand Down
21 changes: 14 additions & 7 deletions app/graphql/types/teams/team_member_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -167,20 +167,27 @@ def team_member_hour_value_chart_list(start_date: 6.months.ago, end_date: Time.z
member_hour_value_list = []
object.teams.each do |team|
member_hour_value_chart_data = []
months.each do |month|
membership = object.memberships.active_for_date(month).find_by(team: team)
next if membership.blank?

member_hour_value_chart_data.push({ date: month, hour_value_expected: membership.expected_hour_value(month), hour_value_realized: membership.realized_hour_value(month) })
end
member_hour_value_list.push({ team: team, member_hour_value_chart_data: member_hour_value_chart_data })
member_hour_value_chart_data << read_hours_in_month(months, team)
member_hour_value_list.push({ team: team, member_hour_value_chart_data: member_hour_value_chart_data.flatten }) if member_hour_value_chart_data.flatten.present?
end

member_hour_value_list
end

private

def read_hours_in_month(months, team)
member_hour_value_chart_data = []
months.each do |month|
membership = object.memberships.active_for_date(month).find_by(team: team)
next if membership.blank? || membership.expected_hour_value(month).zero? || membership.realized_hour_value(month).zero?

member_hour_value_chart_data.push({ date: month, hour_value_expected: membership.expected_hour_value(month), hour_value_realized: membership.realized_hour_value(month) })
end

member_hour_value_chart_data
end

def operations_dashboards
@operations_dashboards ||= Dashboards::OperationsDashboard.where(
team_member: object,
Expand Down
2 changes: 1 addition & 1 deletion app/models/membership.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ def cards_count(start_date, end_date)
end

def current_hours_per_month(date = Time.zone.now)
membership_available_hours_histories.until_date(date).order(:change_date).last&.available_hours || hours_per_month
membership_available_hours_histories.until_date(date).order(:change_date).last&.available_hours || hours_per_month || 0
end

private
Expand Down
7 changes: 5 additions & 2 deletions app/spa/src/components/TeamMemberDashboardCharts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import TeamMemberEffortDailyData from "../modules/teamMember/components/TeamMemb
import { LineChart } from "./charts/LineChart"
import { SliceTooltipProps } from "@nivo/line"
import LineChartTooltip from "./charts/tooltips/LineChartTooltip"
import { formatCurrency } from "../lib/currency"

type TeamMemberDashboardChartsProps = {
teamMember: TeamMember
Expand Down Expand Up @@ -91,7 +92,9 @@ const TeamMemberDashboardCharts = ({
(memberHourValueChartData) => {
return {
x: String(memberHourValueChartData.date || ""),
y: String(memberHourValueChartData.hourValueRealized || 0),
y: String(
memberHourValueChartData.hourValueRealized?.toFixed(2) || 0
),
}
}
) ?? [],
Expand Down Expand Up @@ -159,7 +162,7 @@ const TeamMemberDashboardCharts = ({
/>
</ChartGridItem>
)}
{projectHoursData && (
{lineChartTeamMemberHourValueData && (
<ChartGridItem title={t("charts.valuePerHour")}>
<LineChart
data={lineChartTeamMemberHourValueData}
Expand Down
2 changes: 2 additions & 0 deletions app/spa/src/locales/coca/membership.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
"startDate": "Start",
"endDate": "End",
"hoursPerMonth": "Hours per Month",
"expectedHourValue": "Expected Hour Value",
"realizedHourValue": "Realized Hour Value",
"effortPercentage": "Effort Percentage",
"options": {
"memberRole": {
Expand Down
4 changes: 4 additions & 0 deletions app/spa/src/locales/coca/teamMembers.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
"billable": "Billable",
"monthlyPayment": "Payment",
"hoursPerMonth": "Hours per Month",
"expectedHourValue": "Expected Hour Value",
"realizedHourValue": "Realized Hour Value",
"jiraAccountUserEmail": "User Email",
"jiraAccountId": "Jira Account ID",
"status": {
Expand All @@ -22,6 +24,8 @@
"statusSelectLabel": "Member Status",
"hours": "Hours",
"producedValue": "Value",
"hourValueRealized": "Hour Value Realized",
"hourValueExpected": "Hour Value Expected",
"capacity": "Capacity",
"avgHoursPerDemand": "Hs / Deliverable",
"cardsCount": "Demands",
Expand Down
2 changes: 2 additions & 0 deletions app/spa/src/locales/en/membership.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
"startDate": "Start",
"endDate": "End",
"hoursPerMonth": "Hours per Month",
"expectedHourValue": "Expected Hour Value",
"realizedHourValue": "Realized Hour Value",
"effortPercentage": "Effort Percentage",
"options": {
"memberRole": {
Expand Down
4 changes: 4 additions & 0 deletions app/spa/src/locales/en/teamMembers.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
"billable": "Billable",
"monthlyPayment": "Payment",
"hoursPerMonth": "Hours per Month",
"expectedHourValue": "Expected Hour Value",
"realizedHourValue": "Realized Hour Value",
"jiraAccountUserEmail": "User Email",
"jiraAccountId": "Jira Account ID",
"status": {
Expand All @@ -22,6 +24,8 @@
"statusSelectLabel": "Member Status",
"hours": "Hours",
"producedValue": "Value",
"hourValueRealized": "Hour Value Realized",
"hourValueExpected": "Hour Value Expected",
"capacity": "Capacity",
"avgHoursPerDemand": "Hs / Demand",
"averageHoursPerMember": "Avg per member: {{ hours }}h",
Expand Down
3 changes: 2 additions & 1 deletion app/spa/src/locales/en/teams.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@
"leadTimeP80YLabel": "Days",
"financialPerformance": "Financial Performance",
"financialPerformanceYLabel": "Amount",
"hoursPerPeriodMemberships": "Value per Hour of Work",
"hourValueRealized": "Hour Value Realized",
"hoursExpected": "Hour Value Expected",
"valueInReal": "Value per Hour - ( R$ )"
},
"actions": {
Expand Down
2 changes: 2 additions & 0 deletions app/spa/src/locales/pt/membership.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
"startDate": "Início",
"endDate": "Fim",
"hoursPerMonth": "Horas por mês",
"expectedHourValue": "Valor Hora Esperado",
"realizedHourValue": "Valor Hora Realizado",
"effortPercentage": "Porcentagem de Esforço",
"options": {
"memberRole": {
Expand Down
4 changes: 4 additions & 0 deletions app/spa/src/locales/pt/teamMembers.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
"billable": "Faturável?",
"monthlyPayment": "Pagamento",
"hoursPerMonth": "Horas por Mês",
"expectedHourValue": "Valor Hora Esperado",
"realizedHourValue": "Valor Hora Realizado",
"jiraAccountUserEmail": "Email",
"jiraAccountId": "ID da Conta do Jira",
"status": {
Expand All @@ -22,6 +24,8 @@
"statusSelectLabel": "Status do Membro",
"hours": "Horas",
"producedValue": "Valor",
"hourValueRealized": "Valor Hora Realizado",
"hourValueExpected": "Valor Hora Esperado",
"capacity": "Capacidade",
"avgHoursPerDemand": "Hs / Demanda",
"cardsCount": "Demandas",
Expand Down
3 changes: 2 additions & 1 deletion app/spa/src/locales/pt/teams.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@
"leadTimeP80YLabel": "Days",
"financialPerformance": "Financial Performance",
"financialPerformanceYLabel": "Amount",
"hoursPerPeriodMemberships": "Value per Hour of Work",
"hourValueRealized": "Valor Hora Realizado",
"hourValueExpected": "Valor Hora Esperado",
"valueInReal": "Value per Hour - ( R$ )"
},
"actions": {
Expand Down
1 change: 1 addition & 0 deletions app/spa/src/modules/team/team.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export type Membership = {
hoursPerMonth?: number
effortPercentage?: number
expectedHourValue?: number
realizedHourValue?: number
startDate?: string
endDate?: string
memberRole?: number
Expand Down
12 changes: 12 additions & 0 deletions app/spa/src/pages/Teams/MemberEfficiencyTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
InputLabel,
Link,
Select,
TableCell,
} from "@mui/material"
import { useForm } from "react-hook-form"
import SearchIcon from "@mui/icons-material/Search"
Expand All @@ -23,6 +24,7 @@ import { MembershipEfficiencyData, Team } from "../../modules/team/team.types"
import Table from "../../components/ui/Table"
import { FormElement } from "../../components/ui/Form"
import EditOutlinedIcon from "@mui/icons-material/EditOutlined"
import { formatCurrency } from "../../lib/currency"

const MemberEfficiencyTable = () => {
const { t } = useTranslation("teamMembers")
Expand Down Expand Up @@ -57,6 +59,8 @@ const MemberEfficiencyTable = () => {
t("list.capacity"),
t("list.hours"),
t("list.producedValue"),
t("list.hourValueExpected"),
t("list.hourValueRealized"),
t("list.cardsCount"),
t("list.avgHoursPerDemand"),
]
Expand All @@ -76,6 +80,14 @@ const MemberEfficiencyTable = () => {
style: "currency",
currency: "BRL",
}),
membershipEfficency.hourValueExpected?.toLocaleString("pt-br", {
style: "currency",
currency: "BRL",
}),
membershipEfficency.hourValueRealized?.toLocaleString("pt-br", {
style: "currency",
currency: "BRL",
}),
membershipEfficency.cardsCount,
membershipEfficency.avgHoursPerDemand?.toFixed(2),

Expand Down
9 changes: 9 additions & 0 deletions app/spa/src/pages/Teams/MembershipsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { useTranslation } from "react-i18next"
import BasicPage from "../../components/BasicPage"
import DateLocale from "../../components/ui/DateLocale"
import { Team } from "../../modules/team/team.types"
import { formatCurrency } from "../../lib/currency"

const MembershipsTable = () => {
const { teamId, companySlug } = useParams()
Expand Down Expand Up @@ -108,6 +109,12 @@ const MembershipsTable = () => {
<TableRow>
<TableCell>{membership.teamMemberName}</TableCell>
<TableCell>{membership.hoursPerMonth}</TableCell>
<TableCell>
{formatCurrency(membership.expectedHourValue || 0)}
</TableCell>
<TableCell>
{formatCurrency(membership.realizedHourValue || 0)}
</TableCell>
<TableCell>{membership.memberRoleDescription}</TableCell>
<TableCell>
{membership.startDate && (
Expand Down Expand Up @@ -167,6 +174,8 @@ export const MEMBERSHIPS_TABLE_QUERY = gql`
endDate
memberRole
memberRoleDescription
hourValueExpected
hourValueRealized
}
}
}
Expand Down
48 changes: 40 additions & 8 deletions app/spa/src/pages/Teams/TeamDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { Demand } from "../../modules/demand/demand.types"
import TeamBasicPage from "../../modules/team/components/TeamBasicPage"
import { Team } from "../../modules/team/team.types"
import MemberGeneralInfo from "./MemberGeneralInfo"
import { formatCurrency } from "../../lib/currency"

const TEAM_DASHBOARD_QUERY = gql`
query TeamDashboard($teamId: ID!, $startDate: ISO8601Date, $endDate: ISO8601Date) {
Expand All @@ -43,10 +44,6 @@ const TEAM_DASHBOARD_QUERY = gql`
activeBillableCount
availableHoursInMonthFor
memberships(active: true){
teamMembersHourlyRateList{
periodDate
valuePerHourPerformed
}
teamMemberName
hoursPerMonth
}
Expand Down Expand Up @@ -89,6 +86,7 @@ const TEAM_DASHBOARD_QUERY = gql`
memberHourValueChartData {
date
hourValueRealized
hourValueExpected
}
}
}
Expand Down Expand Up @@ -215,7 +213,25 @@ const TeamDashboard = () => {
},
]

const lineChartMembershipHourValueData =
const lineChartMembershipHourRealizedValueData =
team?.membershipHourValueChartList?.map((membershipHourValueList) => {
return {
id: membershipHourValueList.membership?.teamMemberName ?? "",
data:
membershipHourValueList.memberHourValueChartData?.map(
(memberHourValueChartData) => {
return {
x: String(memberHourValueChartData.date || ""),
y: String(
memberHourValueChartData.hourValueRealized?.toFixed(2) || 0
),
}
}
) ?? [],
}
}) ?? []

const lineChartMembershipHoursExpectedValueData =
team?.membershipHourValueChartList?.map((membershipHourValueList) => {
return {
id: membershipHourValueList.membership?.teamMemberName ?? "",
Expand All @@ -224,13 +240,16 @@ const TeamDashboard = () => {
(memberHourValueChartData) => {
return {
x: String(memberHourValueChartData.date || ""),
y: String(memberHourValueChartData.hourValueRealized || 0),
y: String(
memberHourValueChartData.hourValueExpected?.toFixed(2) || 0
),
}
}
) ?? [],
}
}) ?? []

const num = 2
return (
<TeamBasicPage
breadcrumbsLinks={breadcrumbsLinks}
Expand Down Expand Up @@ -342,9 +361,22 @@ const TeamDashboard = () => {
/>
</ChartGridItem>

<ChartGridItem title={t("charts.hoursPerPeriodMemberships")}>
<ChartGridItem title={t("charts.hourValueRealized")}>
<LineChart
data={lineChartMembershipHourRealizedValueData}
axisLeftLegend={t("charts.valueInReal")}
props={{
enableSlices: "x",
sliceTooltip: ({ slice }: SliceTooltipProps) => (
<LineChartTooltip slice={slice} />
),
}}
/>
</ChartGridItem>

<ChartGridItem title={t("charts.hoursExpected")}>
<LineChart
data={lineChartMembershipHourValueData}
data={lineChartMembershipHoursExpectedValueData}
axisLeftLegend={t("charts.valueInReal")}
props={{
enableSlices: "x",
Expand Down

0 comments on commit 533c8bd

Please sign in to comment.