diff --git a/src/Service/JobOrderHandler/CMBJobOrderHandler.php b/src/Service/JobOrderHandler/CMBJobOrderHandler.php index 43a7becb..acd84d62 100644 --- a/src/Service/JobOrderHandler/CMBJobOrderHandler.php +++ b/src/Service/JobOrderHandler/CMBJobOrderHandler.php @@ -200,6 +200,8 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface $row['car_model'] = $car_model; $row['rider_name'] = $rider_name; $row['rider_plate_number'] = $rider_plate_number; + $row['date_assign'] = !empty($orow->getDateAssign()) ? $orow->getDateAssign()->format("c") : null; + $row['date_fulfill'] = !empty($orow->getDateFulfill()) ? $orow->getDateFulfill()->format("c") : null; $processor = $orow->getProcessedBy(); if ($processor == null) diff --git a/src/Service/JobOrderHandler/ResqJobOrderHandler.php b/src/Service/JobOrderHandler/ResqJobOrderHandler.php index f03d8b0f..234619a7 100644 --- a/src/Service/JobOrderHandler/ResqJobOrderHandler.php +++ b/src/Service/JobOrderHandler/ResqJobOrderHandler.php @@ -228,6 +228,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface $row['is_mobile'] = $orow->getSource() == TransactionOrigin::MOBILE_APP; $row['is_vip'] = $is_vip; $row['is_emergency'] = $is_emergency; + $row['date_assign'] = !empty($orow->getDateAssign()) ? $orow->getDateAssign()->format("c") : null; + $row['date_fulfill'] = !empty($orow->getDateFulfill()) ? $orow->getDateFulfill()->format("c") : null; $processor = $orow->getProcessedBy(); if ($processor == null) diff --git a/templates/job-order/list.all.html.twig b/templates/job-order/list.all.html.twig index 19332331..4e6089f3 100644 --- a/templates/job-order/list.all.html.twig +++ b/templates/job-order/list.all.html.twig @@ -97,7 +97,20 @@ if (data.flag_advance) { $(row).addClass('m-table__row--danger'); } - } + }, + afterTemplate: function (row, data, index) { + // if this row has an incrementing timer, handle the behavior + const timer = row.find('[data-incrementing]')[0]; + + if (timer) { + setInterval(() => { + const dateStart = new moment(data.date_assign, moment.ISO_8601); + const dateEnd = moment(); + + timer.innerHTML = timeDiff(dateStart, dateEnd); + }, 1000) + } + }, }, columns: [ { @@ -136,6 +149,42 @@ field: 'processor', title: 'Dispatcher' }, + { + field: '', + title: 'Dispatch Time', + sortable: false, + searchable: false, + textAlign: 'right', + template: function (row, index, datatable) { + let dateAssign; + let dateEnd; + let incrementing = false; + + // only display timer for these statuses + const statusesWithTimer = [ + 'Assigned', + 'In Transit', + 'In Progress', + 'Completed', // NOTE: completed would be based off the fulfillment time + ]; + + if (row.date_assign && statusesWithTimer.includes(row.status)) { + dateAssign = new moment(row.date_assign, moment.ISO_8601); + + // on completed jos, use date_fulfill as end date and do not increment + if (row.status == 'Completed') { + if (row.date_fulfill) { + dateEnd = new moment(row.date_fulfill, moment.ISO_8601); + } + } else { + dateEnd = moment(); + incrementing = true; + } + } + + return dateEnd ? '' + timeDiff(dateAssign, dateEnd) + '' : '-'; + }, + }, { field: 'Actions', width: 110, @@ -148,13 +197,13 @@ return actions; }, - } + }, ], search: { onEnter: false, input: $('#data-rows-search'), delay: 400 - } + }, }; var table = $("#data-rows").mDatatable(options); @@ -186,5 +235,16 @@ table.search(date_array, "schedule_date"); }); }); + + // get difference in hh:mm:ss format + const timeDiff = (startDate, endDate) => { + const seconds = Math.abs(startDate.diff(endDate, 'seconds')); + + const hh = Math.floor(seconds / 3600).toString().padStart(2, "0"); + const mm = Math.floor((seconds % 3600) / 60).toString().padStart(2, "0"); + const ss = (seconds % 60).toString().padStart(2, "0"); + + return [hh, mm, ss].join(':'); + } {% endblock %}