No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 

732 líneas
33 KiB

  1. "use client";
  2. import * as React from "react";
  3. import Grid from "@mui/material/Grid";
  4. import { useState, useEffect, useMemo } from "react";
  5. import Paper from "@mui/material/Paper";
  6. import { TFunction } from "i18next";
  7. import { useTranslation } from "react-i18next";
  8. import { Card, CardHeader } from "@mui/material";
  9. import CustomSearchForm from "../CustomSearchForm/CustomSearchForm";
  10. import CustomDatagrid from "../CustomDatagrid/CustomDatagrid";
  11. import ReactApexChart from "react-apexcharts";
  12. import { ApexOptions } from "apexcharts";
  13. import { DataGrid, GridColDef, GridRowSelectionModel} from "@mui/x-data-grid";
  14. import ReportProblemIcon from "@mui/icons-material/ReportProblem";
  15. import dynamic from "next/dynamic";
  16. import "../../app/global.css";
  17. import { AnyARecord, AnyCnameRecord } from "dns";
  18. import SearchBox, { Criterion } from "../SearchBox";
  19. import ProgressByClientSearch from "@/components/ProgressByClientSearch";
  20. import { Suspense } from "react";
  21. import { getPossibleInstrumentationHookFilenames } from "next/dist/build/utils";
  22. import Table from '@mui/material/Table';
  23. import TableBody from '@mui/material/TableBody';
  24. import TableCell from '@mui/material/TableCell';
  25. import TableContainer from '@mui/material/TableContainer';
  26. import TableHead from '@mui/material/TableHead';
  27. import TableRow from '@mui/material/TableRow';
  28. import Collapse from '@mui/material/Collapse';
  29. import IconButton from '@mui/material/IconButton';
  30. import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
  31. import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
  32. import Box from '@mui/material/Box';
  33. import Typography from '@mui/material/Typography';
  34. import { useSearchParams } from 'next/navigation';
  35. import {fetchResourceSummaryDetailResult} from "@/app/api/resourcesummary/actions";
  36. const ProjectResourceSummary: React.FC = () => {
  37. const searchParams = useSearchParams();
  38. const projectId = searchParams.get('projectId');
  39. const [SearchCriteria, setSearchCriteria] = React.useState({});
  40. const { t } = useTranslation("dashboard");
  41. const [selectionModel, setSelectionModel]: any[] = React.useState([]);
  42. const [projectName, setProjectName]:any = React.useState("NA");
  43. const [projectFee, setProjectFee]:any = React.useState(0);
  44. const [status, setStatus]:any = React.useState("NA");
  45. const [plannedResources, setPlannedResources]:any = React.useState(0);
  46. const [actualResourcesSpent, setActualResourcesSpent]:any = React.useState(0);
  47. const [remainingResources, setRemainingResources]:any = React.useState(0);
  48. const [dataList, setDataList]:any = React.useState();
  49. const [rows,setRows]:any[] = React.useState([]);
  50. //[subStage, subTaskCount, subTotalPlanned, subTotalActual, subG1Planned, subG1Actual, subG2Planned, subG2Actual, subG3Planned, subG3Actual, subG4Planned, subG4Actual, subG5Planned, subG5Actual]:any[]
  51. function createData([stage, taskCount, totalPlanned, totalActual, g1Planned, g1Actual, g2Planned, g2Actual, g3Planned, g3Actual, g4Planned, g4Actual, g5Planned, g5Actual]: any[], task:any[]) {
  52. return {
  53. stage,
  54. taskCount,
  55. g1Planned,
  56. g1Actual,
  57. g2Planned,
  58. g2Actual,
  59. g3Planned,
  60. g3Actual,
  61. g4Planned,
  62. g4Actual,
  63. g5Planned,
  64. g5Actual,
  65. totalPlanned,
  66. totalActual,
  67. task:task
  68. // subStage,
  69. // subTaskCount,
  70. // subTotalPlanned,
  71. // subTotalActual,
  72. // subG1Planned,
  73. // subG1Actual,
  74. // subG2Planned,
  75. // subG2Actual,
  76. // subG3Planned,
  77. // subG3Actual,
  78. // subG4Planned,
  79. // subG4Actual,
  80. // subG5Planned,
  81. // subG5Actual
  82. }
  83. }
  84. const fetchData = async () => {
  85. var intProjectId = 0
  86. if (projectId !== null) {
  87. intProjectId = parseInt(projectId);
  88. }
  89. if (intProjectId !== 0) {
  90. const result = await fetchResourceSummaryDetailResult(intProjectId);
  91. setProjectName(result[0].summaryInformation[0].projectCodeAndName)
  92. setProjectFee(result[0].summaryInformation[0].totalFee)
  93. setStatus(result[0].summaryInformation[0].status)
  94. setPlannedResources(result[0].summaryInformation[0].plannedResources)
  95. setActualResourcesSpent(result[0].summaryInformation[0].resourcesSpent)
  96. setRemainingResources(result[0].summaryInformation[0].remainingResources)
  97. console.log(result);
  98. const mainStageResult = result[0].summaryMainStage
  99. const subStageResult = result[0].summarySubStage
  100. const mainStageFullList = []
  101. const subStageFullList = []
  102. var tgID = mainStageResult[0].id
  103. var tID = subStageResult[0].id
  104. var subTgId = subStageResult[0].tgId
  105. var firstTg = true
  106. var firstT = true
  107. var mainStageList = []
  108. var subStageList = []
  109. var subStageSecondLayerList = []
  110. var arrayNumber = 0
  111. for (var i = 0; i < subStageResult.length ; i++) {
  112. if (subStageResult[i].id !== tID) {
  113. subStageSecondLayerList.push(subStageList)
  114. if (subStageResult[i].tgId !== subTgId) {
  115. subStageFullList.push(subStageSecondLayerList)
  116. subStageSecondLayerList = []
  117. subTgId = subStageResult[i].tgId
  118. }
  119. tID = subStageResult[i].id
  120. firstT = true
  121. subStageList = []
  122. }
  123. if (firstT === true) {
  124. subStageList.push(subStageResult[i].name)
  125. subStageList.push(subStageResult[i].taskCount)
  126. subStageList.push(subStageResult[i].totalPlannedResource)
  127. subStageList.push(subStageResult[i].totalActualResourcesSpent)
  128. firstT = false
  129. }
  130. if (subStageResult[i].id === tID) {
  131. subStageList.push(subStageResult[i].plannedResources)
  132. subStageList.push(subStageResult[i].actualResourcesSpent)
  133. }
  134. }
  135. console.log(subStageFullList)
  136. for (var i = 0; i < mainStageResult.length; i++) {
  137. if (mainStageResult[i].id !== tgID) {
  138. mainStageFullList.push(createData(mainStageList,subStageFullList[arrayNumber]))
  139. arrayNumber += 1
  140. tgID = mainStageResult[i].id
  141. firstTg = true
  142. mainStageList = []
  143. }
  144. if (firstTg === true) {
  145. mainStageList.push(mainStageResult[i].name)
  146. mainStageList.push(mainStageResult[i].taskCount)
  147. mainStageList.push(mainStageResult[i].totalPlannedResources)
  148. mainStageList.push(mainStageResult[i].totalActualResourcesSpent)
  149. firstTg = false
  150. }
  151. if (mainStageResult[i].id === tgID) {
  152. mainStageList.push(mainStageResult[i].plannedResources)
  153. mainStageList.push(mainStageResult[i].actualResourcesSpent)
  154. }
  155. }
  156. setRows(mainStageFullList)
  157. }
  158. }
  159. useEffect(() => {
  160. fetchData()
  161. }, [projectId]);
  162. function createTaskData(stage:any, taskCount:any, g1Planned:any, g1Actual:any, g2Planned:any, g2Actual:any, g3Planned:any, g3Actual:any, g4Planned:any, g4Actual:any, g5Planned:any, g5Actual:any, totalPlanned:any, totalActual:any) {
  163. return {
  164. stage,
  165. taskCount,
  166. g1Planned,
  167. g1Actual,
  168. g2Planned,
  169. g2Actual,
  170. g3Planned,
  171. g3Actual,
  172. g4Planned,
  173. g4Actual,
  174. g5Planned,
  175. g5Actual,
  176. totalPlanned,
  177. totalActual,
  178. }
  179. }
  180. const task1Rows:any = [
  181. {stage:"1.1 Preparation of preliminary...",taskCount:"-",g1Planned:"-",g1Actual:"172.00",g2Planned:"-", g2Actual:"54.00", g3Planned:"-", g3Actual:"42.00", g4Planned: "-", g4Actual:"12.00", g5Planned:"-", g5Actual:"3.00", totalPlanned:"-", totalActual:"283.00"},
  182. {stage:"1.2 Cash flow forecast",taskCount:"-",g1Planned:"-",g1Actual:"172.00",g2Planned:"-", g2Actual:"54.00", g3Planned:"-", g3Actual:"42.00", g4Planned: "-", g4Actual:"12.00", g5Planned:"-", g5Actual:"3.00", totalPlanned:"-", totalActual:"283.00"},
  183. {stage:"1.3 Cost studies for alterative design solutions",taskCount:"-",g1Planned:"-",g1Actual:"115.00",g2Planned:"-", g2Actual:"36.00", g3Planned:"-", g3Actual:"28.00", g4Planned: "-", g4Actual:"7.00", g5Planned:"-", g5Actual:"1.75", totalPlanned:"-", totalActual:"188.00"},
  184. {stage:"1.4 Attend design co-ordiantion / project",taskCount:"-",g1Planned:"-",g1Actual:"29.00",g2Planned:"-", g2Actual:"9.00", g3Planned:"-", g3Actual:"7.00", g4Planned: "-", g4Actual:"2.00", g5Planned:"-", g5Actual:"1.00", totalPlanned:"-", totalActual:"48.00"},
  185. {stage:"1.5 Prepare / Review RIC",taskCount:"-",g1Planned:"-",g1Actual:"88.00",g2Planned:"-", g2Actual:"27.00", g3Planned:"-", g3Actual:"21.00", g4Planned: "-", g4Actual:"5.00", g5Planned:"-", g5Actual:"1.00", totalPlanned:"-", totalActual:"141.75"}
  186. ]
  187. const data:any = [
  188. "Stage 1 - Design & Cost Planning / Estimating",
  189. "5",
  190. "576.00",
  191. "576.00",
  192. "192.00",
  193. "180.00",
  194. "144.00",
  195. "140.00",
  196. "38.40",
  197. "38.00",
  198. "9.60",
  199. "9.75",
  200. "960.00",
  201. "943.75",
  202. ];
  203. // const rows = [
  204. // createData(data,task1Rows),
  205. // // createData("Stage 2 - Tender Documentation","11", "384.00", "382.00", "128.00", "130.00", "96.00", "79.00", "25.60", "25.00", "6.40", "4.00", "640.00", "620.00",task2Rows),
  206. // // createData("Stage 3 - Tender Analysis & Report & Contract Documentation","7", "384.00", "300.00", "128.00", "130.00", "96.00", "79.00", "25.60", "25.00", "6.40", "4.00", "640.00", "538.00",task3Rows),
  207. // // createData("Stage 4 - Construction", "13", "480.00", "400.00", "160.00", "160.00", "120.00", "128.00", "32.00", "25.00", "8.00", "3.00", "800.00", "716.00",task4Rows),
  208. // // createData("Stage 5 - Miscellaneous", "4", "96.00", "-", "32.00", "-", "24.00", "-0", "6.40", "-", "1.600", "-", "160.00", "-",task5Rows),
  209. // // createData("","Total", "1920.00", "1658.00", "640.00", "600.00", "480.00", "426.00", "128.00", "113.00", "32.00", "20.75", "3,200.00", "2817.75",task6Rows),
  210. // ];
  211. // const taskRows = [
  212. // createTaskData("1.1 Preparation of preliminary...","-","-","172.00","-","54.00","-","42.00","-","12.00","-","3.00","-","283.00"),
  213. // ];
  214. function Row(props:any) {
  215. const { row } = props;
  216. const [open, setOpen] = React.useState(false);
  217. return (
  218. <React.Fragment>
  219. <TableRow sx={{ '& > *': { borderBottom: 'unset' } }}>
  220. <TableCell>
  221. {row.task.length > 0 && (
  222. <IconButton
  223. aria-label="expand row"
  224. size="small"
  225. onClick={() => setOpen(!open)}
  226. >
  227. {open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
  228. </IconButton>
  229. )}
  230. </TableCell>
  231. <TableCell style={{fontSize:10}}>{row.stage}</TableCell>
  232. <TableCell style={{fontSize:10}}>{row.taskCount}</TableCell>
  233. <TableCell style={{fontSize:10}}>{row.g1Planned.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  234. <TableCell style={{fontSize:10}}>{row.g1Actual.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  235. <TableCell style={{fontSize:10}}>{row.g2Planned.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  236. <TableCell style={{fontSize:10}}>{row.g2Actual.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  237. <TableCell style={{fontSize:10}}>{row.g3Planned.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  238. <TableCell style={{fontSize:10}}>{row.g3Actual.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  239. <TableCell style={{fontSize:10}}>{row.g4Planned.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  240. <TableCell style={{fontSize:10}}>{row.g4Actual.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  241. <TableCell style={{fontSize:10}}>{row.g5Planned.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  242. <TableCell style={{fontSize:10}}>{row.g5Actual.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  243. <TableCell style={{fontSize:10}}>{row.totalPlanned.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  244. <TableCell style={{fontSize:10}}>{row.totalActual.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  245. </TableRow>
  246. {row.task.map((taskRow:any) => (
  247. <TableRow key={taskRow[0]} style={{backgroundColor:"#f0f3f7"}}>
  248. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  249. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  250. <Box sx={{ margin: 0 }}>
  251. <Table size="small" aria-label="tasks">
  252. <TableBody>
  253. <TableRow>
  254. <TableCell colSpan={1}/>
  255. </TableRow>
  256. </TableBody>
  257. </Table>
  258. </Box>
  259. </Collapse>
  260. </TableCell>
  261. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  262. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  263. <Box sx={{ margin: 0 }}>
  264. <Table size="small" aria-label="tasks">
  265. <TableBody>
  266. <TableRow>
  267. <TableCell style={{fontSize:10}} colSpan={1}>{taskRow[0]}</TableCell>
  268. </TableRow>
  269. </TableBody>
  270. </Table>
  271. </Box>
  272. </Collapse>
  273. </TableCell>
  274. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  275. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  276. <Box sx={{ margin: 0 }}>
  277. <Table size="small" aria-label="tasks">
  278. <TableBody>
  279. <TableRow>
  280. <TableCell style={{fontSize:10}} colSpan={1}>{taskRow[1]}</TableCell>
  281. </TableRow>
  282. </TableBody>
  283. </Table>
  284. </Box>
  285. </Collapse>
  286. </TableCell>
  287. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  288. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  289. <Box sx={{ margin: 0 }}>
  290. <Table size="small" aria-label="tasks">
  291. <TableBody>
  292. <TableRow>
  293. <TableCell style={{fontSize:10}} colSpan={1}>{taskRow[4].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  294. </TableRow>
  295. </TableBody>
  296. </Table>
  297. </Box>
  298. </Collapse>
  299. </TableCell>
  300. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  301. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  302. <Box sx={{ margin: 0 }}>
  303. <Table size="small" aria-label="tasks">
  304. <TableBody>
  305. <TableRow>
  306. <TableCell style={{fontSize:10}} colSpan={1}>{taskRow[5].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  307. </TableRow>
  308. </TableBody>
  309. </Table>
  310. </Box>
  311. </Collapse>
  312. </TableCell>
  313. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  314. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  315. <Box sx={{ margin: 0 }}>
  316. <Table size="small" aria-label="tasks">
  317. <TableBody>
  318. <TableRow>
  319. <TableCell style={{fontSize:10}} colSpan={1}>{taskRow[6].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  320. </TableRow>
  321. </TableBody>
  322. </Table>
  323. </Box>
  324. </Collapse>
  325. </TableCell>
  326. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  327. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  328. <Box sx={{ margin: 0 }}>
  329. <Table size="small" aria-label="tasks">
  330. <TableBody>
  331. <TableRow>
  332. <TableCell style={{fontSize:10}} colSpan={1}>{taskRow[7].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  333. </TableRow>
  334. </TableBody>
  335. </Table>
  336. </Box>
  337. </Collapse>
  338. </TableCell>
  339. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  340. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  341. <Box sx={{ margin: 0 }}>
  342. <Table size="small" aria-label="tasks">
  343. <TableBody>
  344. <TableRow>
  345. <TableCell style={{fontSize:10}} colSpan={1}>{taskRow[8].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  346. </TableRow>
  347. </TableBody>
  348. </Table>
  349. </Box>
  350. </Collapse>
  351. </TableCell>
  352. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  353. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  354. <Box sx={{ margin: 0 }}>
  355. <Table size="small" aria-label="tasks">
  356. <TableBody>
  357. <TableRow>
  358. <TableCell style={{fontSize:10}} colSpan={1}>{taskRow[9].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  359. </TableRow>
  360. </TableBody>
  361. </Table>
  362. </Box>
  363. </Collapse>
  364. </TableCell>
  365. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  366. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  367. <Box sx={{ margin: 0 }}>
  368. <Table size="small" aria-label="tasks">
  369. <TableBody>
  370. <TableRow>
  371. <TableCell style={{fontSize:10}} colSpan={1}>{taskRow[10].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  372. </TableRow>
  373. </TableBody>
  374. </Table>
  375. </Box>
  376. </Collapse>
  377. </TableCell>
  378. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  379. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  380. <Box sx={{ margin: 0 }}>
  381. <Table size="small" aria-label="tasks">
  382. <TableBody>
  383. <TableRow>
  384. <TableCell style={{fontSize:10}} colSpan={1}>{taskRow[11].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  385. </TableRow>
  386. </TableBody>
  387. </Table>
  388. </Box>
  389. </Collapse>
  390. </TableCell>
  391. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  392. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  393. <Box sx={{ margin: 0 }}>
  394. <Table size="small" aria-label="tasks">
  395. <TableBody>
  396. <TableRow>
  397. <TableCell style={{fontSize:10}} colSpan={1}>{taskRow[12].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  398. </TableRow>
  399. </TableBody>
  400. </Table>
  401. </Box>
  402. </Collapse>
  403. </TableCell>
  404. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  405. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  406. <Box sx={{ margin: 0 }}>
  407. <Table size="small" aria-label="tasks">
  408. <TableBody>
  409. <TableRow>
  410. <TableCell style={{fontSize:10}} colSpan={1}>{taskRow[13].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  411. </TableRow>
  412. </TableBody>
  413. </Table>
  414. </Box>
  415. </Collapse>
  416. </TableCell>
  417. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  418. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  419. <Box sx={{ margin: 0 }}>
  420. <Table size="small" aria-label="tasks">
  421. <TableBody>
  422. <TableRow>
  423. <TableCell style={{fontSize:10}} colSpan={1}>{taskRow[2].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  424. </TableRow>
  425. </TableBody>
  426. </Table>
  427. </Box>
  428. </Collapse>
  429. </TableCell>
  430. <TableCell style={{ paddingBottom: 0, paddingTop: 0}} colSpan={1}>
  431. <Collapse in={open} timeout="auto" unmountOnExit style={{marginLeft:-17, marginRight:-17}}>
  432. <Box sx={{ margin: 0 }}>
  433. <Table size="small" aria-label="tasks">
  434. <TableBody>
  435. <TableRow>
  436. <TableCell style={{fontSize:10}} colSpan={1}>{taskRow[3].toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</TableCell>
  437. </TableRow>
  438. </TableBody>
  439. </Table>
  440. </Box>
  441. </Collapse>
  442. </TableCell>
  443. </TableRow>
  444. ))}
  445. </React.Fragment>
  446. );
  447. }
  448. const projectResourcesRows = [
  449. {id: 1,stage:"Stage 1 - Design & Cost Planning / Estimating",taskCount:"5",g1Planned:"576.00",g1Actual:"576.00",g2Planned:"192.00", g2Actual:"180.00", g3Planned:"144.00", g3Actual:"140.00", g4Planned: "38.40", g4Actual:"38S.00", g5Planned:"9.60", g5Actual:"9.75", totalPlanned:"960.00", totalActual:"943.75"},
  450. {id: 2,stage:"1.1 Preparation of preliminary...",taskCount:"-",g1Planned:"-",g1Actual:"172.00",g2Planned:"-", g2Actual:"54.00", g3Planned:"-", g3Actual:"42.00", g4Planned: "-", g4Actual:"12.00", g5Planned:"-", g5Actual:"3.00", totalPlanned:"-", totalActual:"283.00"},
  451. {id: 3,stage:"1.2 Cash flow forecast",taskCount:"-",g1Planned:"-",g1Actual:"172.00",g2Planned:"-", g2Actual:"54.00", g3Planned:"-", g3Actual:"42.00", g4Planned: "-", g4Actual:"12.00", g5Planned:"-", g5Actual:"3.00", totalPlanned:"-", totalActual:"283.00"},
  452. {id: 4,stage:"1.3 Cost studies for alterative design solutions",taskCount:"-",g1Planned:"-",g1Actual:"115.00",g2Planned:"-", g2Actual:"36.00", g3Planned:"-", g3Actual:"28.00", g4Planned: "-", g4Actual:"7.00", g5Planned:"-", g5Actual:"1.75", totalPlanned:"-", totalActual:"188.00"},
  453. {id: 5,stage:"1.4 Attend design co-ordiantion / project",taskCount:"-",g1Planned:"-",g1Actual:"29.00",g2Planned:"-", g2Actual:"9.00", g3Planned:"-", g3Actual:"7.00", g4Planned: "-", g4Actual:"2.00", g5Planned:"-", g5Actual:"1.00", totalPlanned:"-", totalActual:"48.00"},
  454. {id: 6,stage:"1.5 Prepare / Review RIC",taskCount:"-",g1Planned:"-",g1Actual:"88.00",g2Planned:"-", g2Actual:"27.00", g3Planned:"-", g3Actual:"21.00", g4Planned: "-", g4Actual:"5.00", g5Planned:"-", g5Actual:"1.00", totalPlanned:"-", totalActual:"141.75"},
  455. {id: 7,stage:"Stage 2 - Tender Documentation",taskCount:"11",g1Planned:"384.00",g1Actual:"382.00",g2Planned:"128.00", g2Actual:"130.00", g3Planned:"96.00", g3Actual:"79.00", g4Planned: "25.60", g4Actual:"25.00", g5Planned:"6.40", g5Actual:"4.00", totalPlanned:"640.00", totalActual:"620.00"},
  456. {id: 8,stage:"Stage 3 - Tender Analysis & Report & Contract Documentation",taskCount:"7",g1Planned:"384.00",g1Actual:"300.00",g2Planned:"128.00", g2Actual:"130.00", g3Planned:"96.00", g3Actual:"79.00", g4Planned: "25.60", g4Actual:"25.00", g5Planned:"6.40", g5Actual:"4.00", totalPlanned:"640.00", totalActual:"538.00"},
  457. {id: 9,stage:"Stage 4 - Construction",taskCount:"13",g1Planned:"480.00",g1Actual:"400.00",g2Planned:"160.00", g2Actual:"160.00", g3Planned:"120.00", g3Actual:"128.00", g4Planned: "32.00", g4Actual:"25.00", g5Planned:"8.00", g5Actual:"3.00", totalPlanned:"800.00", totalActual:"716.00"},
  458. {id: 10,stage:"Stage 5 - Miscellaneous",taskCount:"4",g1Planned:"96.00",g1Actual:"-",g2Planned:"32.00", g2Actual:"-", g3Planned:"24.00", g3Actual:"-0", g4Planned: "6.40", g4Actual:"-", g5Planned:"1.600", g5Actual:"-", totalPlanned:"160.00", totalActual:"-"},
  459. {id: 11,stage:"",taskCount:"Total",g1Planned:"1920.00",g1Actual:"1658.00",g2Planned:"640.00", g2Actual:"600.00", g3Planned:"480.00", g3Actual:"426.00", g4Planned: "128.00", g4Actual:"113.00", g5Planned:"32.00", g5Actual:"20.75", totalPlanned:"3,200.00", totalActual:"2817.75"},
  460. ]
  461. const columns2 = [
  462. {
  463. id: 'stage',
  464. field: 'stage',
  465. headerName: "Stage",
  466. flex: 2,
  467. },
  468. {
  469. id: 'taskCount',
  470. field: 'taskCount',
  471. headerName: "Task Count",
  472. flex: 0.5,
  473. },
  474. {
  475. id: 'g1Planned',
  476. field: 'g1Planned',
  477. headerName: "Planned",
  478. flex: 0.7,
  479. },
  480. {
  481. id: 'g1Actual',
  482. field: 'g1Actual',
  483. headerName: "Actual",
  484. flex: 0.7,
  485. },
  486. {
  487. id: 'g2Planned',
  488. field: 'g2Planned',
  489. headerName: "Planned",
  490. flex: 0.7,
  491. },
  492. {
  493. id: 'g2Actual',
  494. field: 'g2Actual',
  495. headerName: "Actual",
  496. flex: 0.7,
  497. },
  498. {
  499. id: 'g3Planned',
  500. field: 'g3Planned',
  501. headerName: "Planned",
  502. flex: 0.7,
  503. },
  504. {
  505. id: 'g3Actual',
  506. field: 'g3Actual',
  507. headerName: "Actual",
  508. flex: 0.7,
  509. },
  510. {
  511. id: 'g4Planned',
  512. field: 'g4Planned',
  513. headerName: "Planned",
  514. flex: 0.7,
  515. },
  516. {
  517. id: 'g4Actual',
  518. field: 'g4Actual',
  519. headerName: "Actual",
  520. flex: 0.7,
  521. },
  522. {
  523. id: 'g5Planned',
  524. field: 'g5Planned',
  525. headerName: "Planned",
  526. flex: 0.7,
  527. },
  528. {
  529. id: 'g5Actual',
  530. field: 'g5Actual',
  531. headerName: "Actual",
  532. flex: 0.7,
  533. },
  534. {
  535. id: 'totalPlanned',
  536. field: 'totalPlanned',
  537. headerName: "Planned",
  538. flex: 0.7,
  539. },
  540. {
  541. id: 'totalActual',
  542. field: 'totalActual',
  543. headerName: "Actual",
  544. flex: 0.7,
  545. },
  546. ];
  547. const columnGroupingModel = [
  548. {
  549. groupId: 'G1',
  550. children: [{ field: 'g1Planned' },{ field: 'g1Actual' }],
  551. headerClassName: 'groupColor',
  552. },
  553. {
  554. groupId: 'G2',
  555. children: [{ field: 'g2Planned' },{ field: 'g2Actual' }],
  556. headerClassName: 'groupColor',
  557. },
  558. {
  559. groupId: 'G3',
  560. children: [{ field: 'g3Planned' },{ field: 'g3Actual' }],
  561. headerClassName: 'groupColor',
  562. },
  563. {
  564. groupId: 'G4',
  565. children: [{ field: 'g4Planned' },{ field: 'g4Actual' }],
  566. headerClassName: 'groupColor',
  567. },
  568. {
  569. groupId: 'G5',
  570. children: [{ field: 'g5Planned' },{ field: 'g5Actual' }],
  571. headerClassName: 'groupColor',
  572. },
  573. {
  574. groupId: 'Total',
  575. children: [{ field: 'totalPlanned' },{ field: 'totalActual' }],
  576. headerClassName: 'totalGroupColor',
  577. },
  578. ];
  579. return (
  580. <Grid item sm sx={{
  581. '& .groupColor': {
  582. backgroundColor: 'rgba(240, 240, 240, 0.55)',
  583. },
  584. '& .totalGroupColor': {
  585. backgroundColor: 'rgba(218, 218, 245, 0.55)',
  586. },
  587. }}>
  588. <Card className="mt-5">
  589. <CardHeader className="text-slate-500" title="Project Information"/>
  590. <div className="ml-6 mr-6">
  591. <div style={{ display: "inline-block", width: "33%"}}>
  592. <div style={{fontSize:"1em", fontWeight:"bold"}}>
  593. <u>
  594. Project
  595. </u>
  596. </div>
  597. <div style={{fontSize:"1em"}}>
  598. {projectName}
  599. </div>
  600. </div>
  601. <div style={{ display: "inline-block", width: "33%"}}>
  602. <div style={{ fontSize:"1em", fontWeight:"bold"}}>
  603. <u>
  604. Project Fee
  605. </u>
  606. </div>
  607. <div style={{fontSize:"1em"}}>
  608. HKD ${projectFee.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
  609. </div>
  610. </div>
  611. <div style={{ display: "inline-block", width: "33%"}}>
  612. <div style={{ fontSize:"1em", fontWeight:"bold"}}>
  613. <u>
  614. Status
  615. </u>
  616. </div>
  617. <div style={{fontSize:"1em"}}>
  618. {status}
  619. </div>
  620. </div>
  621. <div style={{ display: "inline-block", width: "33%"}}>
  622. <div style={{ fontSize:"1em", fontWeight:"bold"}}>
  623. <u>
  624. Planned Resources
  625. </u>
  626. </div>
  627. <div style={{fontSize:"1em"}}>
  628. {plannedResources.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} Manhours
  629. </div>
  630. </div>
  631. <div style={{ display: "inline-block", width: "33%"}}>
  632. <div style={{ fontSize:"1em", fontWeight:"bold"}}>
  633. <u>
  634. Actual Resources Spent
  635. </u>
  636. </div>
  637. <div style={{fontSize:"1em"}}>
  638. {actualResourcesSpent.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} Manhours
  639. </div>
  640. </div>
  641. <div style={{ display: "inline-block", width: "33%"}}>
  642. <div style={{ fontSize:"1em", fontWeight:"bold"}}>
  643. <u>
  644. Remaining Resources
  645. </u>
  646. </div>
  647. <div style={{fontSize:"1em"}}>
  648. {remainingResources.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} Manhours
  649. </div>
  650. </div>
  651. </div>
  652. {/* <div style={{display:"inline-block",width:"99%",marginLeft:10}}>
  653. <CustomDatagrid rows={projectResourcesRows} columns={columns2} columnWidth={200} dataGridHeight={480} pageSize={100} columnGroupingModel={columnGroupingModel} sx={{fontSize:10}}/>
  654. </div> */}
  655. {/* <div style={{display:"inline-block",width:"99%",marginLeft:10, marginRight:10, marginTop:10}}> */}
  656. <TableContainer component={Paper}>
  657. <Table sx={{ minWidth: 650 }} aria-label="simple table">
  658. <TableHead>
  659. <TableRow>
  660. <TableCell align="center" colSpan={3}>
  661. </TableCell>
  662. <TableCell align="center" colSpan={2}>
  663. G1
  664. </TableCell>
  665. <TableCell align="center" colSpan={2}>
  666. G2
  667. </TableCell>
  668. <TableCell align="center" colSpan={2}>
  669. G3
  670. </TableCell>
  671. <TableCell align="center" colSpan={2}>
  672. G4
  673. </TableCell>
  674. <TableCell align="center" colSpan={2}>
  675. G5
  676. </TableCell>
  677. <TableCell align="center" colSpan={2} style={{backgroundColor:"rgba(218, 218, 245, 0.55)"}}>
  678. Total
  679. </TableCell>
  680. </TableRow>
  681. <TableRow>
  682. <TableCell style={{width:"5%"}}/>
  683. <TableCell style={{fontSize:10, width:"20%"}}>Stage</TableCell>
  684. <TableCell style={{fontSize:10, width:"5%"}}>Task Count</TableCell>
  685. <TableCell style={{fontSize:10, width:"5%"}}>Planned</TableCell>
  686. <TableCell style={{fontSize:10, width:"5%"}}>Actual</TableCell>
  687. <TableCell style={{fontSize:10, width:"5%"}}>Planned</TableCell>
  688. <TableCell style={{fontSize:10, width:"5%"}}>Actual</TableCell>
  689. <TableCell style={{fontSize:10, width:"5%"}}>Planned</TableCell>
  690. <TableCell style={{fontSize:10, width:"5%"}}>Actual</TableCell>
  691. <TableCell style={{fontSize:10, width:"5%"}}>Planned</TableCell>
  692. <TableCell style={{fontSize:10, width:"5%"}}>Actual</TableCell>
  693. <TableCell style={{fontSize:10, width:"5%"}}>Planned</TableCell>
  694. <TableCell style={{fontSize:10, width:"5%"}}>Actual</TableCell>
  695. <TableCell style={{fontSize:10, width:"5%"}}>Planned</TableCell>
  696. <TableCell style={{fontSize:10, width:"5%"}}>Actual</TableCell>
  697. </TableRow>
  698. </TableHead>
  699. <TableBody>
  700. {rows.map((row:any) => (
  701. <Row key={row.stage} row={row} />
  702. ))}
  703. </TableBody>
  704. </Table>
  705. </TableContainer>
  706. {/* </div> */}
  707. </Card>
  708. </Grid>
  709. );
  710. };
  711. export default ProjectResourceSummary;