goiintra/public_html/doc/map.php

2601 lines
100 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
//require_once ("/assets/dbCon.php");
require_once getenv("DOCUMENT_ROOT")."/assets/dbCon.php";
//Initialize date
$dateArr = array();
for($i=0;$i < 7;$i++) {
$dateValue = strtotime(date("Ymd")."+".$i." day");
//$dateValue = strtotime(date("20240425")."+".$i." day");
$dateArr[] = array(
"val" => date("Ymd", $dateValue),
"text" => date("Y-m-d", $dateValue)
);
}
//Load driver list
if ($_SESSION['ss_LEVEL'] == 9) {
$qrySTR = " AND (m_uid = '".$_SESSION['ss_UID']."') ";
} else {
$qrySTR = "";
}
$drivers = array();
$sqDriver = qry("SELECT
*
FROM
tbl_member
WHERE
m_level = 9 AND m_status = 'A' ".$qrySTR."
ORDER BY
m_initial ASC ");
while($rstDriver = fetch_array($sqDriver)){
$drivers[] = array(
"id" => $rstDriver['m_uid'],
"name" => $rstDriver['m_initial']
);
}
//Load quantity setting from cookie
$cookieValueArr = explode("_",$_COOKIE['qtySetting']);
$searchQty = array();
if(count($cookieValueArr) > 2){
for($k=0;$k < count($cookieValueArr);$k++) {
$cookieValue = explode(":",$cookieValueArr[$k]);
$searchQty[] = array(
"min" => $cookieValue[0],
"max" => $cookieValue[1]
);
}
}else{
$min = 0;
$max = 100;
for($k=0;$k < 5;$k++) {
$searchQty[] = array(
"min" => $min,
"max" => $max
);
$min = $max + 1;
$max = $min + 49;
}
}
if (($_SESSION['ss_UID'] != "")) {
if ($_POST['orderdate'] != "") $orderdateSTR = $_POST['orderdate'];
else $orderdateSTR = date('Y-m-d');
$orderdateSTR = str_replace('-', "", $orderdateSTR);
$sqQuantity = qry("SELECT
SUM(d_quantity) as pickupquantity
FROM
tbl_daily
WHERE
d_status = 'F' AND d_orderdate = '".$orderdateSTR."'
AND d_driveruid = '".$_SESSION['ss_UID']."' ");
$rstQuantity = fetch_array($sqQuantity);
$curPickupQty = (int)$rstQuantity['pickupquantity'];
}
$strstr = "[".$_SESSION['ss_LEVEL']."][".$_SESSION['ss_UID']."][".$orderdateSTR."][".$rstQuantity['pickupquantity']."]";
?>
<link href="/assets/css/mapMAPCSS.css" rel="stylesheet" type="text/css" >
<!-- New2 -->
<link href="/assets/css/leftside-modal.css" rel="stylesheet">
<!-- New2 -->
<!--script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script-->
<script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=default"></script>
<script src="https://use.fontawesome.com/releases/v6.2.0/js/all.js"></script>
<script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
({key: "AIzaSyDg9u03mGrBhyOisp7VGc27CTPI9QXp8sY", v: "weekly"});</script>
<script src="https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"></script>
<!-- New -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.js"></script>
<div class="loading-overlay">Loading...</div>
<div id="popupMessage"></div>
<main class="pg-location">
<div class="width-20 floating-filter">
<form action="#" class="" >
<table id="sidebar-map" class="td-search">
<? //if (($_SESSION['ss_LEVEL'] == 9) && ($_SESSION['ss_UID'] != "")) { ?>
<? if (($_SESSION['ss_UID'] != "")) { ?>
<tr>
<td><button class="btn-blue-map" type="button">Pickup Qty: <span id="pickupquantity"><?=$curPickupQty?></span>L</button></td>
</tr>
<? } ?>
<!-- <tr>
<td> <label for="orderBy">Order Date</label></td>
</tr> -->
<tr>
<td>
<input type="date" name="orderdate" id="orderdate" value="<?php echo date('Y-m-d');?>">
<!--select name="orderdate" id="orderdate" class="custom-select-map-orderby">
<?php
//foreach($dateArr as $dateDetail) {
// echo '<option value="'.$dateDetail['val'].'">'.$dateDetail['text'].'</option>';
//}
?>
</select-->
</td>
</tr>
<!--tr>
<td><label for="Type">Option</label></td>
</tr-->
<tr>
<td>
<label class="container-chk" style="clear:both">Ordered
<input type="checkbox" checked="checked" class="chk-ordered" disabled>
<span class="checkmark"></span>
</label>
<table>
<tr>
<td style="margin-left:4px;"><span style="width:15px; height:15px;display: block;" class="bg-color-ordered-normal"></span></td><td align=left>Nor </td>
<td><span style="width:15px; height:15px;display: block;" class="bg-color-ordered-requested"></span></td><td>Req</td>
<td><span style="width:15px; height:15px;display: block;" class="bg-color-ordered-scheduled"></span></td><td>Sch</td>
<td><span style="width:15px; height:15px;display: block;" class="bg-color-ordered-finished"></span></td><td>Fin</td>
</tr>
</table>
</td>
</tr>
<!-- <tr>
<td ><label for="orderBy">Driver</label></td>
</tr> -->
<tr>
<td>
<select name="name" id="driver" class="custom-select-map-orderby">
<?php
foreach($drivers as $driver) {
echo '<option value="'.$driver['id'].'">'.$driver['name'].'</option>';
}
?>
</select>
</td>
</tr>
<!-- <tr>
<td><label for="Search">Search</label></td>
</tr> -->
<tr>
<td><input class="input-colour-bar" type="text" id="search-keyword" name="Search" placeholder="Search"></td>
</tr>
</table>
<table>
<!-- <tr>
<td colspan="4"><label for="Quantity">Quantity</label></td>
</tr> -->
<tr>
<td class="box-chk">
<label class="container-chk">
<input type="checkbox" class="qty">
<span class="checkmark"></span>
</label>
</td>
<td class="td-col-qty col-line">
<span class="level-line bg-color-yellow"></span>
</td>
<td class="td-col-qty col-left">
<input class="input-colour-bar qty-min" type="text" value="0" disabled>
</td>
<td class="td-col-qty col-second">~</td>
<td class="td-col-qty col-third">
<input class="input-colour-bar qty-max" type="text" value="<?php echo $searchQty[0]['max'];?>">
</td>
</tr>
<tr>
<td class="box-chk">
<label class="container-chk">
<input type="checkbox" class="qty">
<span class="checkmark"></span>
</label>
</td>
<td class="td-col-qty col-line">
<span class="level-line bg-color-orange"></span>
</td>
<td class="td-col-qty col-left">
<input class="input-colour-bar qty-min" type="text" value="<?php echo $searchQty[1]['min'];?>">
</td>
<td class="td-col-qty col-second">~</td>
<td class="td-col-qty col-third">
<input class="input-colour-bar qty-max" type="text" value="<?php echo $searchQty[1]['max'];?>">
</td>
</tr>
<tr>
<td class="box-chk">
<label class="container-chk">
<input type="checkbox" class="qty">
<span class="checkmark"></span>
</label>
</td>
<td class="td-col-qty col-line">
<span class="level-line bg-color-green"></span>
</td>
<td class="td-col-qty col-left">
<input class="input-colour-bar qty-min" type="text" value="<?php echo $searchQty[2]['min'];?>">
</td>
<td class="td-col-qty col-second">~</td>
<td class="td-col-qty col-third">
<input class="input-colour-bar qty-max" type="text" value="<?php echo $searchQty[2]['max'];?>">
</td>
</tr>
<tr>
<td class="box-chk">
<label class="container-chk">
<input type="checkbox" class="qty">
<span class="checkmark"></span>
</label>
</td>
<td class="td-col-qty col-line">
<span class="level-line bg-color-blue"></span>
</td>
<td class="td-col-qty col-left">
<input class="input-colour-bar qty-min" type="text" value="<?php echo $searchQty[3]['min'];?>">
</td>
<td class="td-col-qty col-second">~</td>
<td class="td-col-qty col-third">
<input class="input-colour-bar qty-max" type="text" value="<?php echo $searchQty[3]['max'];?>">
</td>
</tr>
<tr>
<td class="box-chk">
<label class="container-chk">
<input type="checkbox" class="qty">
<span class="checkmark"></span>
</label>
</td>
<td class="td-col-qty col-line" >
<span class="level-line bg-color-black"></span>
</td>
<td class="td-col-qty col-left">
<input class="input-colour-bar qty-min" type="text" value="<?php echo $searchQty[4]['min'];?>">
</td>
<td class="td-col-qty col-second">~</td>
<td class="td-col-qty col-third">
<input class="input-colour-bar qty-max" type="text" value="MAX" disabled>
</td>
</tr>
</table>
<div>
<button class="btn-blue-map btn-current" type="button">CURRENT</button>
<button class="btn-primary-map btn-routeplanner" type="button" data-toggle="modal" data-target="#routePlannerModal">ROUTE PLANNER</button>
<button class="btn-orange-map btn-route-print hidden" type="button">PRINT</button>
<button class="btn-red-map btn-init" type="button" onClick="forceRefresh()">INIT</button>
</div>
</form>
</div>
<div id="map"></div>
</main>
<!-- ROUTE PLANNER MODAL -->
<div class="modal fade" id="routePlannerModal" tabindex="-1" aria-labelledby="routePlannerModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="routePlannerModalLabel">Route Planner</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p>Make a list in the order you'd like to visit them. The place at the top will be counted as the Route you visit first.</p>
<div id="addressList" class="list-group">
</div>
<div id="addressInformationList" class="list-group">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary routePlannerApply" data-dismiss="modal">Apply</button>
</div>
</div>
</div>
</div>
<!-- ROUTE PLANNER MODAL END -->
<SCRIPT LANGUAGE='JAVASCRIPT'>
function popup(){
var orderdate = jQuery("#map-modal-input .d_orderdate").val();
var customeruid = jQuery("#map-modal-input .d_customeruid").val();
var customerno = jQuery("#map-modal-input .d_customerno").val();
var uid = jQuery("#map-modal-input .d_uid").val();
var str = '/lib/signature.php?'+'uid=' + uid + '&orderdate=' + orderdate + '&customeruid=' + customeruid + '&customerno=' + customerno;
window.open(str, '_blank', 'width=450,height=450,resizable=0,scrollbars=0');
}
</SCRIPT>
<!-- INPUT MODAL-->
<div class="modal fade top map" id="map-modal-input" tabindex="-1" role="dialog">
<div id="modal-input" class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">ORDER DETAIL</h4>
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<form name="pickupOrder" id="pickupOrder" method="POST" novalidate="novalidate">
<input type="hidden" class="d_uid">
<input type="hidden" class="d_customeruid">
<input type="hidden" class="d_customerno">
<input type="hidden" class="d_orderdate">
<input type="hidden" class="d_paymenttype">
<table class="tb-info-box">
<tbody>
<tr>
<td class="td-title-info">Restaurant Name</td>
<td class="td-text-info shortinput-store-name">Name</td>
</tr>
<tr>
<td class="td-title-info">Visited Date</td>
<td class="td-text-info">
<!--input type="datetime-local" class="d_visitdate"-->
<input type="date" class="d_visitdate">
</td>
</tr>
<tr>
<td class="td-title-info">Driver</td>
<td class="td-text-info">
<select class="custom-select d_driveruid">
<?php
foreach($drivers as $driver) {
echo '<option value="'.$driver['id'].'">'.$driver['name'].'</option>';
}
?>
</select>
</td>
</tr>
<tr>
<td class="td-title-info">Rate</td>
<td class="td-text-info shortinput-rate">Rate</td>
</tr>
<tr>
<td class="td-title-info">Oil Quantity</td>
<td class="td-text-info">
<input type="number" class="d_quantity" placeholder="500" minlength="1" maxlength="10">
</td>
</tr>
<tr>
<td class="td-title-info">Sludge (%)</td>
<td class="td-text-info">
<div class="number-input">
<button class="left" type="button">▼</button>
<input type="number" class="d_sludge" value="50" min="0" max="100" placeholder="50">
<button class="right" type="button">▲</button>
</div>
</td>
</tr>
<tr class="CA_option">
<td class="td-title-info">Cash</td>
<td class="td-text-info">
<input type="text" class="d_payamount" placeholder="100">
</td>
</tr>
<tr class="CA_option">
<td class="td-title-info">Pay Status</td>
<td class="td-text-info" style="display:flex;width:100%">
<input type="radio" class="d_paystatuspaid" name="radio-group" value="P" style="margin-right:5px;width:auto;">
<span>Paid</span>
<input type="radio" class="d_paystatusunpaid" name="radio-group" value="N" style="margin-right:5px;margin-left:5px;width:auto;" checked>
<span>UnPaid</span>
</td>
</tr>
<tr class="CA_option">
<td class="td-title-info">Customer Name</td>
<td class="td-text-info">
<input type="text" class="d_payeename" placeholder="100">
</td>
</tr>
<tr class="CA_option">
<td class="td-title-info">Signature</td>
<td class="td-text-info">
<a href="#" onClick="popup();">CLICK</a>
</td>
</tr>
<tr>
<td class="td-title-info">Note</td>
<td class="td-text-info">
<textarea class="textarea d_note" rows="3" cols="20"></textarea>
</td>
</tr>
</tbody>
</table>
<br>
<div class="text-center grid-layout-col-2">
<button type="button" class="btn-sub btn-input-save">SAVE</button>
<button type="button" class="btn-gray" data-dismiss="modal">CLOSE</button>
</div>
</form>
</div>
</div><!-- modal-content ends -->
</div>
</div>
<!-- INPUT DETAIL MODAL Ends -->
<!-- ORDER MODAL-->
<div class="modal fade top map" id="map-modal-order" tabindex="-1" role="dialog">
<div id="modal-input" class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">ADD ORDER</h4>
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<form name="order-form" method="POST">
<input type="hidden" class="d_customeruid">
<input type="hidden" class="d_customerno">
<input type="hidden" class="d_orderdate">
<input type="hidden" class="c_index">
<table class="tb-info-box">
<tbody>
<!-- Order Type -->
<tr>
<td class="td-title-info">Order Type</td>
<td class="td-text-info">
<select class="custom-select d_ordertype">
<option value="R">Request</option>
<option value="N">Normal</option>
<option value="S">Scheduled</option>
<option value="I">Installation</option>
<option value="O">Other</option>
</select>
</td>
</tr>
<!-- RUID -->
<tr>
<td class="td-title-info">RUID</td>
<td class="td-text-info">
<input type="text" class="d_ruid">
</td>
</tr>
<!-- Driver UID -->
<tr>
<td class="td-title-info">Driver UID</td>
<td class="td-text-info">
<select class="custom-select d_driveruid">
<?php
foreach($drivers as $driver) {
echo '<option value="'.$driver['id'].'">'.$driver['name'].'</option>';
}
?>
</select>
</td>
</tr>
</tbody>
</table>
<br>
<div class="text-center grid-layout-col-2">
<button type="button" class="btn-sub btn-order-save">SAVE</button>
<button type="button" class="btn-gray" data-dismiss="modal">CLOSE</button>
</div>
</form>
</div>
</div><!-- modal-content ends -->
</div>
</div>
<!-- ORDER DETAIL MODAL Ends -->
<!-- HISTORY MODAL-->
<div class="modal fade top map" id="map-modal-history" tabindex="-1" role="dialog">
<div id="modal-history" class="modal-dialog" role="document">
<div class="modal-content modal-content-historyOrder">
<div class="modal-header">
<h4 class="modal-title">HISTORY</h4>
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div class="history-warp-scroll">
<form method="POST" action="#">
<table class="tb-info-box1">
<thead>
<tr>
<td class="td-title-info td-no">No</td>
<td class="td-title-info td-date-history">Date</td>
<td class="td-title-info td-oil-quantity-history">Oil Quantity</td>
<td class="td-title-info td-date-history">Driver</td>
<td class="td-title-info td-paid">Paid (Cash)</td>
</tr>
</thead>
<tbody>
<tr>
<td class="td-text-info">85</td>
<td class="td-text-info" style="text-align: center;">2024-03-06</td>
<td class="td-text-info" style="text-align: right;margin-right: 20px;">170</td>
<td class="td-text-info" style="text-align: center;">J.L</td>
<td class="td-text-info"></td>
</tr>
<tr>
<td class="td-text-info">84</td>
<td class="td-text-info" style="text-align: center;">2024-02-21</td>
<td class="td-text-info" style="text-align: right;margin-right: 20px;">100</td>
<td class="td-text-info" style="text-align: center;">J.L</td>
<td class="td-text-info"></td>
</tr>
</tbody>
</table>
</form>
</div>
<br>
<div class="text-center">
<button type="button" class="btn-gray width-200" data-dismiss="modal">CLOSE</button>
</div>
</div>
</div>
</div>
</div>
<!-- HISTORY DETAIL MODAL Ends -->
<!-- INFO MODAL-->
<div class="modal fade top map in" id="map-modal-info" tabindex="-1" role="dialog">
<div id="modal-info" class="modal-dialog" role="document">
<div class="modal-content modal-content-modifycustomerShortInfo">
<div class="modal-header">
<h4 class="modal-title">CUSTOMER INFORMATION</h4>
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<form name="customerShortInfo" id="customerShortInfo" method="POST" novalidate="novalidate">
<input type="hidden" name="actionStr" value="SHORTINFO">
<input type="hidden" name="actionPage" value="">
<input type="hidden" name="c_uid" class="c_uid" value="3888">
<input type="hidden" name="c_accountno" class="c_accountno" value="">
<input type="hidden" name="mode" class="mode" value="update">
<table class="tb-info-box">
<tbody>
<tr>
<td class="td-title-info">Restaurant Name</td>
<td colspan="2" class="td-text-info shortinfo-store-name">Name</td>
</tr>
<tr>
<td class="td-title-info">Payment Type</td>
<td colspan="2" class="td-text-info shortinfo-payment-type">Cheque</td>
</tr>
<tr>
<td class="td-title-info">Pay Status</td>
<td colspan="2" class="td-text-info shortinfo-payment-string">Paid</td>
</tr>
<tr>
<td class="td-title-info">Comment</td>
<td colspan="2" class="td-text-info">
<textarea id="c_comment_ri" class="textarea shortinfo-comment" name="c_comment_ri" rows="4" cols="20">매주 수요일 정기 픽업, 11시 이후 방문</textarea>
</td>
</tr>
<tr>
<td class="td-title-info">Container Location</td>
<td colspan="2" class="td-text-info">
<textarea id="c_location" class="textarea shortinfo-container-location" name="c_location" rows="2" cols="20">Inside Rest</textarea>
</td>
</tr>
<tr>
<td class="td-title-info">Installation Image</td>
<td class="td-text-info" id="installImgArea" style="border-right:none;">
<span>Loading...</span>
</td>
<td style="text-align: right; border-right: 1px solid #e2e2e2; border-bottom:1px solid #e2e2e2;">
<span style="border:1px solid #72A864; border-radius:5px; padding:3px;">
<a href="#" onclick="imagepopup(jQuery('#customerShortInfo .c_uid').val());">ADD</a>
</span>
</td>
</tr>
</tbody>
</table>
<br>
<div class="text-center grid-layout-col-2">
<button type="button" data-dismiss="modal" class="btn-sub" onClick="javscript:updtShortInfo();">SAVE</button>
<button type="button" class="btn-gray" data-dismiss="modal">CLOSE</button>
</div>
</form>
</div>
<div class="modal fade" id="myModalPopup" tabindex="-1" role="dialog" aria-labelledby="myModalPopup" style="opacity: 0.5; padding-right: 0px !important;">
<div class="modal-dialog modal-dialog-centered modal-xl" role="document">
<div class="modal-content" style="background-color:#2A9B56 !important; max-width:260px; margin: 0 auto;">
<div class="myModalPopup-body" style="text-align: center; border-radius: 5px; max-height:60px; font-size:18px; background-color:#2A9B56; color: #FFFFFF; font-weight: bold;padding:0.5em 1em; ">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- INFO DETAIL MODAL Ends -->
<!-- NOTE MODAL-->
<div class="modal fade top map" id="map-modal-note" tabindex="-1" role="dialog">
<div id="modal-note" class="modal-dialog" role="document">
<div class="modal-content modal-content-modifycustomerShortNote">
<div class="modal-header">
<h4 class="modal-title">REQUEST NOTE</h4>
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<table class="tb-info-box">
<tbody>
<tr>
<td class="td-title-info">Note</td>
<td class="td-text-info">
<textarea id="r_note" class="textarea notice-info" name="r_note" rows="4" cols="20">굳지 않았을 것 같아서 요청드리니 교체가 필요한지 확인 부탁드리겠습니다.</textarea>
</td>
</tr>
</tbody>
</table>
<br>
<div class="text-center">
<button type="button" class="btn-gray" data-dismiss="modal">CLOSE</button>
</div>
</div>
<div class="modal fade" id="myModalPopup" tabindex="-1" role="dialog" aria-labelledby="myModalPopup" style="opacity: 0.5; padding-right: 0px !important;">
<div class="modal-dialog modal-dialog-centered modal-xl" role="document">
<div class="modal-content" style="background-color:#2A9B56 !important; max-width:260px; margin: 0 auto;">
<div class="myModalPopup-body" style="text-align: center; border-radius: 5px; max-height:60px; font-size:18px; background-color:#2A9B56; color: #FFFFFF; font-weight: bold;padding:0.5em 1em; ">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- NOTE DETAIL MODAL Ends -->
<div class="container">
<!-- Modal -->
<div class="modal fade" id="myModal" data-backdrop="static" data-keyboard="false" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<!--button type="button" class="close" data-dismiss="modal">&times;</button-->
<h4>MESSAGE</h4>
</div>
<div class="modal-body">
<p> </p>
</div>
<div class="modal-footer">
<button type="button" class="modal-close" data-dismiss="modal" >OK</button>
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade top map" id="modal-confirm" tabindex="-1" role="dialog">
<div id="modal-input" class="modal-dialog" role="document">
<!--
<div class="modal-content">
<div class="modal-body">
<p>Are you sure to remove order?</p>
</div>
<div class="modal-footer">
<input type="hidden" class="order-date" value="">
<input type="hidden" class="id" value="">
<input type="hidden" class="c_index" value="">
<button type="button" class="btnRemoveConfirm" onClick="javascript:confirmRemoveOrder();">Confirm</button>
<button type="button" class="btn-gray" data-dismiss="modal" >Cancel</button>
</div>
</div>--><!-- modal-content ends -->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Confirm</h4>
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<input type="hidden" class="order-date" value="">
<input type="hidden" class="id" value="">
<input type="hidden" class="duid" value="">
<input type="hidden" class="c_index" value="">
<input type="hidden" class="accountno" value="">
<p>Are you sure to remove order?</p>
<br>
<div class="text-center grid-layout-col-2">
<button type="button" class="btn-sub" onClick="javascript:confirmRemoveOrder();" data-dismiss="modal">Confirm</button>
<button type="button" class="btn-gray" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
</div>
<!-- ORDER DETAIL MODAL Ends -->
<!-- Modal -->
<input type="hidden" id="routeplanner_total_duration">
<input type="hidden" id="routeplanner_total_distance">
<input type="hidden" id="routeplanner_encoded_path">
<a href="#" class="scroll-top d-flex align-items-center justify-content-center"><i class="bi bi-arrow-up-short"></i></a>
<div id="preloader"></div>
<p></p><p></p><p></p>
<div class="route-planner-waypoints">
<table>
<thead>
<tr>
<th>No</th>
<th>Name</th>
<th>Account</th>
<th>Container</th>
<th>Payment</th>
<th>Rate</th>
<th>Address</th>
<th>City</th>
<th>Last</th>
<th>Forecast</th>
<th>Actual(L)</th>
<th>Last Paid</th>
<th>2023</th>
<th>2024</th>
<th>Cycle</th>
<th>Last PU</th>
<th>Km</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</body>
</html>
<script>
var center = { lat: 43.732188, lng: -79.571618 };
var currentLocation = { lat: 43.764693323038315, lon: -79.47762958134186 };
/* $(window).ready(function(){
jQuery("#driver").change(function(e){
let data = {
"driver" : jQuery("#driver").val()
}
api('inqDriverGeo', data, rstDriverGeo);
});
var rstDriverGeo = function(json) {
if (json.result['geolat']) {
var driverlat = json.result['geolat'];
var driverlon = json.result['geolon'];
}
else {
var driverlat = 43.732188;
var driverlon = -79.571618;
}
alert (driverlat);
center = { lat: driverlat, lng: driverlon };
}
});
*/
var map;
var directionsRenderer;
var currentMarker;
const {AdvancedMarkerElement} = google.maps.importLibrary("marker");
$(window).ready(function(){
<? if ($_SESSION['ss_LEVEL'] == 9) { ?>
$("#driver").val("<?=$_SESSION['ss_UID']?>").change();
<? } ?>
initMap();
/*Redraw marker when search option changed*/
jQuery("#orderdate").change(function(e){
jQuery('.qty').prop('checked', false);
jQuery("#search-keyword").val("");
drawPoint();
let pickupdata = {
"route_date" : jQuery("#orderdate").val(),
"driver" : jQuery("#driver").val()
}
api('inqPickupQty', pickupdata, rstInqPickupQty);
});
jQuery(".chk-ordered").click(function(e){
drawPoint();
});
jQuery("#driver").change(function(e){
jQuery('.qty').prop('checked', false);
jQuery("#search-keyword").val("");
drawPoint();
//map ceneter change
let data = {
"route_date" : jQuery("#orderdate").val(),
"driver" : jQuery("#driver").val()
}
api('inqMapCenter', data, rstInqMapCenter);
api('inqPickupQty', data, rstInqPickupQty);
});
jQuery("#search-keyword").keyup(function(e){
//if(jQuery(e.target).val().length > 0) {
drawPoint();
//}
});
jQuery(".qty").click(function(e){
drawPoint();
});
jQuery(".qty-min").change(function(e){
let index = jQuery(".qty-min").index(e.target);
if(parseInt(jQuery(e.target).val()) > jQuery(".qty-max:eq("+(index-1)+")").val()) {
for(let i=index;i < jQuery(".qty-min").length;i++) {
let unit = 49;
if(jQuery(".qty-min:eq("+i+")").val() > 200){
unit = 99;
}
if((i+1) < jQuery(".qty-min").length){
jQuery(".qty-max:eq("+i+")").val(parseInt(jQuery(".qty-min:eq("+i+")").val()) + unit);
}
jQuery(".qty-min:eq("+(i+1)+")").val(parseInt(jQuery(".qty-max:eq("+i+")").val()) + 1);
}
drawPoint();
}else{
jQuery(e.target).val(parseInt(jQuery(".qty-max:eq("+(index-1)+")").val())+1);
}
});
jQuery(".qty-max").change(function(e){
let index = jQuery(".qty-max").index(e.target);
if(parseInt(jQuery(e.target).val()) > jQuery(".qty-min:eq("+index+")").val()) {
jQuery(".qty-min:eq("+(index+1)+")").val(parseInt(jQuery(e.target).val())+1).trigger('change');
drawPoint();
}else{
jQuery(e.target).val(parseInt(jQuery(".qty-min:eq("+(index+1)+")").val()) - 1);
}
});
jQuery(".btn-current").click(function(e){
inqCurrent();
});
jQuery(".btn-routeplanner").click(function(e){
jQuery("#routePlannerModal #addressList").html('<p class="text-center">Loading...</p>');
// 각 드라이버의 data 를 가져오는 문제가 있어서 강제로 회사 주소로 셋팅 (2025.06.16)
currentLocation = { lat: 43.764693323038315, lon: -79.47762958134186 };
//alert(currentLocation['lat']);
let data = {
"route_date" : jQuery("#orderdate").val(),
"m_lat" : currentLocation['lat'],
"m_lon" : currentLocation['lon'],
"driver" : jQuery("#driver").val()
}
api('inqRouteAddress', data, rstInqRouteAddress);
});
jQuery(".routePlannerApply").click(function(e){
removeCircle();
for(let j=0; j < marker.length; j++) {
marker[j].setMap(null);
marker[j] = null;
}
marker = [];
overlay = [];
let waypoints = [];
let dispWaypoints = [];
for(let i=0; i < jQuery("#routePlannerModal #addressList .draggable-item").length; i++) {
let dataArr = jQuery("#routePlannerModal #addressList .draggable-item:eq("+i+")").attr("data").split("*&^&*");
if(waypoints.length < 24) {
if(i < (jQuery("#routePlannerModal #addressList .draggable-item").length - 1)){
let point = {
'location' : {
'lat' : parseFloat(dataArr[0]),
'lng' : parseFloat(dataArr[1])
},
stopover : true
}
waypoints.push(point);
}
}
// Print
let dispWaypoint = {
'point' : (i < 25)?String.fromCharCode(65+(i+1)):'',
'name' : dataArr[2],
'address' : dataArr[3],
'accountno' : jQuery("#routePlannerModal #addressInformationList .item-information-"+dataArr[4]+" .account").val(),
'maincontainer' : jQuery("#routePlannerModal #addressInformationList .item-information-"+dataArr[4]+" .maincontainer").val(),
'paymenttype' : jQuery("#routePlannerModal #addressInformationList .item-information-"+dataArr[4]+" .paymenttype").val(),
'rate' : jQuery("#routePlannerModal #addressInformationList .item-information-"+dataArr[4]+" .rate").val(),
'city' : jQuery("#routePlannerModal #addressInformationList .item-information-"+dataArr[4]+" .city").val(),
'lastpickupquantity' : jQuery("#routePlannerModal #addressInformationList .item-information-"+dataArr[4]+" .lastpickupquantity").val(),
'estquantity' : jQuery("#routePlannerModal #addressInformationList .item-information-"+dataArr[4]+" .estquantity").val(),
'quantity' : jQuery("#routePlannerModal #addressInformationList .item-information-"+dataArr[4]+" .quantity").val(),
'lastpaiddate' : jQuery("#routePlannerModal #addressInformationList .item-information-"+dataArr[4]+" .lastpaiddate").val(),
'this_year' : jQuery("#routePlannerModal #addressInformationList .item-information-"+dataArr[4]+" .this_year").val(),
'last_year' : jQuery("#routePlannerModal #addressInformationList .item-information-"+dataArr[4]+" .last_year").val(),
'fullcycle' : jQuery("#routePlannerModal #addressInformationList .item-information-"+dataArr[4]+" .fullcycle").val(),
'lastpickupdate' : jQuery("#routePlannerModal #addressInformationList .item-information-"+dataArr[4]+" .lastpickupdate").val()
}
dispWaypoints.push(dispWaypoint);
}
let destinationDataArr = jQuery("#routePlannerModal #addressList .draggable-item:eq("+(jQuery("#routePlannerModal #addressList .draggable-item").length - 1)+")").attr("data").split("*&^&*");
if(jQuery("#routePlannerModal #addressList .draggable-item").length > 23) {
destinationDataArr = jQuery("#routePlannerModal #addressList .draggable-item:eq(23)").attr("data").split("*&^&*");
}
let directionsService = new google.maps.DirectionsService();
directionsRenderer = new google.maps.DirectionsRenderer({
map: map,
suppressMarkers: false
});
directionsService.route({
origin: {lat: parseFloat(currentLocation['lat']), lng: parseFloat(currentLocation['lon'])}, // 시작 위치
destination: {lat: parseFloat(destinationDataArr[0]), lng: parseFloat(destinationDataArr[1])}, // 종료 위치 (시작 위치와 같을 수 있음)
waypoints: waypoints,
optimizeWaypoints: true, // Google에게 경유지 최적화를 요청
travelMode: google.maps.TravelMode.DRIVING,
}, (response, status) => {
if (status === 'OK') {
directionsRenderer.setDirections(response);
var route = response.routes[0];
var totalDuration = 0;
var totalDistance = 0;
let waypointsTable = '<tr><td>A</td><td>Current Location</td><td colspan="13">&nbsp;</td></tr>';
for (var i = 0; i < route.legs.length; i++) {
totalDuration += route.legs[i].duration.value;
totalDistance += route.legs[i].distance.value;
/* suppressMarkers: true
var marker = new google.maps.Marker({
position: route.legs[i].start_location,
label: ""+(i+1),
map: map
});
*/
if(i != 0) {
waypointsTable += '<tr>';
waypointsTable += '<td>'+dispWaypoints[i-1]['point']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['name']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['accountno']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['maincontainer']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['paymenttype']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['rate']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['address']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['city']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['lastpickupquantity']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['estquantity']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['quantity']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['lastpaiddate']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['this_year']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['last_year']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['fullcycle']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i-1]['lastpickupdate']+'</td>';
waypointsTable += '<td>'+(route.legs[i-1].distance.value/1000)+'</td>';
waypointsTable += '</tr>';
}
}
// Convert the duration to minutes
totalDuration = totalDuration / 60;
// 총 이동 거리를 킬로미터 단위로 변환 (미터 단위에서 킬로미터 단위로 변환하기 위해 1000으로 나눔)
totalDistance = totalDistance / 1000;
jQuery("#routeplanner_total_duration").val(totalDuration);
jQuery("#routeplanner_total_distance").val(totalDistance);
waypointsTable += '<tr>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['point']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['name']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['accountno']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['maincontainer']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['paymenttype']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['rate']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['address']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['city']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['lastpickupquantity']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['estquantity']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['quantity']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['lastpaiddate']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['this_year']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['last_year']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['fullcycle']+'</td>';
waypointsTable += '<td>'+dispWaypoints[route.legs.length-1]['lastpickupdate']+'</td>';
waypointsTable += '<td>'+(route.legs[route.legs.length-1].distance.value/1000)+'</td>';
waypointsTable += '</tr>';
if(dispWaypoints.length > route.legs.length) {
for (let i=route.legs.length;i < dispWaypoints.length;i++) {
waypointsTable += '<tr>';
waypointsTable += '<td>'+dispWaypoints[i]['point']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['name']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['accountno']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['maincontainer']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['paymenttype']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['rate']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['address']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['city']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['lastpickupquantity']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['estquantity']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['quantity']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['lastpaiddate']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['this_year']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['last_year']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['fullcycle']+'</td>';
waypointsTable += '<td>'+dispWaypoints[i]['lastpickupdate']+'</td>';
waypointsTable += '<td></td>';
waypointsTable += '</tr>';
}
}
jQuery(".route-planner-waypoints table tbody").html(waypointsTable);
/*
//overlay 텍스트 마커 생성
let waypointCnt = 0;
waypoints.forEach(waypoint => {
let labelArr = jQuery("#routePlannerModal #addressList .draggable-item:eq("+waypointCnt+")").attr("data").split("/");
let canvas = document.createElement('canvas');
canvas.width = 100;
canvas.height = 50;
let context = canvas.getContext('2d');
// 배경 그리기
context.fillStyle = '#FF6347'; // 배경색
context.fillRect(0, 0, canvas.width, canvas.height);
// 텍스트 그리기
context.fillStyle = '#FFFFFF'; // 텍스트 색상
context.font = '12px Arial';
context.fillText(labelArr[2], 10, 25); // 텍스트와 위치
let markerIcon = canvas.toDataURL(); // 캔버스를 데이터 URL로 변환
new google.maps.Marker({
position: waypoint.location,
icon: markerIcon,
map: map,
});
waypointCnt += 1;
});*/
jQuery(".btn-route-print").removeClass("hidden");
} else {
window.alert('Directions request failed due to ' + status);
}
});
jQuery("#routePlannerModal .close").trigger("click");
});
jQuery(".btn-route-print").click(function(e){
window.print();
});
jQuery(".btn-order-save").click(function(e){
// 폼 데이터 유효성 검사
if (addOrderValidation()) {
let data = {
"orderdate" : jQuery("#map-modal-order .d_orderdate").val(),
"ordertype" : jQuery("#map-modal-order .d_ordertype").val(),
"ruid" : jQuery("#map-modal-order .d_ruid").val(),
"driveruid" : jQuery("#map-modal-order .d_driveruid").val(),
"customer_uid" : jQuery("#map-modal-order .d_customeruid").val(),
"customer_no" : jQuery("#map-modal-order .d_customerno").val(),
"c_index" : jQuery("#map-modal-order .c_index").val()
}
api('addOrder', data, rstAddOrder);
}
});
jQuery(".btn-input-save").click(function(e){
// 폼 데이터 유효성 검사
if (saveInputValidation()) {
let data = {
"uid" : jQuery("#map-modal-input .d_uid").val(),
"customeruid" : jQuery("#map-modal-input .d_customeruid").val(),
"customerno" : jQuery("#map-modal-input .d_customerno").val(),
"orderdate" : jQuery("#map-modal-input .d_orderdate").val(),
//"ordertype" : jQuery("#map-modal-input .d_ordertype").val(),
//"ruid" : jQuery("#map-modal-input .d_ruid").val(),
"visitdate" : replaceAll(jQuery("#map-modal-input .d_visitdate").val(), '-' ,''),
"driveruid" : jQuery("#map-modal-input .d_driveruid").val(),
"quantity" : jQuery("#map-modal-input .d_quantity").val(),
"sludge" : jQuery("#map-modal-input .d_sludge").val(),
"note" : jQuery("#map-modal-input .d_note").val(),
"createruid" : <?=$_SESSION['ss_UID']?>,
"paymenttype" : jQuery("#map-modal-input .d_paymenttype").val(),
"payamount" : jQuery("#map-modal-input .d_payamount").val(),
"payeename" : jQuery("#map-modal-input .d_payeename").val(),
"paystatus" : jQuery("#map-modal-input input[name='radio-group']:checked").val()
}
// api('saveInput', data, rstSaveInput);
api('saveInput', data, function(rst){
rstSaveInput(rst);
drawPoint(); // 저장시 깃발 색깔 변경
});
//let pickupdata = {
// "route_date" : jQuery("#orderdate").val(),
// "driver" : jQuery("#driver").val()
//}
//api('inqPickupQty', pickupdata, rstInqPickupQty);
}
});
});
function updatePickupQty(){
let pickupdata = {
"route_date" : jQuery("#orderdate").val(),
"driver" : jQuery("#driver").val()
}
api('inqPickupQty', pickupdata, rstInqPickupQty);
}
function smoothZoom(map, maxZoom, currentZoom) {
if (currentZoom >= maxZoom) {
return;
} else {
google.maps.event.addListenerOnce(map, 'zoom_changed', function(event) {
smoothZoom(map, maxZoom, currentZoom + 1);
});
setTimeout(function() {
map.setZoom(currentZoom);
}, 80); // Adjust the speed of zooming
}
}
var rstInqPickupQty = function(json) {
jQuery("#pickupquantity").text(json.curPickupQty);
}
var rstSaveInput = function(json) {
$('#map-modal-input').modal('hide'); // Bootstrap 정상 닫기 시도
$('#map-modal-input').removeClass('show in').css('display', 'none').attr('aria-hidden', 'true'); // 남아 있을 수 있는 클래스 제거
$('.modal-backdrop').remove(); // backdrop 제거
showPopupMessage(json.msg);
//drawPoint();
updatePickupQty();
}
function replaceAll(str, searchStr, replaceStr) {
return str.split(searchStr).join(replaceStr);
}
function initAddOrder(customer_id, index){
//jQuery("#map-modal-order .d_customeruid").val(customer_id);
//jQuery("#map-modal-order .c_index").val(index);
//jQuery("#map-modal-order .d_orderdate").val(jQuery("#orderdate").val());
let data = {
"orderdate" : jQuery("#orderdate").val(),
"driveruid" : jQuery("#driver").val(),
"customer_uid" : customer_id,
"d_createruid" : <?=$_SESSION['ss_UID']?>,
"c_index" : index
}
api('addOrderDirect', data, rstAddOrder);
}
var rstAddOrder = function(json) {
//$('#map-modal-order .close').trigger('click');
//jQuery(".modal").removeClass("show");
//jQuery(".modal-backdrop").remove();
if (json.c_return == 0) {
jQuery(".addOrderBtn_"+json.c_index).addClass('hidden');
jQuery(".removeOrderBtn_"+json.c_index).removeClass('hidden');
showPopupMessage(json.msg);
} else {
jQuery(".addOrderBtn_"+json.c_index).addClass('hidden');
jQuery(".removeOrderBtn_"+json.c_index).removeClass('hidden');
showPopupMessage(json.msg);
drawPoint(); // Add order시 flag 가 변경되지 않으므로 필요함
}
}
function showPopupMessage(msg) {
jQuery("#popupMessage").text(msg);
$('#popupMessage').fadeIn().delay(2000).fadeOut();
}
function removeOrder(id, duid, index, accountno) {
jQuery("#modal-confirm .order-date").val(jQuery("#orderdate").val());
jQuery("#modal-confirm .id").val(id);
jQuery("#modal-confirm .duid").val(duid);
jQuery("#modal-confirm .c_index").val(index);
jQuery("#modal-confirm .accountno").val(accountno);
/*
if(confirm('Are you sure you want to remove the order?')) {
let data = {
"orderdate" : jQuery("#orderdate").val(),
"id" : id,
"c_index" : index
}
api('removeOrder', data, rstRemoveOrder);
}*/
}
function confirmRemoveOrder(){
let data = {
"orderdate" : jQuery("#modal-confirm .order-date").val(),
"id" : jQuery("#modal-confirm .id").val(),
"duid" : jQuery("#modal-confirm .duid").val(),
"c_index" : jQuery("#modal-confirm .c_index").val(),
"accountno" : jQuery("#modal-confirm .accountno").val(),
"createruid" : <?=$_SESSION['ss_UID']?>
}
api('removeOrder', data, rstRemoveOrder);
//let pickupdata = {
// "route_date" : jQuery("#orderdate").val(),
// "driver" : jQuery("#driver").val()
//}
//api('inqPickupQty', pickupdata, rstInqPickupQty);
}
var rstRemoveOrder = function(json) {
showPopupMessage(json.msg);
jQuery(".addOrderBtn_"+json.c_index).removeClass('hidden');
jQuery(".removeOrderBtn_"+json.c_index).addClass('hidden');
drawPoint(); // remove order시 flag 가 변경되지 않으므로 필요함
updatePickupQty();
}
function addOrderValidation(){
jQuery("#map-modal-order .d_ruid").css("border","1px solid black");
if(jQuery("#map-modal-order .d_ruid").val().trim() === '') {
jQuery("#map-modal-order .d_ruid").css("border","1px solid red");
return false;
}
return true;
}
function initInput(customer_id, customer_no){
// input modal 에서 저장버튼 클릭 후 다시 오픈할 때, modal 내부에 포커스가 남아있어서 modal 이 오픈되지 않는 이슈 (modal-backdrop 만 열려서 전체 클릭이 막힘)
// 1. 현재 포커스를 가진 요소에서 포커스를 제거하고 body에 포커스
jQuery(':focus').blur();
jQuery('body').focus();
// 2. 모달 자체의 속성 초기화 (Bootstrap의 동작을 돕기 위해 유지)
jQuery('#map-modal-input').attr('aria-hidden', 'false').removeAttr('tabindex');
// end input modal
let loadingTxt = 'Loading...';
jQuery("#map-modal-input .shortinput-store-name").text(loadingTxt);
jQuery("#map-modal-input .d_uid, #map-modal-input .d_customeruid, #map-modal-input .d_customerno, #map-modal-input .orderdate, #map-modal-input .d-ruid, #map-modal-input .d_visitdate, #map-modal-input .d_quantity, #map-modal-input .d_sludge, #map-modal-input .d_note").val('');
jQuery("#map-modal-input .d_payamount, #map-modal-input .d_payeename").val('');
jQuery("#map-modal-input .d_customeruid").val(customer_id);
jQuery("#map-modal-input .d_customerno").val(customer_no);
jQuery("#map-modal-input .d_paystatusunpaid").prop("checked", true);
jQuery("#map-modal-input .d_orderdate").val(jQuery("#orderdate").val());
<? if ($_SESSION['ss_LEVEL'] == 9) { ?>
jQuery("#map-modal-input .d_visitdate").prop("readonly", true);
let orderdateSTR = jQuery("#orderdate").val();
let orderdateRT = orderdateSTR.replaceAll("-","");
//alert(orderdateRT);
if(orderdateRT < <?=date("Ymd")?>) {
jQuery("#map-modal-input .btn-input-save").prop("disabled", true);
}else {
jQuery("#map-modal-input .btn-input-save").prop("disabled", false);
}
<? } ?>
let data = {
"c_uid" : customer_id,
"orderdate" : jQuery("#orderdate").val()
}
api('initInput', data, rstInitInput);
}
var rstInitInput = function(json) {
jQuery("#map-modal-input .shortinput-store-name").text(json.result['d_name']);
jQuery("#map-modal-input .shortinput-rate").text(json.result['d_rate']);
jQuery("#map-modal-input .d_driveruid").val(json.result['d_driveruid']);
jQuery("#map-modal-input .d_paymenttype").val(json.result['d_paymenttype']);
jQuery("#map-modal-input .d_sludge").val(json.result['d_sludge']);
if(json.result['d_uid'].length > 0) {
jQuery("#map-modal-input .d_uid").val(json.result['d_uid']);
jQuery("#map-modal-input .d_quantity").val(json.result['d_quantity']);
jQuery("#map-modal-input .d_note").val(json.result['d_note']);
if(json.result['d_paymenttype'] === 'CA') {
jQuery("#map-modal-input .CA_option").removeClass("hide");
jQuery("#map-modal-input .d_payamount").val(json.result['d_payamount']);
jQuery("#map-modal-input .d_payeename").val(json.result['d_payeename']);
if(json.result['d_paystatus'] === 'P') {
jQuery("#map-modal-input .d_paystatuspaid").prop("checked", true);
jQuery("#map-modal-input .d_paystatusunpaid").prop("unchecked", true);
} else if (json.result['d_paystatus'] === 'N') {
jQuery("#map-modal-input .d_paystatuspaid").prop("unchecked", true);
jQuery("#map-modal-input .d_paystatusunpaid").prop("checked", true);
}
} else{
jQuery("#map-modal-input .CA_option").addClass("hide");
}
}else{
if(json.result['d_paymenttype'] === 'CA') {
jQuery("#map-modal-input .CA_option").removeClass("hide");
}else{
jQuery("#map-modal-input .CA_option").addClass("hide");
}
}
//alert (jQuery("#map-modal-input .d_uid").val());
//alert (jQuery("#map-modal-input .d_paymenttype").val());
//visitdate setting
let visitdate = json.result['d_orderdate'];
//jQuery("#map-modal-input .d_visitdate").val(visitdate.substring(0, 4) + '-' + visitdate.substring(4, 6) + '-' + visitdate.substring(6, 8) + 'T' + visitdate.substring(8, 10) + ':' + visitdate.substring(10, 12));
jQuery("#map-modal-input .d_visitdate").val(visitdate.substring(0, 4) + '-' + visitdate.substring(4, 6) + '-' + visitdate.substring(6, 8));
}
function saveInputValidation(){
jQuery("#map-modal-input .d_visitdate, #map-modal-input .d_quantity").css("border","1px solid black");
if(jQuery("#map-modal-input .d_quantity").val().trim() === '') {
jQuery("#map-modal-input .d_quantity").css("border","1px solid red");
return false;
}
return true;
}
// 경로를 지도에서 제거하는 함수
function clearRoute() {
if (directionsRenderer) {
//directionsRenderer.setDirections({routes: []}); // 경로 데이터를 비우기
// 또는
directionsRenderer.setMap(null); // 지도에서 경로 제거
}
}
var rstInqRouteAddress = function(json) {
let output = '';
let tableData = '';
for(let i=0; i < json.result.length; i++) {
output += '<div class="draggable-item" draggable="true" id="visit_'+i+'" data="'+json.result[i]['lat']+'*&^&*'+json.result[i]['lon']+'*&^&*'+json.result[i]['name']+'*&^&*'+json.result[i]['address']+'*&^&*'+i+'">';
output += '<table>';
output += '<tr>';
output += '<td>'+(i+1)+'</td>';
output += '<td><b>'+json.result[i]['name']+'</b></td>';
output += '<td>'+json.result[i]['address']+', '+json.result[i]['city']+', '+json.result[i]['postal']+'</td>';
output += '</tr>';
output += '</table>';
output += '</div>';
tableData += '<div class="item-information-'+i+'">';
tableData += '<input type="text" class="account" value="'+json.result[i]['accountno']+'">';
tableData += '<input type="text" class="maincontainer" value="'+json.result[i]['maincontainer']+'">';
tableData += '<input type="text" class="paymenttype" value="'+json.result[i]['paymenttype']+'">';
tableData += '<input type="text" class="rate" value="'+json.result[i]['rate']+'">';
tableData += '<input type="text" class="address" value="'+json.result[i]['address']+'">';
tableData += '<input type="text" class="city" value="'+json.result[i]['city']+'">';
tableData += '<input type="text" class="lastpickupquantity" value="'+json.result[i]['lastpickupquantity']+'">';
tableData += '<input type="text" class="estquantity" value="'+json.result[i]['estquantity']+'">';
tableData += '<input type="text" class="quantity" value="'+json.result[i]['quantity']+'">';
tableData += '<input type="text" class="lastpaiddate" value="'+json.result[i]['lastpaiddate']+'">';
tableData += '<input type="text" class="this_year" value="'+json.result[i]['THIS_YEAR']+'">';
tableData += '<input type="text" class="last_year" value="'+json.result[i]['LAST_YEAR']+'">';
tableData += '<input type="text" class="fullcycle" value="'+json.result[i]['fullcycle']+'">';
tableData += '<input type="text" class="lastpickupdate" value="'+json.result[i]['lastpickupdate']+'">';
tableData += '</div>';
}
jQuery("#routePlannerModal #addressList").html(output);
jQuery("#routePlannerModal #addressInformationList").html(tableData);
let draggedItem = null;
document.querySelectorAll('.draggable-item').forEach(item => {
item.addEventListener('dragstart', function(e) {
draggedItem = this;
});
item.addEventListener('dragover', function(e) {
e.preventDefault(); // Necessary for allowing dropping.
});
item.addEventListener('drop', function(e) {
if (this !== draggedItem) {
let list = document.getElementById('addressList');
let currentPos = Array.from(list.children).indexOf(this);
let draggedPos = Array.from(list.children).indexOf(draggedItem);
if (currentPos < draggedPos) {
list.insertBefore(draggedItem, this);
} else {
list.insertBefore(draggedItem, this.nextSibling);
}
}
});
});
}
// Nearby 반경 원 생성 및 추가 함수
var circle;
function addCircle(center) {
circle = new google.maps.Circle({
strokeColor: '#FF0000', // 원의 선 색상
strokeOpacity: 0.8, // 원의 선 불투명도
strokeWeight: 2, // 원의 선 굵기
fillColor: '#FF0000', // 원의 채우기 색상
fillOpacity: 0.05, // 원의 채우기 불투명도
map: map, // 원이 추가될 지도 객체
center: center, // 원의 중심점 (위도, 경도)
radius: 1000 // 원의 반경 (미터 단위) 1km
});
map.fitBounds(circle.getBounds());
}
// Nearby 반경 원 삭제 함수
function removeCircle() {
if (circle) {
circle.setMap(null);
}
}
function drawPoint(){
if(!jQuery(".btn-route-print").hasClass("hidden")){
jQuery(".btn-route-print").addClass("hidden")
}
removeCircle();
clearRoute();
if (currentMarker) {
currentMarker.setMap(null); // Remove existing marker
currentMarker = null;
offLoading();
}
let quantity_array = [];
for(let i=0; i < jQuery(".qty").length; i++) {
quantity_array.push(
{
"checked" : jQuery(".qty:eq("+i+")").is(":checked"),
"min" : jQuery(".qty-min:eq("+i+")").val(),
"max" : jQuery(".qty-max:eq("+i+")").val()
}
);
}
let data = {
"search_date" : jQuery("#orderdate").val(),
"option" : {
"ordered" : jQuery(".chk-ordered").is(":checked")
},
"driver" : jQuery("#driver").val(),
"search" : jQuery("#search-keyword").val(),
"quantity" : quantity_array
}
api('inqPoint', data, rstInqPoint);
/*COOKIE UPDATE*/
let cookieValue = '0:' + jQuery(".qty-max:eq(0)").val();
for(let i=1;i < jQuery(".qty-min").length-1;i++) {
cookieValue += '_';
cookieValue += jQuery(".qty-min:eq("+i+")").val() + ':' + jQuery(".qty-max:eq("+i+")").val();
}
cookieValue += '_' + jQuery(".qty-min:eq("+(jQuery(".qty-min").length-1)+")").val() + ':MAX';
setCookie('qtySetting',cookieValue);
}
var marker = [];
var markerwindow = [];
var overlay = [];
var clusterer = null;
var clusterInfoGlobal = null;
var typeOrder = { "#FF0000": 1, "#800080": 2, "#FF80FF": 3, "#7B7A7A": 4 }; // Request > Scheduled > Normal > Finished
var rstInqPoint = function(json) {
if (clusterInfoGlobal) {
clusterInfoGlobal.close();
clusterInfoGlobal = null;
}
for(let j=0; j < marker.length; j++) {
marker[j].setMap(null);
marker[j] = null;
if(overlay[j] !== undefined) {
overlay[j].setMap(null);
overlay[j] = null;
}
}
if (clusterer) {
clusterer.setMap(null);
clusterer = null;
}
marker = [];
overlay = [];
let pointGeocoder = new google.maps.Geocoder();
let location = '';
for(let i=0; i < json.result.length; i++) {
let property = {
index : i,
store: json.result[i]['name'],
accountno: json.result[i]['accountno'],
paymentcycle: json.result[i]['paymentcycle'],
maincontainer: json.result[i]['maincontainer'],
rate: json.result[i]['rate'],
estqty: json.result[i]['estqty'],
phone: json.result[i]['phone'],
address: json.result[i]['address'],
paymentType: json.result[i]['payment_type'],
date: json.result[i]['order_date'],
ordertype: json.result[i]['ordertype'],
customerid: json.result[i]['id'],
type: json.result[i]['type'],
colour: "transparency",
color: json.result[i]['color'],
lat: json.result[i]['lat'],
lon: json.result[i]['lon'],
comment: json.result[i]['comment'],
container_location: json.result[i]['container_location'],
lastPickupDate: json.result[i]['last_pickup_date'],
lastPaidDate: json.result[i]['last_paid_date'],
duid: json.result[i]['duid'],
druid: json.result[i]['druid'],
rnote: json.result[i]['rnote'],
<? if ($_SESSION['ss_LEVEL'] == 9) { ?>
orderFlag: json.result[i]['orderFlag']
<? } else { ?>
orderFlag: ''
<? } ?>
};
let icon = (json.result[i]['type'] === 'flag')?getFlagIcon(json.result[i]['color']):getMarkerIcon(json.result[i]['color']);
//let orderFlagValue = (json.result[i]['orderFlag'] === '1')?"":"DISABLED";
if(json.result[i]['lat'].length < 1) {
pointGeocoder.geocode({ address: json.result[i]['address'] }, (results, status) => {
if (status === "OK" && results[0]) {
location = results[0].geometry.location;
latitude = results[0].geometry.location.lat();
longitude = results[0].geometry.location.lng();
let updtPointdata = {
"marker_index" : i,
"id" : json.result[i]['id'],
"accountno" : json.result[i]['accountno'],
"lat" : latitude,
"lon" : longitude,
"property" : property,
"name" : json.result[i]['name'],
"qty" : json.result[i]['estqty']
// 2025.06.19
//"qty" : json.result[i]['qty']
}
api('updtPoint', updtPointdata, rstUpdtPoint);
} else {
console.error("Geocoding failed for the account address: " + status);
}
});
}else{
location = {lat: parseFloat(json.result[i]['lat']), lng: parseFloat(json.result[i]['lon'])};
marker[i] = new google.maps.Marker({
position: location,
map: map,
icon: icon,
animation: (property.rnote && /\S/.test(property.rnote) && property.color !== "#7B7A7A") ? google.maps.Animation.BOUNCE : null
});
marker[i].customType = property.type; //'flag' 또는 'map-marker'
marker[i].property = property;
// Add an info window with company information
markerwindow[i] = new google.maps.InfoWindow({
content: `<strong>`+json.result[i]['name']+`</strong><br>Est. Quantity : `+json.result[i]['estqty']
});
marker[i].addListener('mouseover', () => {
markerwindow[i].open(map, marker[i]);
});
google.maps.event.addListener(markerwindow[i], 'domready', function() {
// InfoWindow의 닫기 버튼만 숨기기
const iwOuter = jQuery(".gm-style-iw").last();
const closeBtn = iwOuter.parent().find(".gm-ui-hover-effect");
closeBtn.css("display","none");
});
marker[i].addListener('mouseout', () => {
markerwindow[i].close();
});
let content = buildContent(property);
marker[i].addListener('click', function() {
if(overlay[i]) {
overlay[i].setMap(null);
}
overlay[i] = new CustomOverlay(map, marker[i].getPosition(), content.innerHTML, i);
});
}
}
// 클러스터 생성
if (marker.length > 0) {
// flag 타입만 필터링
const flagMarkers = marker.filter(m => m.customType === 'flag');
if (flagMarkers.length > 0) {
// 사이즈 줄이기
const algorithm = new markerClusterer.GridAlgorithm({
gridSize: 5,
maxDistance: 50,
});
clusterer = new markerClusterer.MarkerClusterer({
map,
markers: flagMarkers,
algorithm,
renderer: {
render: ({ count, position, markers }) => {
// 클러스터 안에 rnote 있는 flag 마커가 한 개라도 포함됐는지 확인
const hasRnoteMarker = markers.some(m =>
m.property && m.property.rnote && /\S/.test(m.property.rnote)
);
markers.sort((a, b) => {
const t1 = a.property.color || "#FF80FF";
const t2 = b.property.color || "#FF80FF";
return typeOrder[t1] - typeOrder[t2];
});
const topColor = markers[0]?.property?.color || "#4285f4";
const size = Math.min(50, 30 + Math.log(count) * 10);
return new google.maps.Marker({
position,
icon: {
url:
"data:image/svg+xml;charset=UTF-8," +
encodeURIComponent(`
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30">
<circle cx="15" cy="15" r="13"
fill="${topColor}" />
<text x="15" y="20" text-anchor="middle"
font-size="12" fill="#fff">${count}</text>
</svg>
`),
scaledSize: new google.maps.Size(30, 30),
anchor: new google.maps.Point(15, 15),
},
zIndex: Number(google.maps.Marker.MAX_ZINDEX) + count,
animation: (
// 클러스터 안에 rnote가 있으면서 finished가 아닌 마커가 1개라도 있는 경우만 Bounce
markers.some(m =>
m.property &&
m.property.rnote && /\S/.test(m.property.rnote) &&
m.property.color !== "#7B7A7A"
)
) ? google.maps.Animation.BOUNCE : null,
});
},
},
onClusterClick: (...args) => {
let clusterObj = null;
if (args.length === 1 && args[0]) {
const a = args[0];
clusterObj = a.cluster || a;
} else if (args.length >= 2) {
clusterObj = args[1];
}
if (!clusterObj) return false;
const markersInCluster =
clusterObj.markers ||
(typeof clusterObj.getMarkers === "function"
? clusterObj.getMarkers()
: []) ||
[];
const clusterCenter =
clusterObj.position ||
(typeof clusterObj.getCenter === "function"
? clusterObj.getCenter()
: null);
if (!markersInCluster.length || !clusterCenter) return false;
if (clusterInfoGlobal) {
clusterInfoGlobal.close();
}
markersInCluster.sort((a, b) => {
const t1 = a.property.color || "#FF80FF";
const t2 = b.property.color || "#FF80FF";
return typeOrder[t1] - typeOrder[t2];
});
let html =
"<div style='min-width:220px;max-height:240px;overflow:auto'>";
markersInCluster.forEach((m) => {
const p = m.property || {};
const hasRnote = p.rnote && /\S/.test(p.rnote);
html += `
<div class="cluster-item" data-marker-index="${p.index}" style="display:flex; align-items:center; margin-bottom:4px; cursor:pointer;">
<span style="width:15px; height:15px; margin-right:6px; background-color:${p.color || "#ccc"}; display:inline-block; border:1px solid #999;"></span>
<strong>${p.store ?? "—"}</strong>
${
hasRnote
? `<span style="margin-left:6px; padding:2px 4px; background:#FF9800; color:white; border-radius:3px; font-size:10px;">
notice
</span>`
: ""
}
</div>
<div style="margin-left:22px; font-size:12px; color:#333;">
Est. Quantity : ${p.estqty ?? "-"}
</div>
<hr style="margin:7px 0;">
`;
});
html += "</div>";
const clusterInfo = new google.maps.InfoWindow({
content: html,
position: clusterCenter,
pixelOffset: new google.maps.Size(0, -25),
});
clusterInfoGlobal = clusterInfo;
clusterInfo.open(map);
google.maps.event.addListenerOnce(
clusterInfo,
"domready",
function () {
document.querySelectorAll(".cluster-item").forEach((el) => {
el.addEventListener("click", () => {
const idx = el.getAttribute("data-marker-index");
if (idx !== null && marker[idx]) {
google.maps.event.trigger(marker[idx], "click");
}
clusterInfo.close();
});
});
}
);
return false;
},
});
}
// 클러스터링이 끝났을 때 실행되는 이벤트
clusterer.addListener('clusteringend', () => {
marker.forEach(m => {
if (!m.getMap()) return;
if (m.property?.rnote && /\S/.test(m.property.rnote) && m.property.color !== "#7B7A7A") {
m.setAnimation(google.maps.Animation.BOUNCE);
} else {
m.setAnimation(null);
}
});
});
}
}
function showInfoWindow(position, title, quantity, infoType) {
const showClose = infoType === 'cluster'; // 클러스터일 때만 X 표시
const infoContent = `
<div class="info-window">
${showClose ? '<button class="close" onclick="closeInfoWindow()">×</button>' : ''}
<div class="info-body">
<strong>${title}</strong><br>
Est. Quantity: ${quantity}
</div>
</div>
`;
infoWindow.setContent(infoContent);
infoWindow.setPosition(position);
infoWindow.open(map);
}
function addDragEvent(customOverlay) {
let div = customOverlay.div;
//for mobile
let table = div.querySelector('table');;
let title = div.querySelector('h4');
let isDragging = false;
let startX, startY;
let startDrag = (e) => {
isDragging = true;
startX = (e.clientX || e.touches[0].clientX) - div.offsetLeft;
startY = (e.clientY || e.touches[0].clientY) - div.offsetTop;
e.preventDefault();
// Prevent map from dragging
map.setOptions({ draggable: false });
console.log("aaa");
};
let onDrag = (e) => {
if (isDragging) {
const currentX = e.clientX || e.touches[0].clientX;
const currentY = e.clientY || e.touches[0].clientY;
const dx = currentX - startX;
const dy = currentY - startY;
if (Math.abs(dx) > 5 || Math.abs(dy) > 5) {
clickPrevent = true;
}
div.style.left = dx + 'px';
div.style.top = dy + 'px';
e.preventDefault();
}
};
let endDrag = (e) => {
if (isDragging) {
isDragging = false;
e.preventDefault();
// Re-enable map dragging
map.setOptions({ draggable: true });
if (!clickPrevent) {
// If not dragging, it is a click event
const target = e.target || e.touches[0].target;
if (target.tagName === 'BUTTON') {
target.click();
}
}
// Update the overlay position to the new location
const overlayProjection = customOverlay.getProjection();
const divPosition = new google.maps.Point(parseInt(div.style.left, 10), parseInt(div.style.top, 10));
const newPosition = overlayProjection.fromDivPixelToLatLng(divPosition);
customOverlay.position = newPosition;
customOverlay.draw();
}
};
div.addEventListener('mousedown', startDrag);
table.addEventListener('touchstart', startDrag, { passive: false });
title.addEventListener('touchstart', startDrag, { passive: false });
document.addEventListener('mousemove', onDrag);
document.addEventListener('touchmove', onDrag, { passive: false });
document.addEventListener('mouseup', endDrag);
document.addEventListener('touchend', endDrag, { passive: false });
}
// 깃발 모양 마커 아이콘 생성 함수에 16진수 색상 코드 사용
function getFlagIcon(color) {
return {
path: 'M64 32C64 14.3 49.7 0 32 0S0 14.3 0 32V64 368 480c0 17.7 14.3 32 32 32s32-14.3 32-32V352l64.3-16.1c41.1-10.3 84.6-5.5 122.5 13.4c44.2 22.1 95.5 24.8 141.7 7.4l34.7-13c12.5-4.7 20.8-16.6 20.8-30V66.1c0-23-24.2-38-44.8-27.7l-9.6 4.8c-46.3 23.2-100.8 23.2-147.1 0c-35.1-17.6-75.4-22-113.5-12.5L64 48V32z', // 깃발 모양의 간단한 SVG 경로
fillColor: color, // 16진수 색상 코드
fillOpacity: 1,
strokeColor: 'black',
strokeWeight: 0.5,
scale: 0.04,
};
}
// 원 모양 마커 아이콘 생성 함수에 16진수 색상 코드 사용
function getMarkerIcon(color) {
return {
path: 'M215.7 499.2C267 435 384 279.4 384 192C384 86 298 0 192 0S0 86 0 192c0 87.4 117 243 168.3 307.2c12.3 15.3 35.1 15.3 47.4 0zM192 128a64 64 0 1 1 0 128 64 64 0 1 1 0-128z',
fillColor: color,
fillOpacity: 1,
strokeColor: '#000',
strokeWeight: 0.5,
scale: 0.04,
};
}
// 현재위치 마커 아이콘 생성 함수에 16진수 색상 코드 사용
function getCurrentIcon(color) {
return {
path: 'M256 0c17.7 0 32 14.3 32 32V66.7C368.4 80.1 431.9 143.6 445.3 224H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H445.3C431.9 368.4 368.4 431.9 288 445.3V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V445.3C143.6 431.9 80.1 368.4 66.7 288H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H66.7C80.1 143.6 143.6 80.1 224 66.7V32c0-17.7 14.3-32 32-32zM128 256a128 128 0 1 0 256 0 128 128 0 1 0 -256 0zm128-80a80 80 0 1 1 0 160 80 80 0 1 1 0-160z',
fillColor: color,
fillOpacity: 1,
strokeColor: '#000',
strokeWeight: 0.5,
scale: 0.04,
};
}
function CustomOverlay(map, position, content, index) {
this.position = position;
this.content = content;
this.index = index;
this.map = map;
this.div = null;
this.setMap(map);
}
var rstUpdtPoint = function(json) {
let location = {lat: parseFloat(json.lat), lng: parseFloat(json.lon)};
let icon = (json.property['type'] === 'flag')?getFlagIcon(json.property['color']):getMarkerIcon(json.property['color']);
marker[parseInt(json.markerIndex)] = new google.maps.Marker({
position: location,
map: map,
icon: icon
});
// Add an info window with company information
markerwindow[parseInt(json.markerIndex)] = new google.maps.InfoWindow({
content: `<strong>`+json.name+`</strong><br>Est. Quantity : `+json.estqty
});
marker[parseInt(json.markerIndex)].addListener('mouseover', () => {
markerwindow[parseInt(json.markerIndex)].open(map, marker[parseInt(json.markerIndex)]);
});
marker[parseInt(json.markerIndex)].addListener('mouseout', () => {
markerwindow[parseInt(json.markerIndex)].close();
});
let content = buildContent(json.property);
marker[parseInt(json.markerIndex)].addListener('click', function() {
overlay[parseInt(json.markerIndex)] = new CustomOverlay(map, marker[parseInt(json.markerIndex)].getPosition(), content.innerHTML, parseInt(json.markerIndex));
});
}
async function initMap() {
// Request needed libraries.
const { Map } = await google.maps.importLibrary("maps");
map = new Map(document.getElementById("map"), {
zoom: 11,
center,
mapId: "4504f8b37365c3d0",
gestureHandling: 'greedy',
disableDefaultUI: true
});
/*
//find current position
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position) => {
center = { lat: position.coords.latitude, lng: position.coords.longitude };
currentLocation = { lat: position.coords.latitude, lon: position.coords.longitude };
map.setCenter(center);
}
);
}
*/
jQuery("#driver").trigger("change");
drawPoint();
CustomOverlay.prototype = new google.maps.OverlayView();
CustomOverlay.prototype.onAdd = function() {
var div = document.createElement('div');
div.style.position = 'absolute';
div.innerHTML = this.content;
this.div = div;
var panes = this.getPanes();
panes.overlayMouseTarget.appendChild(div);
// 닫기 버튼에 이벤트 리스너 추가
var closeButton = div.getElementsByClassName('overlay-close-'+this.index)[0];
closeButton.addEventListener('click', () => {
this.hide();
});
jQuery(".btn-add-order:eq("+this.index+")").click(function(){
addOrder(this.id);
});
addDragEvent(this);
};
CustomOverlay.prototype.draw = function() {
var overlayProjection = this.getProjection();
var position = overlayProjection.fromLatLngToDivPixel(this.position);
var div = this.div;
div.style.left = position.x + 'px';
div.style.top = position.y + 'px';
};
CustomOverlay.prototype.onRemove = function() {
if (this.div) {
this.div.parentNode.removeChild(this.div);
this.div = null;
}
};
CustomOverlay.prototype.hide = function() {
if (this.div) {
this.div.style.visibility = 'hidden';
}
};
CustomOverlay.prototype.show = function() {
if (this.div) {
this.div.style.visibility = 'visible';
}
};
}
function toggleHighlight(markerView, property) {
if (!markerView.content.classList.contains("highlight")) {
markerView.content.classList.add("highlight");
markerView.zIndex = 1;
}else{
}
/*
//info modal init
jQuery("#customerShortInfo .c_uid").val(property['customerid']);
jQuery(".shortinfo-payment-type").text(property['paymentType']);
jQuery(".shortinfo-comment").val(property['comment']);
jQuery(".shortinfo-container-location").val(property['container_location']);
//history modal init
}*/
}
function showShortInfo(id){
let loadingTxt = 'Loading...';
jQuery("#customerShortInfo .shortinfo-payment-type").text(loadingTxt);
jQuery("#customerShortInfo #c_comment_ri,#customerShortInfo #c_location").val(loadingTxt).attr("disabled","disabled");
jQuery("#customerShortInfo .btn-sub").attr("disabled","disabled");
let data = {
"id" : id
}
api('inqShortInfo', data, rstInqShortInfo);
}
var rstInqShortInfo = function(json) {
jQuery("#customerShortInfo .c_uid").val(json.result['id']);
jQuery("#customerShortInfo .c_accountno").val(json.result['accountno']);
jQuery("#customerShortInfo .shortinfo-store-name").text(json.result['name']);
jQuery("#customerShortInfo .shortinfo-payment-type").text(json.result['payment_type']);
jQuery("#customerShortInfo .shortinfo-payment-string").text(json.result['paymentstring']);
jQuery("#customerShortInfo #c_comment_ri").val(json.result['comment']).attr("disabled",false);
jQuery("#customerShortInfo #c_location").val(json.result['location']).attr("disabled",false);
jQuery("#customerShortInfo .btn-sub").attr("disabled",false);
if (json.result.install_img && json.result.install_img !== "") {
jQuery("#installImgArea").html(
'<a href="'+ json.result.install_img +'" target="_blank">View Image</a>'
);
} else {
jQuery("#installImgArea").html('<span>No image</span>');
}
}
function updtShortInfo(){
let data = {
"id" : jQuery("#customerShortInfo .c_uid").val(),
"accountno" : jQuery("#customerShortInfo .c_accountno").val(),
"comment" : jQuery(".shortinfo-comment").val(),
"location" : jQuery(".shortinfo-container-location").val()
}
api('updtShortInfo', data, rstUpdtShortInfo);
}
var rstUpdtShortInfo = function(json) {
drawPoint();
}
function showShortNotice(id){
let loadingTxt = 'Loading...';
jQuery("#map-modal-note #r_note").val('');
jQuery("#map-modal-note #r_note").text(loadingTxt);
let data = {
"id" : id
}
api('inqShortNotice', data, rstInqShortNotice);
}
var rstInqShortNotice = function(json) {
jQuery("#map-modal-note #r_note").val(json.result['rnote']).attr("disabled",false);
}
function inqCurrent() {
onLoading();
removeCircle();
//set to init
jQuery(".chk-ordered").prop("checked",true);
jQuery(".chk-scheduled").prop("checked",false);
jQuery(".chk-requested").prop("checked",false);
jQuery("#search-keyword").val("");
jQuery(".qty").prop("checked", true);
if (currentMarker) {
currentMarker.setMap(null); // Remove existing marker
currentMarker = null;
// map-marker만 제거
marker.forEach(marker => {
if (marker.customType === 'map-marker') {
marker.setMap(null);
}
});
offLoading();
}else{
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
const currentPosition = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
if (currentMarker) {
currentMarker.setMap(null); // Remove existing marker
}
currentMarker = new google.maps.Marker({
position: currentPosition,
map: map,
icon: getCurrentIcon('#dc3545'),
title: "Current Location"
});
map.setCenter(currentPosition);
addCircle(currentPosition);
let quantity_array = [];
for(let i=0; i < jQuery(".qty").length; i++) {
quantity_array.push(
{
"checked" : jQuery(".qty:eq("+i+")").is(":checked"),
"min" : jQuery(".qty-min:eq("+i+")").val(),
"max" : jQuery(".qty-max:eq("+i+")").val()
}
);
}
let data = {
"center_lat" : currentPosition.lat,
"center_lon" : currentPosition.lng,
"search_date" : jQuery("#orderdate").val(),
"driver" : jQuery("#driver").val(),
"quantity" : quantity_array
}
api('inqNearby', data, rstInqPoint);
smoothZoom(map, 14, map.getZoom());
offLoading();
}, function() {
offLoading();
alert("Unable to retrieve your location.");
});
} else {
offLoading();
alert("Geolocation is not supported by this browser.");
}
}
}
function inqNearby(coord){
removeCircle();
//set to init
jQuery(".chk-ordered").prop("checked",true);
jQuery(".chk-scheduled").prop("checked",false);
jQuery(".chk-requested").prop("checked",false);
jQuery("#search-keyword").val("");
jQuery(".qty").prop("checked",true);
if (currentMarker) {
currentMarker.setMap(null); // Remove existing marker
}
let coordArr = coord.split(":");
center = { lat: parseFloat(coordArr[0]), lng: parseFloat(coordArr[1]) };
map.setCenter(center);
addCircle(center);
let quantity_array = [];
for(let i=0; i < jQuery(".qty").length; i++) {
quantity_array.push(
{
"checked" : jQuery(".qty:eq("+i+")").is(":checked"),
"min" : jQuery(".qty-min:eq("+i+")").val(),
"max" : jQuery(".qty-max:eq("+i+")").val()
}
);
}
let data = {
"center_lat" : coordArr[0],
"center_lon" : coordArr[1],
"search_date" : jQuery("#orderdate").val(),
"driver" : jQuery("#driver").val(),
"quantity" : quantity_array
}
api('inqNearby', data, rstInqPoint);
}
function initHistory(id){
jQuery("#map-modal-history tbody").html("<tr><td colspan='5' class='text-center'>Loading</td></tr>");
let data = {
"id" : id
}
api('inqHistory', data, rstInqHistory);
}
var rstInqHistory = function(json) {
let output = '';
let j = json.result.length;
for(let i=0; i < json.result.length; i++) {
output += '<tr>';
output += '<td>' + j + '</td>';
output += '<td>' + json.result[i]['date'] + '</td>';
output += '<td>' + json.result[i]['quantity'] + '</td>';
output += '<td>' + json.result[i]['driver'] + '</td>';
output += '<td>' + json.result[i]['paid'] + '</td>';
output += '</tr>';
j -= 1;
}
jQuery("#map-modal-history tbody").html(output);
}
function buildContent(property) {
let content = document.createElement("div");
content.classList.add("property");
let innerHtml = `
<div class="point-overlay">
<div class="modal-header">
<h4 class="modal-title">${property.store} ${property.ordertype}</h4>
<!--h4 class="modal-title" onClick="javascript:jQuery('.overlay-close-${property.index}').trigger('click');">${property.store}</h4-->
<div class="close overlay-close-${property.index}">&times;</div>
</div><!--modal-header-->
<div class="store-info">
<table class="tb-info-box">
<!--table class="tb-info-box" onClick="javascript:jQuery('.overlay-close-${property.index}').trigger('click');"-->
<tr>
<td class="td-title-info">Account</td>
<td class="td-text-info">
<span>${property.accountno}</span>
</td>
<td class="td-title-info">Container</td>
<td class="td-text-info">
<span>${property.maincontainer}</span>
</td>
</tr>
<tr>
<td class="td-title-info">Payment</td>
<td class="td-text-info">
<span>${property.paymentType}</span>
</td>
<td class="td-title-info">Rate</td>
<td class="td-text-info">
<span>${property.rate}</span>
</td>
</tr>
<tr>
<td class="td-title-info">Phone</td>
<td class="td-text-info">
<span>${property.phone}</span>
</td>
<td class="td-title-info">Forecast</td>
<td class="td-text-info">
<span>${property.estqty}</span>
</td>
</tr>
<tr>
<td class="td-title-info">Last Pickup</td>
<td class="td-text-info">
<span>${property.lastPickupDate}</span>
</td>
<td class="td-title-info">Last Paid</td>
<td class="td-text-info">
<span>${property.lastPaidDate}</span>
</td>
</tr>
</table>
<div class="address-row">
<div class="address-title">Address</div>
<div class="address-content">
<a href="https://maps.google.com/?q=${encodeURIComponent(property.address)}"
class="address-link"
target="_blank"
rel="noopener noreferrer">
${property.address}
</a>
</div>
</div>
<div class="text-center map-grid-layout-col-3">
<button type="button" class="mapBtn btn-info-modal" onClick="javscript:showShortInfo(${property.customerid});" data-toggle="modal" data-target="#map-modal-info"><i class="fa-solid fa-question"></i> Info</button>
<button type="submit" class="mapBtn btn-grey-modal" onClick="javascript:initHistory(${property.customerid});" data-toggle="modal" data-target="#map-modal-history"><i class="bi bi-folder2-open"></i> History</button>`;
if(`${property.date}` === 'null') {
innerHtml += `<button type="button" class="mapBtn btn-primary-modal addOrderBtn_${property.index}" data-toggle="modal" onClick="javascript:initAddOrder(${property.customerid},${property.index});"><i class="fa-solid fa-plus"></i> Add</button>`;
innerHtml += `<button type="button" class="mapBtn btn-red-modal hidden removeOrderBtn_${property.index}" data-toggle="modal" data-target="#modal-confirm" onClick="javascript:removeOrder(${property.customerid},${property.duid},${property.index},'${property.accountno}');"><i class="fa-solid fa-xmark"></i> Remove</button>`;
}else{
innerHtml += `<button type="button" class="mapBtn btn-primary-modal addOrderBtn_${property.index} hidden" data-toggle="modal" onClick="javascript:initAddOrder(${property.customerid},${property.index});"><i class="fa-solid fa-plus"></i> Add</button>`;
innerHtml += `<button type="button" ${property.orderFlag} class="mapBtn btn-red-modal removeOrderBtn_${property.index}" data-toggle="modal" data-target="#modal-confirm" onClick="javascript:removeOrder(${property.customerid},${property.duid},${property.index},'${property.accountno}');"><i class="fa-solid fa-xmark"></i> Remove</button>`;
}
innerHtml += `<button type="submit" class="mapBtn btn-nearby" onClick="javascript:inqNearby('${property.lat}:${property.lon}');"><i class="fa-solid fa-diamond-turn-right"></i> Nearby</button>
<button type="submit" class="mapBtn btn-orange-modal ${(property.rnote && /\S/.test(property.rnote)) ? 'blink' : ''}" data-toggle="modal" data-target="#map-modal-note" onClick="javscript:showShortNotice(${property.duid});"><i class="fa fa-thumb-tack"></i> Notice</button>
<button type="submit" class="mapBtn btn-purple-modal" data-toggle="modal" data-target="#map-modal-input" onClick="javascript:initInput(${property.customerid},'${property.accountno}');"><i class="bi bi-truck"></i> Input</button>
</div>
</div>
</div>
`;
content.innerHTML = innerHtml;
return content;
}
var rstInqMapCenter = function(json) {
center = { lat: parseFloat(json.geo['lat']), lng: parseFloat(json.geo['lon']) };
currentLocation = { lat: parseFloat(json.geo['lat']), lon: parseFloat(json.geo['lon']) };
map.setCenter(center);
}
function onLoading(){
jQuery(".loading-overlay").css("display","flex");
}
function offLoading(){
jQuery(".loading-overlay").css("display","none");
}
function imagepopup(c_uid) {
const url = `/lib/customer_image_upload_popup.php?c_uid=${c_uid}`;
window.open(url, "uploadImage", "width=600,height=750,scrollbars=yes");
}
</script>
<script>
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.number-input').forEach(container => {
const input = container.querySelector('.d_sludge');
const leftBtn = container.querySelector('.left');
const rightBtn = container.querySelector('.right');
const step = 5;
leftBtn.addEventListener('click', () => {
const min = input.min ? parseInt(input.min) : -Infinity;
let value = parseInt(input.value || 0);
if (value - step >= min) input.value = value - step;
});
rightBtn.addEventListener('click', () => {
const max = input.max ? parseInt(input.max) : Infinity;
let value = parseInt(input.value || 0);
if (value + step <= max) input.value = value + step;
});
});
});
async function forceRefresh() {
if ('caches' in window) {
const keys = await caches.keys();
await Promise.all(keys.map(key => caches.delete(key)));
}
window.location.reload();
/*
const cssFiles = [
'mapMAPCSS.css',
'main.css',
'leftside-modal.css'
];
cssFiles.forEach(file => {
const oldLink = Array.from(document.querySelectorAll('link[rel="stylesheet"]'))
.find(l => l.href.endsWith(file));
if (oldLink) {
const newLink = oldLink.cloneNode();
newLink.href = oldLink.href.split('?')[0] + '?view=map&_=' + new Date().getTime();
oldLink.parentNode.replaceChild(newLink, oldLink);
console.log(`CSS replaced: ${newLink.href}`);
} else {
console.warn(`CSS not found: ${file}`);
}
});
if ('caches' in window) {
const keys = await caches.keys();
console.log('Cache keys found:', keys);
await Promise.all(keys.map(key => caches.delete(key)));
console.log('Caches cleared');
}
console.log('CSS force refresh completed without page reload');
*/
}
$('.point-overlay').on(
'click mousedown mouseup touchstart touchend pointerdown pointerup',
function (e) {
e.stopPropagation();
}
);
$('.point-overlay *').on(
'click mousedown mouseup touchstart touchend pointerdown pointerup',
function (e) {
e.stopPropagation();
}
);
</script>