@@ -284,7 +413,7 @@ const DashboardCustomer = () => {
Customer
-
{customerName}
+
{isReadyProjectDetail ? customerName : }
@@ -302,18 +431,36 @@ const DashboardCustomer = () => {
- Planned Start
- {plannedStart ? moment(plannedStart).format('D MMMM YYYY') : '-'}
- Planned Finish
- {plannedFinish ? moment(plannedFinish).format('D MMMM YYYY') : '-'}
- Actual Finish
- {actualFinish ? moment(actualFinish).format('D MMMM YYYY') : '-'}
+ Planned Start
+
+ {isReadyProjectDetail ?
+ plannedStart ? moment(plannedStart).format('D MMMM YYYY') : '-'
+ :
+ }
+
+ Planned Finish
+
+ {isReadyProjectDetail ?
+ plannedFinish ? moment(plannedFinish).format('D MMMM YYYY') : '-'
+ :
+ }
+
- Actual Start
- {actualStart ? moment(actualStart).format('D MMMM YYYY') : '-'}
- Estimated Finish
- {estimatedFinish ? moment(estimatedFinish).format('D MMMM YYYY') : '-'}
+ Actual Start
+
+ {isReadyProjectDetail ?
+ actualStart ? moment(actualStart).format('D MMMM YYYY') : '-'
+ :
+ }
+
+ Estimated Finish
+
+ {isReadyProjectDetail ?
+ estimatedFinish ? moment(estimatedFinish).format('D MMMM YYYY') : '-'
+ :
+ }
+
@@ -347,12 +494,17 @@ const DashboardCustomer = () => {
Progress
-
-
Planning : {planningProgress}%
-
-
-
{actualProgress && actualProgress < 50 ? `${actualProgress}%` : `Actual : ${actualProgress}%` }
-
+ {isReadySCurve ?
+
+ :
+
+ }
+
+ {isReadySCurve ?
+
+ :
+
+ }
@@ -360,9 +512,7 @@ const DashboardCustomer = () => {
Health By Schedule
-
+ {isReadySCurve ?
:
}
diff --git a/src/views/Dashboard/DashboardProject.js b/src/views/Dashboard/DashboardProject.js
index 388ca3e..d6130a6 100644
--- a/src/views/Dashboard/DashboardProject.js
+++ b/src/views/Dashboard/DashboardProject.js
@@ -11,6 +11,7 @@ import { BASE_OSPRO } from '../../const/ApiConst';
import { SendOutlined } from '@ant-design/icons';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import ContentLoader from 'react-content-loader';
+import { BehindTaskItem, Comment, HealthByBudget, HealthBySchedule, ListLoader, PopupContent, ProgressActualBar, ProgressPlanningBar, SingleTextLoader } from './Components';
const { TextArea } = Input;
const styles = {
@@ -37,7 +38,8 @@ const DashboardProject = () => {
const { PROJECT_ID, GANTT_ID } = useParams();
// const URL_GANTT = `http://103.73.125.81:8446/index.html?base_url=http://103.73.125.81:8444/api&gantt_id=${GANTT_ID}&proyek_id=${PROJECT_ID}&token=${token}&ro=1`;
// const URL_GANTT = `https://adw-gantt.ospro.id/index.html?base_url=${BASE_OSPRO}/api&gantt_id=${GANTT_ID}&proyek_id=${PROJECT_ID}&token=${token}&ro=1`;
- const URL_GANTT = '';
+ // const URL_GANTT = '';
+ const URL_GANTT = `http://192.168.1.104:8446/view-mode/index.html?base_url=${BASE_OSPRO}/api&gantt_id=${GANTT_ID}&proyek_id=${PROJECT_ID}&token=${token}&ro=1`;
const mapRef = useRef()
const [projectName, setProjectName] = useState("");
const [projectManagerName, setProjectManagerName] = useState("");
@@ -50,8 +52,8 @@ const DashboardProject = () => {
const [mymap, setMymap] = useState(null);
const [activeTabIdx, setActiveTabIdx] = useState(0);
const [activeTabCommentIdx, setActiveTabCommentIdx] = useState(0);
- const [planningProgress, setPlanningProgress] = useState(79);
- const [actualProgress, setActualProgress] = useState(43);
+ const [planningProgress, setPlanningProgress] = useState(0);
+ const [actualProgress, setActualProgress] = useState(0);
const [currentBudget, setCurrentBudget] = useState(null)
const [addCostToComplete, setAddCostToComplete] = useState(null)
const [actualToDate, setActualToDate] = useState(null)
@@ -66,21 +68,23 @@ const DashboardProject = () => {
const [comments, setComments] = useState([]);
const [isReadyComments, setIsReadyComments] = useState(false);
const [isSendingComment, setIsSendingComment] = useState(false);
-
const [isReadyProjectDetail, setIsReadyProjectDetail] = useState(false);
const [isReadySCurve, setIsReadySCurve] = useState(false);
const [isReadyOverdueActivities, setIsReadyOverdueActivities] = useState(false);
+ const [isReadyIntegrationInvoice, setIsReadyIntegrationInvoice] = useState(false);
+ const [isReadyReportDistribution, setIsReadyReportDistribution] = useState(false);
const [overdueActivities, setOverdueActivities] = useState([]);
-
const [healthBySchedule, setHealthBySchedule] = useState('-')
const [healthByBudget, setHealthByBudget] = useState('-')
+ const [reportDistribution, setReportDistribution] = useState([]);
+
useEffect(() => {
- // console.log('URL_GANTT', URL_GANTT);
- getProjectDetail();
- getSCurve();
- getOverdueActivities();
- getComments();
+ getProjectDetail()
+ getSCurve()
+ getOverdueActivities()
+ getReportDistribution()
+ getComments()
return () => {
console.log('unmount RenderMap');
}
@@ -119,6 +123,10 @@ const DashboardProject = () => {
setActualStart(result.data.data.header?.start_date ? result.data.data.header.start_date : null)
setEstimatedFinish(result.data.data.header?.end_date ? result.data.data.header.end_date : null)
setIsReadyProjectDetail(true);
+
+ if (result.data.data.kode_sortname && result.data.data.kode_sortname !== '') {
+ getIntegrationInvoice(result.data.data.kode_sortname)
+ }
}
}
@@ -144,7 +152,10 @@ const DashboardProject = () => {
return;
}
else if (result.status == 200 && result.data.data) {
- console.log(result.data.data);
+ let selisihProgress = 0;
+ let planningProgress = 0;
+ let actualProgress = 0;
+ let statusHealthBySchedule = 'on-schedule';
if (result.data.data.length > 0 && result.data.data[0].data?.budget_control) {
setCurrentBudget(result.data.data[0].data.budget_control.current_budget?.toString())
setActualToDate(result.data.data[0].data.budget_control.acwp?.toString())
@@ -154,6 +165,24 @@ const DashboardProject = () => {
setEstAtCompletion(result.data.data[0].data.budget_control.estimated_at_completion?.toString())
setCostDeviation(result.data.data[0].data.budget_control.cost_deviation?.toString())
}
+ if (result.data.data.length > 0 && result.data.data[0].data?.percentagePlan && result.data.data[0].data?.percentagePlan.length > 0) {
+ let planningProgress = result.data.data[0].data?.percentagePlan[result.data.data[0].data?.percentagePlan.length-1];
+ setPlanningProgress(planningProgress);
+ }
+ if (result.data.data.length > 0 && result.data.data[0].data?.percentageReal && result.data.data[0].data?.percentageReal.length > 0) {
+ let actualProgress = result.data.data[0].data?.percentageReal[result.data.data[0].data?.percentageReal.length-1];
+ setActualProgress(actualProgress);
+ }
+
+ selisihProgress = planningProgress - actualProgress;
+ if (selisihProgress > 0 && selisihProgress <= 5) {
+ statusHealthBySchedule = 'warning'
+ }
+ else if (selisihProgress > 5) {
+ statusHealthBySchedule = 'danger'
+ }
+
+ setHealthBySchedule(statusHealthBySchedule)
setIsReadySCurve(true);
}
}
@@ -179,7 +208,6 @@ const DashboardProject = () => {
return;
}
else if (result.status == 200 && result.data.data) {
- console.log(result.data.data);
if (result.data.data.overdueActivities) {
setOverdueActivities(result.data.data.overdueActivities)
}
@@ -188,6 +216,66 @@ const DashboardProject = () => {
}
}
+ const getIntegrationInvoice = async (kode_sortname) => {
+ setIsReadyIntegrationInvoice(false);
+ const URL = `${BASE_OSPRO}/api/project/get-integration-invoice`;
+ const payload = {
+ "search": kode_sortname
+ }
+ const result = await axios.post(URL, payload, HEADER).then(res => res).catch(err => err.response)
+ console.log('getIntegrationInvoice', result);
+ if (!result) {
+ NotificationManager.error(`Could not connect to internet.`, "Failed");
+ setIsReadyIntegrationInvoice(true);
+ return;
+ }
+
+ if (result.status !== 200) {
+ NotificationManager.error(`Get integration invoice failed, ${result.data.message}`, "Failed");
+ setIsReadyIntegrationInvoice(true);
+ return;
+ }
+ else if (result.status == 200 && result.data.data) {
+ // console.log()
+ if (result.data.data.data) {
+ let total_invoice = result.data.data.data.total_invoice_amount;
+ let cash_in = result.data.data.data.total_invoice_paid_amount;
+ let outstanding_balance = total_invoice - cash_in;
+ setTotalInvoice(total_invoice ? total_invoice.toString() : null);
+ setCashIn(cash_in ? total_invoice.toString() : null)
+ setOutstandingBalance(outstanding_balance ? outstanding_balance.toString() : null);
+ }
+ setIsReadyIntegrationInvoice(true);
+ }
+ }
+
+ const getReportDistribution = async () => {
+ setIsReadyReportDistribution(false);
+ const URL = `${BASE_OSPRO}/api/project/get-report-distribution`;
+ const payload = {
+ "project_id": PROJECT_ID,
+ "start_date": moment().startOf('month').subtract(1, 'years').format('YYYY-MM-DD'),
+ "end_date": moment(new Date()).subtract(1, 'years').format('YYYY-MM-DD')
+ }
+ const result = await axios.post(URL, payload, HEADER).then(res => res).catch(err => err.response)
+ console.log('getReportDistribution', result);
+ if (!result) {
+ NotificationManager.error(`Could not connect to internet.`, "Failed");
+ setIsReadyReportDistribution(true);
+ return;
+ }
+
+ if (result.status !== 200) {
+ NotificationManager.error(`Get report distribution failed, ${result.data.message}`, "Failed");
+ setIsReadyReportDistribution(true);
+ return;
+ }
+ else if (result.status == 200 && result.data.data) {
+ setReportDistribution(result.data.data);
+ setIsReadyReportDistribution(true);
+ }
+ }
+
const getComments = async () => {
setIsReadyComments(false);
const URL = `${BASE_OSPRO}/api/project-comment/search`;
@@ -231,7 +319,6 @@ const DashboardProject = () => {
return;
}
else if (result.status == 200 && result.data.data) {
- console.log(result.data.data);
setComments(result.data.data);
setIsReadyComments(true);
}
@@ -284,10 +371,19 @@ const DashboardProject = () => {
});
setMymap(mymap);
-
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {attribution: '©
OpenStreetMap contributors'}).addTo(mymap);
}
+ useEffect(() => {
+ if (mymap) {
+ if (reportDistribution.length > 0) {
+ reportDistribution.map((item, idx) => {
+ L.marker([item.lat, item.lon]).addTo(mymap).bindPopup(PopupContent(item));
+ });
+ }
+ }
+ }, [mymap, reportDistribution])
+
const RenderGantt = useMemo(() => (
), [activeTabIdx])
- const SingleTextLoader = ({width, height}) => (
-
-
-
- )
-
- const ListLoader = () => (
- //
Loading overdue activities...
-
- )
-
- const Comment = ({name, comment, created_at}) => (
-
-
{name}
-
{created_at ? moment(created_at).format('D MMMM YYYY HH:mm:ss') : '-'}
-
{comment}
-
- )
-
- const BehindTaskItem = ({name, message}) => (
-
-
{name}
-
{message}
- {/*
{division}
*/}
-
- )
const RenderComments = useMemo(() => {
return (
@@ -578,12 +631,17 @@ const DashboardProject = () => {
Progress
-
-
Planning : {planningProgress}%
-
-
-
Actual : {actualProgress}%
-
+ {isReadySCurve ?
+
+ :
+
+ }
+
+ {isReadySCurve ?
+
+ :
+
+ }
@@ -591,17 +649,13 @@ const DashboardProject = () => {
Health By Budget
-
+ {isReadyOverdueActivities ?
:
}
Health By Schedule
-
+ {isReadySCurve ?
:
}
@@ -614,18 +668,33 @@ const DashboardProject = () => {