|
|
|
@ -11,6 +11,7 @@ import 'antd/dist/antd.css';
|
|
|
|
|
import './style.css' |
|
|
|
|
import { Select, Table, Tooltip } from 'antd'; |
|
|
|
|
import DialogFormAnalysis from './DialogFormAnalysis'; |
|
|
|
|
import moment from "moment"; |
|
|
|
|
const { Option } = Select |
|
|
|
|
|
|
|
|
|
const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) => { |
|
|
|
@ -24,6 +25,7 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
const [dataTable, setDatatable] = useState([]); |
|
|
|
|
const [dataTableActivityToHr, setDataTableActivityToHr] = useState([]); |
|
|
|
|
const [hrList, setHrList] = useState([]); |
|
|
|
|
const [groupedActivity, setGroupedActivity] = useState([]); |
|
|
|
|
const [selectedHr, setSelectedHr] = useState(null); |
|
|
|
|
|
|
|
|
|
const toggle = (tab) => { |
|
|
|
@ -54,23 +56,88 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const columns = [ |
|
|
|
|
{title: "Activity", dataIndex: "name", key: "name"}, |
|
|
|
|
{title: "Gantt", dataIndex: "name_version", key: "name_version"}, |
|
|
|
|
{title: "Assign HR", dataIndex: "user_name", key: "user_name"}, |
|
|
|
|
{title: "Progress (%)", dataIndex: "persentase_progress", key: "persentase_progress"}, |
|
|
|
|
{title: "Volume Plan", dataIndex: "qty_planning", key: "qty_planning", |
|
|
|
|
render: (text, record) => |
|
|
|
|
<> |
|
|
|
|
{text ? text : 0} |
|
|
|
|
</> |
|
|
|
|
}, |
|
|
|
|
{title: "Volume Actual", dataIndex: "qty", key: "qty"}, |
|
|
|
|
{title: "Progress Plan (%)", dataIndex: "persentase_progress", key: "persentase_progress", |
|
|
|
|
render: (text, record) => { |
|
|
|
|
const startDate = moment(record.start_date); |
|
|
|
|
const duration = record.duration; |
|
|
|
|
|
|
|
|
|
const currentDate = moment(); |
|
|
|
|
const daysElapsed = Math.max(0, currentDate.diff(startDate, 'days')); |
|
|
|
|
const progressPercentage = Math.min(100, (daysElapsed / duration) * 100); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<> |
|
|
|
|
{progressPercentage.toFixed(0)} |
|
|
|
|
</> |
|
|
|
|
); |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
{title: "Progress Actual (%)", dataIndex: "persentase_progress", key: "persentase_progress"}, |
|
|
|
|
{ |
|
|
|
|
title: 'Action', |
|
|
|
|
dataIndex: '', |
|
|
|
|
key: 'id', |
|
|
|
|
className: "nowrap", |
|
|
|
|
render: (text, record) => |
|
|
|
|
<> |
|
|
|
|
<Tooltip title="Detail Activity"> |
|
|
|
|
<Button size={"sm"} color='primary' onClick={() => handleDetail(text)}><i className="fa fa-eye"></i></Button> |
|
|
|
|
</Tooltip>{" "} |
|
|
|
|
</> |
|
|
|
|
, |
|
|
|
|
}, |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
const columnActivityToHr = [ |
|
|
|
|
{title: "Activity", dataIndex: "join_second_name", key: "join_second_name"}, |
|
|
|
|
{title: "Gantt", dataIndex: "join_fourth_name_version", key: "join_fourth_name_version"}, |
|
|
|
|
{title: "Assign HR", dataIndex: "join_first_name", key: "join_first_name"}, |
|
|
|
|
{title: "Material Plan", dataIndex: "join_third_qty_planning", key: "join_third_qty_planning", |
|
|
|
|
{title: "Start Date", dataIndex: "start_date", key: "start_date", |
|
|
|
|
render: (text, record) => ( |
|
|
|
|
<> |
|
|
|
|
{moment(record.start_date).format("DD-MM-YYYY")} |
|
|
|
|
</> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
|
{title: "End Date", dataIndex: "end_date", key: "end_date", |
|
|
|
|
render: (text, record) => ( |
|
|
|
|
<> |
|
|
|
|
{moment(record.end_date).format("DD-MM-YYYY")} |
|
|
|
|
</> |
|
|
|
|
), |
|
|
|
|
}, |
|
|
|
|
{title: "Volume Plan", dataIndex: "join_third_qty_planning", key: "join_third_qty_planning", |
|
|
|
|
render: (text, record) => |
|
|
|
|
<> |
|
|
|
|
{text ? text : 0} |
|
|
|
|
</> |
|
|
|
|
}, |
|
|
|
|
{title: "Progress (%)", dataIndex: "join_second_persentase_progress", key: "persentase_progress"}, |
|
|
|
|
{title: "Volume Actual", dataIndex: "volume_actual", key: "volume_actual"}, |
|
|
|
|
{title: "Progress Plan (%)", dataIndex: "join_second_persentase_progress", key: "persentase_progress", |
|
|
|
|
render: (text, record) => { |
|
|
|
|
const startDate = moment(record.join_second_start_date); |
|
|
|
|
const duration = record.join_second_duration; |
|
|
|
|
|
|
|
|
|
const currentDate = moment(); |
|
|
|
|
const daysElapsed = Math.max(0, currentDate.diff(startDate, 'days')); |
|
|
|
|
const progressPercentage = Math.min(100, (daysElapsed / duration) * 100); |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<> |
|
|
|
|
{progressPercentage.toFixed(0)} |
|
|
|
|
</> |
|
|
|
|
); |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
{title: "Progress Actual (%)", dataIndex: "join_second_persentase_progress", key: "persentase_progress"}, |
|
|
|
|
{ |
|
|
|
|
title: 'Action', |
|
|
|
|
dataIndex: '', |
|
|
|
@ -102,6 +169,23 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
getDataHr() |
|
|
|
|
}, []); |
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
if (projectId) { |
|
|
|
|
getGroupedActivity() |
|
|
|
|
getDataHr() |
|
|
|
|
} |
|
|
|
|
}, [projectId]); |
|
|
|
|
|
|
|
|
|
const handleClose = () => { |
|
|
|
|
setAvgActivityHr(0); |
|
|
|
|
setSelectedHr(null); |
|
|
|
|
setDataTableActivityToHr([]); |
|
|
|
|
setAvgActivity(0); |
|
|
|
|
setSearch(''); |
|
|
|
|
setDatatable([]) |
|
|
|
|
closeDialog() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const handleSearch = (e) => { |
|
|
|
|
const value = e.target.value; |
|
|
|
|
setSearch(value); |
|
|
|
@ -131,8 +215,27 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const getDataHr = async () => { |
|
|
|
|
const payload = { |
|
|
|
|
columns: [ |
|
|
|
|
{ |
|
|
|
|
name: "proyek_id", |
|
|
|
|
logic_operator: "=", |
|
|
|
|
value: projectId, |
|
|
|
|
operator: "AND", |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
joins: [ |
|
|
|
|
{ |
|
|
|
|
name: "m_users", |
|
|
|
|
column_join: "user_id", |
|
|
|
|
column_results: ["id", "name"] |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
orders: { columns: ["id"], ascending: false }, |
|
|
|
|
paging: { start: 0, length: -1 }, |
|
|
|
|
}; |
|
|
|
|
const result = await axios |
|
|
|
|
.get(`${BASE_SIMPRO_LUMEN}/human-resource/list`, HEADER) |
|
|
|
|
.post(`${BASE_SIMPRO_LUMEN}/user-to-proyek/search`, payload, HEADER) |
|
|
|
|
.then((res) => res) |
|
|
|
|
.catch((error) => error.response); |
|
|
|
|
|
|
|
|
@ -145,6 +248,7 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
} |
|
|
|
|
const getDataActivityToHr = async () => { |
|
|
|
|
setAvgActivityHr(0); |
|
|
|
|
setDataTableActivityToHr([]); |
|
|
|
|
let sum = 0; |
|
|
|
|
const payload = { |
|
|
|
|
columns: [ |
|
|
|
@ -162,16 +266,20 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
operator: "AND", |
|
|
|
|
} |
|
|
|
|
], |
|
|
|
|
select: [ |
|
|
|
|
'id', |
|
|
|
|
'start_date', |
|
|
|
|
'end_date' |
|
|
|
|
], |
|
|
|
|
joins: [ |
|
|
|
|
{ |
|
|
|
|
name: "m_users", |
|
|
|
|
column_join: "user_id", |
|
|
|
|
column_results: ["name"] |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
name: "m_activity", |
|
|
|
|
column_join: "activity_id", |
|
|
|
|
column_results: ["name", "persentase_progress"] |
|
|
|
|
column_results: ["name", "persentase_progress", "start_date", "end_date", "duration"] |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
name1: "m_activity", |
|
|
|
@ -187,6 +295,12 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
column_self:"id", |
|
|
|
|
column_results: ["name_version"] |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
name1: "m_activity", |
|
|
|
|
name: "report_activity_material", |
|
|
|
|
column_join: "id", |
|
|
|
|
column_self:"activity_id", |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
orders: { columns: ["id"], ascending: false }, |
|
|
|
|
paging: { start: 0, length: -1 }, |
|
|
|
@ -209,14 +323,42 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const getGroupedActivity = async () => { |
|
|
|
|
const payload = { |
|
|
|
|
columns: [ |
|
|
|
|
{ |
|
|
|
|
name: "proyek_id", |
|
|
|
|
logic_operator: "=", |
|
|
|
|
value: projectId, |
|
|
|
|
operator: "AND", |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
orders: { columns: ["id"], ascending: false }, |
|
|
|
|
paging: { start: 0, length: -1 }, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const result = await axios |
|
|
|
|
.post(`${BASE_SIMPRO_LUMEN}/activity/search-analysis-prep`, payload, HEADER) |
|
|
|
|
.then((res) => res) |
|
|
|
|
.catch((error) => error.response); |
|
|
|
|
|
|
|
|
|
if (result && result.data && result.data.code == 200) { |
|
|
|
|
let dataRes = result.data.data || []; |
|
|
|
|
setGroupedActivity(dataRes); |
|
|
|
|
} else { |
|
|
|
|
NotificationManager.error("Gagal Mengambil Data!!", "Failed"); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const getDataActivity = async () => { |
|
|
|
|
setAvgActivity(0); |
|
|
|
|
setDatatable([]); |
|
|
|
|
let sum = 0; |
|
|
|
|
const payload = { |
|
|
|
|
columns: [ |
|
|
|
|
{ |
|
|
|
|
name: "name", |
|
|
|
|
logic_operator: "ilike", |
|
|
|
|
logic_operator: "=", |
|
|
|
|
value: search, |
|
|
|
|
operator: "AND", |
|
|
|
|
}, |
|
|
|
@ -251,7 +393,7 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
return ( |
|
|
|
|
<> |
|
|
|
|
<Modal size="xl" isOpen={openDialog} toggle={toggleDialog}> |
|
|
|
|
<ModalHeader className="capitalize" toggle={closeDialog}>Report Analysis</ModalHeader> |
|
|
|
|
<ModalHeader className="capitalize" toggle={handleClose}>Report Analysis</ModalHeader> |
|
|
|
|
<ModalBody> |
|
|
|
|
<div> |
|
|
|
|
<Nav tabs> |
|
|
|
@ -282,15 +424,13 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
<CardHeader> |
|
|
|
|
<Row> |
|
|
|
|
<Col> |
|
|
|
|
<Input |
|
|
|
|
onChange={handleSearch} |
|
|
|
|
value={search} |
|
|
|
|
type="text" |
|
|
|
|
name="search" |
|
|
|
|
id="search" |
|
|
|
|
placeholder={`Search Activity Name`} |
|
|
|
|
style={{ width: 200 }} |
|
|
|
|
/> |
|
|
|
|
<Select showSearch value={search} onChange={(val) => setSearch(val)} placeholder="Select Activity" filterOption={(input, option) => |
|
|
|
|
option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 |
|
|
|
|
} style={{ width: 200 }}> |
|
|
|
|
{groupedActivity && groupedActivity.map((res, index) => ( |
|
|
|
|
<Option key={index} value={res.name}>{`${res.name}`}</Option> |
|
|
|
|
))} |
|
|
|
|
</Select> |
|
|
|
|
</Col> |
|
|
|
|
</Row> |
|
|
|
|
</CardHeader> |
|
|
|
@ -321,7 +461,7 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 |
|
|
|
|
} style={{ width: 200 }}> |
|
|
|
|
{hrList && hrList.map(res => ( |
|
|
|
|
<Option key={res.id} value={res.id}>{`${res.name}`}</Option> |
|
|
|
|
<Option key={res.join_first_id} value={res.join_first_id}>{`${res.join_first_name}`}</Option> |
|
|
|
|
))} |
|
|
|
|
</Select> |
|
|
|
|
</Col> |
|
|
|
@ -342,7 +482,7 @@ const ReportAnalysis = ({ openDialog, closeDialog, toggleDialog, projectId }) =>
|
|
|
|
|
</div> |
|
|
|
|
</ModalBody> |
|
|
|
|
<ModalFooter> |
|
|
|
|
<Button color="primary" onClick={closeDialog}>Close</Button> |
|
|
|
|
<Button color="primary" onClick={handleClose}>Close</Button> |
|
|
|
|
</ModalFooter> |
|
|
|
|
</Modal> |
|
|
|
|
<DialogFormAnalysis |
|
|
|
|