@@ -19,7 +19,7 @@ import SearchBox, { Criterion } from "../SearchBox"; | |||
import ProgressByClientSearch from "@/components/ProgressByClientSearch"; | |||
import { Suspense } from "react"; | |||
import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch"; | |||
import { Input, Label } from "reactstrap"; | |||
import { CardFooter, Input, Label } from "reactstrap"; | |||
import Select, { components } from "react-select"; | |||
import { fetchTeamCombo, fetchTeamCashFlowChartData } from "@/app/api/teamCashflow"; | |||
import { VIEW_DASHBOARD_ALL } from "@/middleware"; | |||
@@ -395,6 +395,11 @@ const CompanyTeamCashFlow: React.FC<Props> = ({ abilities, staff }) => { | |||
height="500" | |||
/> | |||
</div> | |||
<CardFooter> | |||
<Grid sx={{ ml: 2, mb: 2, fontSize: '0.8rem' }}> | |||
* Cumulative Expenditure: Manpower Expense + Other Expense | |||
</Grid> | |||
</CardFooter> | |||
</Card> | |||
</Grid> | |||
</div> | |||
@@ -10,15 +10,19 @@ import { TeamResult } from "@/app/api/team"; | |||
import { SessionStaff } from "@/config/authConfig"; | |||
interface Props { | |||
teams: TeamResult[]; | |||
_teams: TeamResult[]; | |||
userStaff: SessionStaff; | |||
} | |||
type SearchQuery = Partial<Omit<CrossTeamChargeReportFilter, "id">>; | |||
type SearchParamNames = keyof SearchQuery; | |||
const GenerateCrossTeamChargeReport: React.FC<Props> = ({ teams, userStaff }) => { | |||
const GenerateCrossTeamChargeReport: React.FC<Props> = ({ _teams, userStaff }) => { | |||
const { t } = useTranslation("report"); | |||
let teams = _teams | |||
if (Boolean(userStaff?.isTeamLead)) { | |||
teams.filter(team => team.id == userStaff.teamId) | |||
} | |||
const teamCombo = teams.map(team => `${team.code} - ${team.name}`) | |||
const searchCriteria: Criterion<SearchParamNames>[] = useMemo( | |||
@@ -50,7 +54,11 @@ const GenerateCrossTeamChargeReport: React.FC<Props> = ({ teams, userStaff }) => | |||
// const projectIndex = projectCombo.findIndex(({value}) => value === parseInt(query.project)) | |||
const teamIndex = teamCombo.findIndex(team => team === query.team) | |||
const response = await fetchCrossTeamChargeReport({ month: query.month, teamId: teamIndex >= 0 ? teams[teamIndex].id : "All", }) | |||
const response = await fetchCrossTeamChargeReport( | |||
{ | |||
month: query.month, | |||
teamId: teamIndex >= 0 ? teams[teamIndex].id : "All", | |||
}) | |||
if (response) { | |||
downloadFile(new Uint8Array(response.blobValue), response.filename!!) | |||
} | |||
@@ -9,10 +9,15 @@ interface SubComponents { | |||
} | |||
const GenerateCrossTeamChargeReportWrapper: React.FC & SubComponents = async () => { | |||
const [ | |||
teams, | |||
userStaff | |||
] = await Promise.all([ | |||
fetchTeam(), | |||
fetchUserStaff() | |||
]) | |||
const [teams, userStaff] = await Promise.all([fetchTeam(), fetchUserStaff()]) | |||
return <GenerateCrossTeamChargeReport teams={!Boolean(userStaff?.isTeamLead) ? teams : teams.filter(team => team.id === userStaff?.teamId)} userStaff={userStaff}/>; | |||
return <GenerateCrossTeamChargeReport _teams={!Boolean(userStaff?.isTeamLead) ? teams : teams.filter(team => team.id === userStaff?.teamId)} userStaff={userStaff}/>; | |||
}; | |||
GenerateCrossTeamChargeReportWrapper.Loading = GenerateCrossTeamChargeReportLoading; | |||
@@ -47,6 +47,7 @@ const ProjectResourceSummary: React.FC = () => { | |||
const [projectBudget, setProjectBudget]:any = React.useState(0); | |||
const [expenditure, setExpenditure]:any = React.useState(0); | |||
const [remainingBudget, setRemainingBudget]:any = React.useState(0); | |||
const [expense, setExpense] = React.useState(0); | |||
const [status, setStatus]:any = React.useState("NA"); | |||
const [plannedResources, setPlannedResources]:any = React.useState(0); | |||
const [actualResourcesSpent, setActualResourcesSpent]:any = React.useState(0); | |||
@@ -105,6 +106,7 @@ const ProjectResourceSummary: React.FC = () => { | |||
setPlannedResources(result[0].summaryInformation[0].plannedResources) | |||
setActualResourcesSpent(result[0].summaryInformation[0].resourcesSpent) | |||
setRemainingResources(result[0].summaryInformation[0].remainingResources) | |||
setExpense(result[0].summaryInformation[0].expense) | |||
console.log(result); | |||
const mainStageResult = result[0].summaryMainStage | |||
const subStageResult = result[0].summarySubStage | |||
@@ -661,10 +663,37 @@ const columns2 = [ | |||
<u> | |||
{t("Cumulative Expenditure")} | |||
</u> | |||
<br/> | |||
{/* <u> | |||
{t(" (Manpower + Other Expense)")} | |||
</u> */} | |||
</div> | |||
<div style={infoDataStyle}> | |||
HKD ${expenditure.toFixed(2)} | |||
</div> | |||
{/* <div style={infoDataStyle}> | |||
{`HKD $(${(expenditure - expense).toFixed(2)} + ${expense.toFixed(2)})`} | |||
</div> */} | |||
</div> | |||
<div style={{ display: "inline-block", width: "33%"}}> | |||
<div style={infoHeaderStyle}> | |||
<u> | |||
{t("Manpower Expense")} | |||
</u> | |||
</div> | |||
<div style={infoDataStyle}> | |||
HKD ${(expenditure - expense).toFixed(2)} | |||
</div> | |||
</div> | |||
<div style={{ display: "inline-block", width: "33%"}}> | |||
<div style={infoHeaderStyle}> | |||
<u> | |||
{t("Other Expense")} | |||
</u> | |||
</div> | |||
<div style={infoDataStyle}> | |||
HKD ${(expense).toFixed(2)} | |||
</div> | |||
</div> | |||
<div style={{ display: "inline-block", width: "33%"}}> | |||
<div style={infoHeaderStyle}> | |||