1430 lines
		
	
	
		
			72 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1430 lines
		
	
	
		
			72 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
| @extends('app.app')
 | |
| @section('title')
 | |
|     Transactions
 | |
| @endsection
 | |
| @section('customcss')
 | |
|     <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="" />
 | |
|     <style>
 | |
|         #mapId {
 | |
|             height: 180px;
 | |
|         }
 | |
|     </style>
 | |
| @endsection
 | |
| @section('content')
 | |
|     <div class="container-fluid">
 | |
|         <div class="content">
 | |
|             <div class="row">
 | |
|                 <div class="col-sm-12">
 | |
|                     <div class="card">
 | |
|                         <div class="card-header">
 | |
|                             <div class="row d-flex align-items-center">
 | |
|                                 <div class="col">
 | |
|                                     <p class="card-title text-bold mb-0">Jobs</p>
 | |
|                                     {{-- <p class="card-subtitle text-muted">Jobs List</p> --}}
 | |
|                                 </div>
 | |
|                                 {{-- <div class="col-auto text-end ps-0">
 | |
|                                     <a href="#" id="btnMdlMrgTrx" class="btn btn-sm btn-danger">Merge Transaksi</a>
 | |
|                                 </div>
 | |
|                                 <div class="col-auto text-end ps-0">
 | |
|                                     <a href="{{ route('view_transactions_spc_add') }}" class="btn btn-sm btn-warning">Transaksi Khusus</a>
 | |
|                                 </div> --}}
 | |
|                                 @can('transaction.create')
 | |
|                                     <div class="col-auto text-end ps-0">
 | |
|                                         <a href="{{ route('view_transactions_add') }}" class="btn btn-sm btn-danger">Add New Job</a>
 | |
|                                     </div>
 | |
|                                 @endcan
 | |
|                             </div>
 | |
|                         </div>
 | |
|                         <div class="card-body">
 | |
|                             <div class="table-responsive">
 | |
|                                 <table id="tOrders" class="table table-hover dataTable w-100">
 | |
|                                     <thead>
 | |
|                                         <tr class="">
 | |
|                                             <th class="">#</th>
 | |
|                                             <th class="text-nowrap text-center">Action</th>
 | |
|                                             <th class="text-nowrap">Order Code</th>
 | |
|                                             <th class="text-nowrap">Company</th>
 | |
|                                             <th class="text-nowrap">Order Time</th>
 | |
|                                             {{-- <th class="text-nowrap">Vendor</th> --}}
 | |
|                                             <th class="text-nowrap">Vehicle</th>
 | |
|                                             <th class="text-nowrap">Driver</th>
 | |
|                                             <th class="text-nowrap">Origin</th>
 | |
|                                             <th class="text-nowrap">Destination</th>
 | |
|                                             <th class="text-nowrap text-center">Status</th>
 | |
|                                         </tr>
 | |
|                                     </thead>
 | |
|                                     <tbody>
 | |
|                                         {{-- <tr class="">
 | |
|                                             <td class="text-nowrap">1</td>
 | |
|                                             <td class="text-nowrap">SiCepat</td>
 | |
|                                             <td class="text-nowrap">Feb 20, 2022 17:29:50</td>
 | |
|                                             <td class="text-nowrap"><span class="text-danger">belum ditugaskan</span>
 | |
|                                             </td>
 | |
|                                             <td class="text-nowrap"><span class="text-danger">belum ditugaskan</span>
 | |
|                                             </td>
 | |
|                                             <td class="text-nowrap"><span class="text-danger">belum ditugaskan</span>
 | |
|                                             </td>
 | |
|                                             <td class="text-nowrap">Gudang Pluit SiCepat (Jakarta)</td>
 | |
|                                             <td class="text-nowrap">Kantor Pusat SiCepat (yogyakarta)</td>
 | |
|                                             <td class="text-center">
 | |
|                                                 <span class="badge bg-warning text-dark">Menunggu Konfirmasi</span>
 | |
|                                             </td>
 | |
|                                             <td class="align-baseline text-center">
 | |
|                                                 <a href="{{ route('view_transactions_confirm') }}" class="text-decoration-none me-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Edit">
 | |
|                                                     <span class="icon ion-forward text-danger fz-16"></span>
 | |
|                                                 </a>
 | |
|                                                 <a href="{{ route('view_transactions_view') }}" class="text-decoration-none me-1" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Edit">
 | |
|                                                     <span class="icon ion-eye text-danger fz-16"></span>
 | |
|                                                 </a>
 | |
|                                             </td>
 | |
|                                         </tr> --}}
 | |
|                                     </tbody>
 | |
|                                 </table>
 | |
|                             </div>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
|         </div>
 | |
|     </div>
 | |
| 
 | |
|     {{-- modal pantu --}}
 | |
|     <div class="modal" id="mdlPantau" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false" aria-labelledby="mdlPantau" aria-hidden="true">
 | |
|         <div class="modal-dialog modal-fullscreen">
 | |
|             <div class="modal-content">
 | |
|                 <div class="modal-header">
 | |
|                     <h5 class="modal-title" id="mdlPantau-code">#828469287552</h5>
 | |
|                     {{-- <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> --}}
 | |
|                 </div>
 | |
|                 <div class="modal-body">
 | |
|                     <div id="map"></div>
 | |
|                 </div>
 | |
|                 <div class="modal-footer">
 | |
|                     <button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Close</button>
 | |
|                 </div>
 | |
|             </div>
 | |
|         </div>
 | |
|     </div>
 | |
| 
 | |
|     {{-- modal merge payment --}}
 | |
|     <div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="mdlMrgItem" aria-labelledby="mdlMrgItemLabel" aria-hidden="true">
 | |
|         <div class="modal-dialog modal-dialog-centered modal-sm">
 | |
|             <div class="modal-content">
 | |
|                 <div class="modal-header">
 | |
|                     <h5 class="modal-title" id="mdlMrgItemLabel">Merge Item</h5>
 | |
|                     <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
 | |
|                 </div>
 | |
|                 <div class="modal-body">
 | |
|                     <div class="d-flex justify-content-center flex-column">
 | |
|                         <div class="row">
 | |
|                             <div class="col-12">
 | |
|                                 <div class="mb-3">
 | |
|                                     <label for="mrg-sel_from_trx_code" class="form-label">Merge dari transaksi <span class="text-danger">*</span></label>
 | |
|                                     <select name="mrg-sel_from_trx_code" id="mrg-sel_from_trx_code" class="select2 form-control" style="width: 100% !important">
 | |
|                                         <option value="" selected disabled>Belum ada transaksi yang dipilih</option>
 | |
|                                         @foreach ($availOrdToMerge as $row)
 | |
|                                             <option value="{{ $row->code }}" data-id="{{ $row->id }}" data-code="{{ $row->code }}">{{ $row->code }}</option>
 | |
|                                         @endforeach
 | |
|                                     </select>
 | |
|                                 </div>
 | |
|                             </div>
 | |
|                             <div class="col-12">
 | |
|                                 <div class="mb-3">
 | |
|                                     <label for="mrg-sel_to_trx_code" class="form-label">Merge ke transaksi <span class="text-danger">*</span></label>
 | |
|                                     <select name="mrg-sel_to_trx_code" id="mrg-sel_to_trx_code" class="select2 form-control" style="width: 100% !important">
 | |
|                                         <option value="" selected disabled>Belum ada transaksi yang dipilih</option>
 | |
|                                         @foreach ($availOrdToMerge as $row)
 | |
|                                             <option value="{{ $row->code }}" data-id="{{ $row->id }}" data-code="{{ $row->code }}">{{ $row->code }}</option>
 | |
|                                         @endforeach
 | |
|                                     </select>
 | |
|                                 </div>
 | |
|                             </div>
 | |
|                             <div class="col-12">
 | |
|                                 <div class="mb-3">
 | |
|                                     <label for="mrg-new_buy_price" class="form-label">Biaya <span class="text-danger">*</span></label>
 | |
|                                     <input type="text" name="mrg-new_buy_price" id="mrg-new_buy_price" class="form-control">
 | |
|                                     <small class="text-muted">Biaya baru untuk vendor dari 2 transaksi</small>
 | |
|                                 </div>
 | |
|                             </div>
 | |
|                             <div class="col-12">
 | |
|                                 <div class="mb-3">
 | |
|                                     <label for="mrg-note" class="form-label">Catatan <span class="text-dark">(Opsional)</span></label>
 | |
|                                     <textarea name="mrg-note" id="mrg-note" class="form-control"></textarea>
 | |
|                                 </div>
 | |
|                             </div>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                 </div>
 | |
|                 <div class="modal-footer">
 | |
|                     <button type="button" class="btn btn-sm btn-danger" data-bs-dismiss="modal">Close</button>
 | |
|                     <button id="btnSubmitMergeItem" type="button" class="btn btn-sm btn-warning">Ya, merge</button>
 | |
|                     <div id="btnSubmitMergeItem-loader" class="d-none">
 | |
|                         <div class="spinner-border" role="status">
 | |
|                             <span class="visually-hidden">Loading...</span>
 | |
|                         </div>
 | |
|                     </div>
 | |
|                 </div>
 | |
|             </div>
 | |
|         </div>
 | |
|     </div>
 | |
| 
 | |
|     <div class="modal fade" id="mdlDelOrder" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false" aria-labelledby="mdlDelOrder" aria-hidden="true">
 | |
|         <div class="modal-dialog modal-dialog-centered modal-sm">
 | |
|             <div class="modal-content">
 | |
|                 <div class="modal-header">
 | |
|                     <h5 class="modal-title" id="mdlDelOrder">Delete Order</h5>
 | |
|                     <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
 | |
|                 </div>
 | |
|                 <div class="modal-body">
 | |
|                     <div class="d-flex justify-content-center">
 | |
|                         <p class="mb-0">
 | |
|                             Apa kamu yakin ingin menghapus order ini ?
 | |
|                             <a href="#" class="text-danger">
 | |
|                                 #<span id="del-ord_code"></span>
 | |
|                             </a>
 | |
|                         </p>
 | |
|                     </div>
 | |
|                 </div>
 | |
|                 <div class="modal-footer">
 | |
|                     <button type="button" class="btn btn-sm btn-danger" data-bs-dismiss="modal">Close</button>
 | |
|                     @can('transaction.delete')
 | |
|                         <button id="btnSubmitDelOrder" type="button" class="btn btn-sm btn-secondary">Yes, delete</button>
 | |
|                     @endcan
 | |
|                 </div>
 | |
|             </div>
 | |
|         </div>
 | |
|     </div>
 | |
| @endsection
 | |
| 
 | |
| @section('customjs')
 | |
|     <script src="{{ asset('assets/vendor/leaflet-1.7.1/leaflet-src.js') }}"></script>
 | |
|     <script>
 | |
|         'use strict';
 | |
|         const State = {
 | |
|             file_jimp_worker: "{{ asset('assets/js/worker/jimp.js') }}",
 | |
|             storage_lara: "{{ asset('storage') }}/",
 | |
|             stts_order: {
 | |
|                 wait: "{{ App\Models\Orders::STTS_WAIT }}",
 | |
|                 confirm: "{{ App\Models\Orders::STTS_CONFIRM }}",
 | |
|                 have_get_vhc: "{{ App\Models\Orders::STTS_HAVE_GET_VHC }}",
 | |
|                 pck: "{{ App\Models\Orders::STTS_PCK }}",
 | |
|                 go: "{{ App\Models\Orders::STTS_GO }}",
 | |
|                 arv: "{{ App\Models\Orders::STTS_ARV }}",
 | |
|                 drop: "{{ App\Models\Orders::STTS_DROP }}",
 | |
|                 client_pay: "{{ App\Models\Orders::STTS_CLIENT_PAY }}",
 | |
|                 vendor_payed: "{{ App\Models\Orders::STTS_VENDOR_PAYED }}",
 | |
|                 close: "{{ App\Models\Orders::STTS_CLOSE }}",
 | |
|                 cancel: "{{ App\Models\Orders::STTS_CANCEL }}",
 | |
|             },
 | |
|             stts_pck: {
 | |
|                 wait: "{{ App\Models\OrdersPickups::STTS_WAIT }}",
 | |
|                 picking: "{{ App\Models\OrdersPickups::STTS_PICKING }}",
 | |
|                 picked: "{{ App\Models\OrdersPickups::STTS_PICKED }}",
 | |
|                 fail: "{{ App\Models\OrdersPickups::STTS_FAIL }}",
 | |
|             },
 | |
|             stts_drop: {
 | |
|                 wait: "{{ App\Models\OrdersDrops::STTS_WAIT }}",
 | |
|                 dropping: "{{ App\Models\OrdersDrops::STTS_DROPING }}",
 | |
|                 droped: "{{ App\Models\OrdersDrops::STTS_DROPED }}",
 | |
|                 fail: "{{ App\Models\OrdersDrops::STTS_FAIL }}",
 | |
|             },
 | |
|             stts_engine: {
 | |
|                 idling: "{{ App\Models\Tracks::STTS_EN_IDLING }}",
 | |
|                 moving: "{{ App\Models\Tracks::STTS_EN_MOVING }}",
 | |
|                 stoping: "{{ App\Models\Tracks::STTS_EN_STOPING }}",
 | |
|             },
 | |
|             stts_ignition: {
 | |
|                 active: "{{ App\Models\Tracks::STTS_IGNITION_ON }}",
 | |
|                 inactive: "{{ App\Models\Tracks::STTS_IGNITION_OFF }}",
 | |
|                 low: "{{ App\Models\Tracks::STTS_IGNITION_LOW }}",
 | |
|                 high: "{{ App\Models\Tracks::STTS_IGNITION_HIGH }}",
 | |
|             },
 | |
|             url_conf_order: "{{ route('view_transactions_confirm') }}",
 | |
|             url_view_order: "{{ route('view_transactions_view') }}",
 | |
|             inShowOrdId: 0,
 | |
|             inShowOrdCode: 0,
 | |
|             eventRemoveDestination: null,
 | |
|             eventRemoveHistory: null,
 | |
|         };
 | |
| 
 | |
|         const Icon = {
 | |
|             hub: function() {
 | |
|                 return L.icon({
 | |
|                     iconUrl: "{{ asset('assets/icons/pin-resto.png') }}",
 | |
|                     iconSize: [38, 48],
 | |
|                     iconAnchor: [20, 46], // lb, rt, bottom, rb. Positive
 | |
|                     popupAnchor: [0, -32],
 | |
|                     // shadowUrl: 'my-icon-shadow.png',
 | |
|                     // shadowSize: [68, 95],
 | |
|                     // shadowAnchor: [22, 94]
 | |
|                 });
 | |
|             },
 | |
|             destination: function() {
 | |
|                 return L.icon({
 | |
|                     iconUrl: "{{ asset('assets/icons/pin-tujuan.png') }}",
 | |
|                     iconSize: [38, 48],
 | |
|                     iconAnchor: [20, 46], // lb, rt, bottom, rb. Positive
 | |
|                     popupAnchor: [0, -32],
 | |
|                     // shadowUrl: 'my-icon-shadow.png',
 | |
|                     // shadowSize: [68, 95],
 | |
|                     // shadowAnchor: [22, 94]
 | |
|                 });
 | |
|             },
 | |
|             point: function() {
 | |
|                 return L.icon({
 | |
|                     // iconUrl: 'https://www.nicepng.com/png/full/101-1015767_map-marker-circle-png.png',
 | |
|                     iconUrl: "{{ asset('assets/icons/maps-marker-circle-blue-radius.png') }}",
 | |
|                     iconSize: [38, 38],
 | |
|                     // iconAnchor: [20, 46], // lb, rt, bottom, rb. Positive
 | |
|                     // popupAnchor: [0, -32],
 | |
|                     // shadowUrl: 'my-icon-shadow.png',
 | |
|                     // shadowSize: [68, 95],
 | |
|                     // shadowAnchor: [22, 94]
 | |
|                 });
 | |
|             },
 | |
|             startNav: function() {
 | |
|                 return L.icon({
 | |
|                     iconUrl: 'https://image.flaticon.com/icons/png/512/803/803559.png',
 | |
|                     iconSize: [38, 38],
 | |
|                     iconAnchor: [20, 16], // lb, rt, bottom, rb. Positive
 | |
|                     // popupAnchor: [0, -32],
 | |
|                     // shadowUrl: 'my-icon-shadow.png',
 | |
|                     // shadowSize: [68, 95],
 | |
|                     // shadowAnchor: [22, 94]
 | |
|                 });
 | |
|             },
 | |
|             titikAwal: function() {
 | |
|                 return L.icon({
 | |
|                     iconUrl: "{{ asset('images/start.png') }}",
 | |
|                     iconSize: [30, 30],
 | |
|                     iconAnchor: [15, 28], // lb, rt, bottom, rb. Positive
 | |
|                     // popupAnchor: [0, -32],
 | |
|                     // shadowUrl: 'my-icon-shadow.png',
 | |
|                     // shadowSize: [68, 95],
 | |
|                     // shadowAnchor: [22, 94]
 | |
|                 });
 | |
|             },
 | |
|             titikAkhir: function() {
 | |
|                 return L.icon({
 | |
|                     iconUrl: "{{ asset('images/finish.png') }}",
 | |
|                     iconSize: [30, 30],
 | |
|                     iconAnchor: [15, 28], // lb, rt, bottom, rb. Positive
 | |
|                     // popupAnchor: [0, -32],
 | |
|                     // shadowUrl: 'my-icon-shadow.png',
 | |
|                     // shadowSize: [68, 95],
 | |
|                     // shadowAnchor: [22, 94]
 | |
|                 });
 | |
|             },
 | |
|             vechicleIcon: function() {
 | |
|                 return L.icon({
 | |
|                     iconUrl: "{{ asset('images/2active.png') }}",
 | |
|                     iconSize: [30, 30],
 | |
|                     iconAnchor: [15, 28], // lb, rt, bottom, rb. Positive
 | |
|                     popupAnchor: [-3, -35],
 | |
|                     // shadowUrl: 'my-icon-shadow.png',
 | |
|                     // shadowSize: [68, 95],
 | |
|                     // shadowAnchor: [22, 94]
 | |
|                 });
 | |
|             },
 | |
|             vhcIdleIcon: function() {
 | |
|                 return L.icon({
 | |
|                     iconUrl: "{{ asset('images/2idle.png') }}",
 | |
|                     iconSize: [30, 30],
 | |
|                     iconAnchor: [15, 28], // lb, rt, bottom, rb. Positive
 | |
|                     popupAnchor: [-3, -35],
 | |
|                     // shadowUrl: 'my-icon-shadow.png',
 | |
|                     // shadowSize: [68, 95],
 | |
|                     // shadowAnchor: [22, 94]
 | |
|                 });
 | |
|             },
 | |
|         };
 | |
| 
 | |
|         const Wrapper = {
 | |
|             activate: function() {
 | |
|                 Wrapper.event();
 | |
|                 OrdTable.activate();
 | |
|                 OrdMerge.activate();
 | |
|                 Leaflet.activate();
 | |
|                 OrdTrack.activate();
 | |
|                 OrdDelete.activate();
 | |
|                 Filter.activate();
 | |
|             },
 | |
|             event: function() {},
 | |
|             getHtmlSttsOrd: function(stts, stts_pck = 99, stts_drop = 99) {
 | |
|                 if (State.stts_order.wait == stts) {
 | |
|                     return '<span class="badge bg-warning text-dark">Menunggu Konfirmasi</span>';
 | |
|                 } else if (State.stts_order.confirm == stts) {
 | |
|                     return '<span class="badge bg-warning text-dark">Mencari Kendaraan</span>';
 | |
|                 } else if (State.stts_order.have_get_vhc == stts) {
 | |
|                     return '<span class="badge bg-warning text-dark">Kendaraan Menuju Lokasi Penjemputan</span>';
 | |
|                 } else if (State.stts_order.pck == stts) {
 | |
|                     // return '<span class="badge bg-warning text-dark">Berhasil Mengambil Pesanan</span>';
 | |
|                     if (State.stts_pck.wait == stts_pck) {
 | |
|                         return '<span class="badge bg-warning text-dark">Tiba Dilokasi Penjemputan</span>';
 | |
|                     } else if (State.stts_pck.picking == stts_pck) {
 | |
|                         return '<span class="badge bg-warning text-dark">Sedang Memuat Barang</span>';
 | |
|                     } else if (State.stts_pck.picked == stts_pck) {
 | |
|                         return '<span class="badge bg-warning text-dark">Berhasil Mengambil Pesanan</span>';
 | |
|                     } else if (State.stts_pck.fail == stts_pck) {
 | |
|                         return '<span class="badge bg-warning text-dark">Gagal Mengambil Pesanan</span>';
 | |
|                     }
 | |
|                 } else if (State.stts_order.go == stts) {
 | |
|                     return '<span class="badge bg-info text-dark">Menuju Lokasi Pengantaran</span>';
 | |
|                 } else if (State.stts_order.arv == stts) {
 | |
|                     // return '<span class="badge bg-info text-dark">Tiba Dilokasi Pengantaran</span>';
 | |
|                     if (State.stts_drop.wait == stts_drop) {
 | |
|                         return '<span class="badge bg-warning text-dark">Tiba Dilokasi Pengantaran</span>';
 | |
|                     } else if (State.stts_drop.dropping == stts_drop) {
 | |
|                         return '<span class="badge bg-warning text-dark">Sedang Membongkar Barang</span>';
 | |
|                     } else if (State.stts_drop.droped == stts_drop) {
 | |
|                         return '<span class="badge bg-warning text-dark">Berhasil Drop Pesanan</span>';
 | |
|                     } else if (State.stts_drop.fail == stts_drop) {
 | |
|                         return '<span class="badge bg-warning text-dark">Gagal Drop Pesanan</span>';
 | |
|                     }
 | |
|                 } else if (State.stts_order.drop == stts) {
 | |
|                     return '<span class="badge bg-warning text-dark">Selesai Melakukan Pengantaran</span>';
 | |
|                 } else if (State.stts_order.client_pay == stts) {
 | |
|                     // return '<span class="badge bg-danger text-light">Invoicing to Client</span>';
 | |
|                     return '<span class="badge bg-danger text-light">Selesai (Waiting Payment)</span>';
 | |
|                 } else if (State.stts_order.vendor_payed == stts) {
 | |
|                     // return '<span class="badge bg-danger text-light">Payment to Vendor</span>';
 | |
|                     return '<span class="badge bg-danger text-light">Selesai (Menunggu Pembayaran)</span>';
 | |
|                 } else if (State.stts_order.close == stts) {
 | |
|                     return '<span class="badge bg-danger text-light">Selesai</span>';
 | |
|                 } else if (State.stts_order.cancel == stts) {
 | |
|                     return '<span class="badge bg-danger text-light">Dibatalkan</span>';
 | |
|                 } else {
 | |
|                     return '<span class="badge bg-secondary text-white">-</span>';
 | |
|                 }
 | |
|             },
 | |
|         };
 | |
| 
 | |
|         const OrdTable = {
 | |
|             activate: function() {
 | |
|                 OrdTable.reload();
 | |
|             },
 | |
|             reload: function() {
 | |
|                 // $('#tOrders').DataTable();
 | |
|                 // if (User.Table.firstInitDataTable == 1) { loadTableSkeletonLoading() } else { User.Table.firstInitDataTable = 1; }
 | |
|                 $('#tOrders').DataTable({
 | |
|                     processing: true,
 | |
|                     serverSide: false,
 | |
|                     bLengthChange: true,
 | |
|                     deferRender: true,
 | |
|                     destroy: true,
 | |
|                     ajax: {
 | |
|                         url: "{{ route('api_list_orders') }}?cptid=" + AppState.current_company + '&order_by=desc',
 | |
|                         type: 'GET',
 | |
|                         complete: function(jqXHR, textStatus, c) {
 | |
|                             let count = jqXHR.responseJSON.count;
 | |
|                             if (typeof count != 'undefined') {
 | |
|                                 $('#count_orders').text(count);
 | |
|                             }
 | |
|                             // removeTableSkeletonLoading()
 | |
|                         },
 | |
|                     },
 | |
|                     deferRender: true,
 | |
|                     columns: [{
 | |
|                             data: 'DT_RowIndex',
 | |
|                             className: 'text-end',
 | |
|                             visible: true,
 | |
|                             orderable: true,
 | |
|                             searchable: true,
 | |
|                         },
 | |
|                         {
 | |
|                             data: 'action',
 | |
|                             className: 'text-center',
 | |
|                             visible: true,
 | |
|                             orderable: true,
 | |
|                             searchable: true,
 | |
|                             render: function(data, type, row, meta) {
 | |
|                                 console.log("rows: ", row)
 | |
|                                 let action = ``;
 | |
|                                 // if (row.confirm_at === 0) {
 | |
|                                 // if (!row.vdr_name) {
 | |
|                                 //     action += `<a href="${State.url_conf_order}?code=${row.ord_code}"
 | |
|                             //     class="text-decoration-none me-1" data-bs-toggle="tooltip"
 | |
|                             //     data-bs-placement="bottom" title="Tindak Lanjuti">
 | |
|                             //     <span class="icon ion-forward text-danger fz-16"></span>
 | |
|                             //     </a>`;
 | |
|                                 // } else {
 | |
|                                 //     let ord_codes = row.ord_code;
 | |
|                                 //     if (typeof row.childs != 'undefined' && row.childs.length > 0) {
 | |
|                                 //         for (const child of row.childs) {
 | |
|                                 //             ord_codes += ',' + child.ord_code;
 | |
|                                 //         }
 | |
|                                 //     }
 | |
|                                 //     action += `
 | |
|                             //         <a href="${State.url_view_order}?code=${ord_codes}"
 | |
|                             //             class="text-decoration-none me-1" data-bs-toggle="tooltip"
 | |
|                             //             data-bs-placement="bottom" title="Lihat">
 | |
|                             //             <span class="icon ion-eye text-danger fz-16"></span>
 | |
|                             //         </a>
 | |
|                             //     `;
 | |
|                                 //     action += `
 | |
|                             //         <a href="#"
 | |
|                             //             class="text-decoration-none me-1 btnTrackOrder" data-bs-toggle="tooltip"
 | |
|                             //             data-bs-placement="bottom" title="Tracking #${row.ord_code}"
 | |
|                             //             data-id="${row.ord_id}" data-code="${row.ord_code}">
 | |
|                             //             <span class="icon ion-map text-danger fz-16"></span>
 | |
|                             //         </a>
 | |
|                             //     `;
 | |
|                                 //     // data-bs-toggle="modal" data-bs-target="#mdlPantau"
 | |
|                                 //     for (const child of row.childs) {
 | |
|                                 //         action += `
 | |
|                             //         <a href="#"
 | |
|                             //             class="text-decoration-none me-1 btnTrackOrder" data-bs-toggle="tooltip"
 | |
|                             //             data-bs-placement="bottom" title="Tracking #${child.ord_code}"
 | |
|                             //             data-id="${child.ord_id}" data-code="${child.ord_code}">
 | |
|                             //             <span class="icon ion-map text-danger fz-16"></span>
 | |
|                             //         </a>
 | |
|                             //         `;
 | |
|                                 //     }
 | |
|                                 // }
 | |
|                                 // action += `
 | |
|                             // <a href="#"
 | |
|                             //     class="text-decoration-none me-1 btnDelOrder" data-bs-toggle="tooltip"
 | |
|                             //     data-bs-placement="bottom" title="Delete Order"
 | |
|                             //     data-id="${row.ord_id}" data-code="${row.ord_code}">
 | |
|                             //     <span class="icon ion-ios-trash text-danger fz-16"></span>
 | |
|                             // </a>
 | |
|                             // `;
 | |
|                                 let ord_codes = row.ord_code;
 | |
|                                 if (typeof row.childs != 'undefined' && row.childs.length > 0) {
 | |
|                                     for (const child of row.childs) {
 | |
|                                         ord_codes += ',' + child.ord_code;
 | |
|                                     }
 | |
|                                 }
 | |
|                                 action += `
 | |
|                                         <a href="${State.url_view_order}?code=${ord_codes}"
 | |
|                                             class="text-decoration-none me-1" data-bs-toggle="tooltip"
 | |
|                                             data-bs-placement="bottom" title="Lihat">
 | |
|                                             <span class="icon ion-eye text-danger fz-16"></span>
 | |
|                                         </a>
 | |
|                                     `;
 | |
|                                 // action += `
 | |
|                             //         <a href="#"
 | |
|                             //             class="text-decoration-none me-1 btnTrackOrder" data-bs-toggle="tooltip"
 | |
|                             //             data-bs-placement="bottom" title="Tracking #${row.ord_code}"
 | |
|                             //             data-id="${row.ord_id}" data-code="${row.ord_code}">
 | |
|                             //             <span class="icon ion-map text-danger fz-16"></span>
 | |
|                             //         </a>
 | |
|                             //     `;
 | |
|                                 // data-bs-toggle="modal" data-bs-target="#mdlPantau"
 | |
|                                 for (const child of row.childs) {
 | |
|                                     action += `
 | |
|                                         <a href="#"
 | |
|                                             class="text-decoration-none me-1 btnTrackOrder" data-bs-toggle="tooltip"
 | |
|                                             data-bs-placement="bottom" title="Tracking #${child.ord_code}"
 | |
|                                             data-id="${child.ord_id}" data-code="${child.ord_code}">
 | |
|                                             <span class="icon ion-map text-danger fz-16"></span>
 | |
|                                         </a>
 | |
|                                         `;
 | |
|                                 }
 | |
|                                 action += `
 | |
|                                 <a href="#"
 | |
|                                     class="text-decoration-none me-1 btnDelOrder" data-bs-toggle="tooltip"
 | |
|                                     data-bs-placement="bottom" title="Delete Order"
 | |
|                                     data-id="${row.ord_id}" data-code="${row.ord_code}">
 | |
|                                     <span class="icon ion-ios-trash text-danger fz-16"></span>
 | |
|                                 </a>
 | |
|                                 `;
 | |
|                                 return action;
 | |
|                             }
 | |
|                         },
 | |
|                         {
 | |
|                             data: 'code',
 | |
|                             className: 'text-start',
 | |
|                             visible: true,
 | |
|                             orderable: true,
 | |
|                             searchable: true,
 | |
|                             render: function(data, type, row, meta) {
 | |
|                                 let txt = '#' + data;
 | |
|                                 for (const child of row.childs) {
 | |
|                                     txt += '<br>#' + child.code;
 | |
|                                 }
 | |
|                                 return txt;
 | |
|                             },
 | |
|                             createdCell: function(td, cellData, rowData, row, col) {
 | |
|                                 $(td).attr('data-id', rowData.ord_id);
 | |
|                                 $(td).attr('data-code', rowData.ord_code);
 | |
|                             },
 | |
|                         },
 | |
|                         {
 | |
|                             data: 'c_pt_name',
 | |
|                             className: 'text-start',
 | |
|                             visible: true,
 | |
|                             orderable: true,
 | |
|                             searchable: true,
 | |
|                             // createdCell: function(td, cellData, rowData, row, col) {
 | |
|                             //     $(td).attr('data-id', rowData.id);
 | |
|                             //     $(td).attr('data-name', rowData.name);
 | |
|                             //     $(td).attr('data-phone', rowData.phone);
 | |
|                             //     $(td).attr('data-phone_code', rowData.phone_code);
 | |
|                             //     $(td).attr('data-client_group_name', rowData.client_group_name);
 | |
|                             // },
 | |
|                             render: function(data, type, row, meta) {
 | |
|                                 let txt = data;
 | |
|                                 console.log("row:", row);
 | |
|                                 for (const child of row.childs) {
 | |
|                                     txt += '<br>' + child.c_pt_name;
 | |
|                                 }
 | |
|                                 return txt;
 | |
|                             },
 | |
|                         },
 | |
|                         {
 | |
|                             data: 'crt',
 | |
|                             className: 'text-start',
 | |
|                             visible: true,
 | |
|                             orderable: true,
 | |
|                             searchable: true,
 | |
|                             render: function(data, type, row, meta) {
 | |
|                                 let txt = moment.unix(data).format('DD MMM YYYY HH:mm:ss');
 | |
|                                 for (const child of row.childs) {
 | |
|                                     txt += '<br>' + moment.unix(child.crt).format('DD MMM YYYY HH:mm:ss');
 | |
|                                 }
 | |
|                                 return txt;
 | |
|                             },
 | |
|                         },
 | |
|                         // {
 | |
|                         //     data: 'vdr_name',
 | |
|                         //     className: 'text-start',
 | |
|                         //     visible: true,
 | |
|                         //     orderable: true,
 | |
|                         //     searchable: true,
 | |
|                         //     render: function(data, type, row, meta) {
 | |
|                         //         let txt = '';
 | |
|                         //         if (data) {
 | |
|                         //             txt += data;
 | |
|                         //         } else {
 | |
|                         //             txt += `<span class="text-danger">belum ditugaskan</span>`;
 | |
|                         //         }
 | |
|                         //         for (const child of row.childs) {
 | |
|                         //             if (child.vdr_name) {
 | |
|                         //                 txt += '<br>' + child.vdr_name;
 | |
|                         //             } else {
 | |
|                         //                 txt += `<br><span class="text-danger">belum ditugaskan</span>`;
 | |
|                         //             }
 | |
|                         //         }
 | |
|                         //         return txt;
 | |
|                         //     },
 | |
|                         // },
 | |
|                         {
 | |
|                             data: 'vhc_nopol1',
 | |
|                             className: 'text-start',
 | |
|                             visible: true,
 | |
|                             orderable: true,
 | |
|                             searchable: true,
 | |
|                             render: function(data, type, row, meta) {
 | |
|                                 let txt = '';
 | |
|                                 if (row.vhc_nopol1) {
 | |
|                                     txt += row.vhc_nopol1 + ' ' + row.vhc_nopol2 + ' ' + row.vhc_nopol3;
 | |
|                                 } else {
 | |
|                                     txt += `<span class="text-danger">belum ditugaskan</span>`;
 | |
|                                 }
 | |
|                                 for (const child of row.childs) {
 | |
|                                     if (child.vhc_nopol1) {
 | |
|                                         txt += '<br>' + child.vhc_nopol1 + ' ' + child.vhc_nopol2 + ' ' + child.vhc_nopol3;
 | |
|                                     } else {
 | |
|                                         txt += `<br><span class="text-danger">belum ditugaskan</span>`;
 | |
|                                     }
 | |
|                                 }
 | |
|                                 return txt;
 | |
|                             },
 | |
|                         },
 | |
|                         {
 | |
|                             data: 'drv_name',
 | |
|                             className: 'text-start',
 | |
|                             visible: true,
 | |
|                             orderable: true,
 | |
|                             searchable: true,
 | |
|                             render: function(data, type, row, meta) {
 | |
|                                 let txt = '';
 | |
|                                 if (data) {
 | |
|                                     txt += data;
 | |
|                                 } else {
 | |
|                                     txt += `<span class="text-danger">belum ditugaskan</span>`;
 | |
|                                 }
 | |
|                                 for (const child of row.childs) {
 | |
|                                     if (child.drv_name) {
 | |
|                                         txt += '<br>' + child.drv_name;
 | |
|                                     } else {
 | |
|                                         txt += `<br><span class="text-danger">belum ditugaskan</span>`;
 | |
|                                     }
 | |
|                                 }
 | |
|                                 return txt;
 | |
|                             },
 | |
|                         },
 | |
|                         {
 | |
|                             data: 'pck_name',
 | |
|                             className: 'text-start text-nowrap',
 | |
|                             visible: true,
 | |
|                             orderable: true,
 | |
|                             searchable: true,
 | |
|                             render: function(data, type, row, meta) {
 | |
|                                 let txt = data;
 | |
|                                 for (const child of row.childs) {
 | |
|                                     txt += '<br>' + child.pck_name;
 | |
|                                 }
 | |
|                                 return txt;
 | |
|                             },
 | |
|                         },
 | |
|                         {
 | |
|                             data: 'drop_name',
 | |
|                             className: 'text-start text-nowrap',
 | |
|                             visible: true,
 | |
|                             orderable: true,
 | |
|                             searchable: true,
 | |
|                             render: function(data, type, row, meta) {
 | |
|                                 let txt = data;
 | |
|                                 for (const child of row.childs) {
 | |
|                                     txt += '<br>' + child.drop_name;
 | |
|                                 }
 | |
|                                 return txt;
 | |
|                             },
 | |
|                         },
 | |
|                         {
 | |
|                             data: 'status',
 | |
|                             className: 'text-center',
 | |
|                             visible: true,
 | |
|                             orderable: true,
 | |
|                             searchable: true,
 | |
|                             render: function(data, type, row, meta) {
 | |
|                                 // let txt = Wrapper.getHtmlSttsOrd(data, row.stts_pck, row.stts_drop);
 | |
|                                 // for (const child of row.childs) {
 | |
|                                 //     txt += '<br>' + Wrapper.getHtmlSttsOrd(child.status);
 | |
|                                 // }
 | |
|                                 // return txt;
 | |
|                                 let a = ''
 | |
|                                 if (row.status == 10) {
 | |
|                                     a = `<span class="btn btn-sm btn-success">Complete</span>`
 | |
|                                 } else if (row.status == 11) {
 | |
|                                     a = `<span class="btn btn-sm btn-danger">Cancel</span>`
 | |
|                                 } else {
 | |
|                                     a = `<span class="btn btn-sm btn-warning">Active</span>`
 | |
|                                 }
 | |
|                                 return a;
 | |
|                             },
 | |
|                         },
 | |
|                     ],
 | |
|                 });
 | |
|             },
 | |
|         };
 | |
| 
 | |
|         const OrdMerge = {
 | |
|             activate: function() {
 | |
|                 OrdMerge.event();
 | |
|             },
 | |
|             event: function() {
 | |
|                 // select2
 | |
|                 $('#mrg-sel_from_trx_code').select2({
 | |
|                     dropdownParent: $('#mdlMrgItem'),
 | |
|                 });
 | |
|                 $('#mrg-sel_to_trx_code').select2({
 | |
|                     dropdownParent: $('#mdlMrgItem'),
 | |
|                 });
 | |
|                 // input
 | |
|                 $('#mrg-new_buy_price').on('keyup', function() {
 | |
|                     let val = Number($('#mrg-new_buy_price').val().split('.').join(''));
 | |
|                     $('#mrg-new_buy_price').val((new Intl.NumberFormat('id-ID')).format(val));
 | |
|                 });
 | |
|                 // modal
 | |
|                 $('#btnMdlMrgTrx').on('click', function() {
 | |
|                     $('#mdlMrgItem').modal('show');
 | |
|                 });
 | |
|                 // submit
 | |
|                 $('#btnSubmitMergeItem').on('click', function() {
 | |
|                     const data = OrdMerge.getData();
 | |
|                     const isValid = OrdMerge.checkData(data, true);
 | |
|                     if (!isValid) return false;
 | |
|                     OrdMerge.submitData(data);
 | |
|                 });
 | |
|             },
 | |
|             getData: function() {
 | |
|                 const data = {};
 | |
|                 const selFromTrx = $('#mrg-sel_from_trx_code :selected');
 | |
|                 data.mrg_from_ord_id = selFromTrx.data('id');
 | |
|                 data.mrg_from_ord_code = selFromTrx.data('code');
 | |
|                 const selToTrx = $('#mrg-sel_to_trx_code :selected');
 | |
|                 data.mrg_to_ord_id = selToTrx.data('id');
 | |
|                 data.mrg_to_ord_code = selToTrx.data('code');
 | |
|                 data.new_buy_price = Number($('#mrg-new_buy_price').val().split('.').join(''));
 | |
|                 data.note = $('#mrg-note').val();
 | |
|                 return data;
 | |
|             },
 | |
|             checkData: function(data, isAlert = true) {
 | |
|                 if (typeof data.mrg_from_ord_code === 'undefined' || data.mrg_from_ord_code == '') {
 | |
|                     Helper.toast('Warning', 'just now', 'merge dari transaksi belum dipilih');
 | |
|                     return false;
 | |
|                 }
 | |
|                 if (typeof data.mrg_to_ord_code === 'undefined' || data.mrg_to_ord_code == '') {
 | |
|                     Helper.toast('Warning', 'just now', 'merge ke transaksi belum dipilih');
 | |
|                     return false;
 | |
|                 }
 | |
|                 if (isNaN(data.new_buy_price)) {
 | |
|                     Helper.toast('Warning', 'just now', 'Biaya belum diisi');
 | |
|                     return false;
 | |
|                 }
 | |
|                 if (data.new_buy_price < 0) {
 | |
|                     Helper.toast('Warning', 'just now', 'Minimal biaya adalah 0');
 | |
|                     return false;
 | |
|                 }
 | |
|                 return true;
 | |
|             },
 | |
|             submitData: function(data) {
 | |
|                 return new Promise((resolve, reject) => {
 | |
|                     if (typeof $('#btnSubmitMergeItem').attr('disabed') != 'undefined') {
 | |
|                         resolve({
 | |
|                             type: 'fail'
 | |
|                         });
 | |
|                         return false;
 | |
|                     }
 | |
|                     $('#btnSubmitMergeItem-loader').removeClass('d-none');
 | |
|                     $('#btnSubmitMergeItem').attr('disabed', true);
 | |
|                     $('#btnSubmitMergeItem').addClass('d-none');
 | |
|                     $.ajax({
 | |
|                         url: "{{ route('api_finance_merger_trx', '') }}",
 | |
|                         method: 'POST',
 | |
|                         crossDomain: true,
 | |
|                         processData: true,
 | |
|                         headers: {
 | |
|                             'x-api-key': Helper.getCookie('_trtk'),
 | |
|                             'x-csrf-token': $('meta[name="csrf-token"]').attr('content'),
 | |
|                         },
 | |
|                         data: data,
 | |
|                         success: (data, textStatus, jqXHR) => {
 | |
|                             $('#btnSubmitMergeItem').removeAttr('disabed');
 | |
|                             $('#btnSubmitMergeItem-loader').addClass('d-none');
 | |
|                             $('#btnSubmitMergeItem').removeClass('d-none');
 | |
|                             if (data.meta.type != 'success') {
 | |
|                                 resolve({
 | |
|                                     type: 'fail'
 | |
|                                 });
 | |
|                                 Helper.toast('Warning', 'just now', data.meta.message);
 | |
|                                 return false;
 | |
|                             }
 | |
|                             Helper.toast('Success', 'just now', 'sukses merge transaksi');
 | |
|                             OrdMerge.clearInput();
 | |
|                             $('#mdlMrgItem').modal('hide');
 | |
|                             OrdTable.reload();
 | |
|                             resolve({
 | |
|                                 type: 'success'
 | |
|                             });
 | |
|                         },
 | |
|                         error: (jqXHR, textStatus, error) => {
 | |
|                             $('#btnSubmitMergeItem').removeAttr('disabed');
 | |
|                             $('#btnSubmitMergeItem-loader').addClass('d-none');
 | |
|                             $('#btnSubmitMergeItem').removeClass('d-none');
 | |
|                             if (jqXHR.status >= 500) {
 | |
|                                 Helper.toast('Error', 'just now', 'Please try again');
 | |
|                             } else {
 | |
|                                 Helper.toast('Error', 'just now', jqXHR.responseJSON.meta
 | |
|                                     .message);
 | |
|                             }
 | |
|                             resolve({
 | |
|                                 type: 'error'
 | |
|                             });
 | |
|                         }
 | |
|                     })
 | |
|                 })
 | |
|             },
 | |
|             clearInput: function() {
 | |
|                 $('#mrg-sel_from_trx_code').val('').trigger('change');
 | |
|                 $('#mrg-sel_to_trx_code').val('').trigger('change');
 | |
|                 $('#mrg-new_buy_price').val('');
 | |
|                 $('#mrg-note').val('');
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         const OrdTrack = {
 | |
|             tracks: null,
 | |
|             activate: function() {
 | |
|                 OrdTrack.event();
 | |
|             },
 | |
|             event: function() {
 | |
|                 $('#tOrders').on('click', '.btnTrackOrder', function(e) {
 | |
|                     // let id = $(e.target).closest('tr').find('td[data-id]').data('id');
 | |
|                     // let code = $(e.target).closest('tr').find('td[data-code]').data('code');
 | |
|                     let id = $(e.target).closest('a').data('id');
 | |
|                     let code = $(e.target).closest('a').data('code');
 | |
|                     State.inShowOrdId = Number(id);
 | |
|                     State.inShowOrdCode = code;
 | |
|                     OrdTrack.bundleTrackOrder(false);
 | |
|                 });
 | |
|             },
 | |
|             bundleTrackOrder: async function(cache = false) {
 | |
|                 Leaflet.clearLayer('eventRemoveDestination');
 | |
|                 Leaflet.clearLayer('eventRemoveHistory');
 | |
|                 OrdTrack.tracks = await OrdTrack.getTrackOrder(cache);
 | |
|                 OrdTrack.showToModal(OrdTrack.tracks);
 | |
|                 OrdTrack.showHistoryToMap(OrdTrack.tracks);
 | |
|                 OrdTrack.showDestinationToMap(OrdTrack.tracks);
 | |
|             },
 | |
|             getTrackOrder: async function(cache = false) {
 | |
|                 if (cache) {
 | |
|                     if (OrdTrack.tracks == null) {
 | |
|                         return (await OrdTrack.reqTrackOrder()).data;
 | |
|                     } else {
 | |
|                         return OrdTrack.tracks;
 | |
|                     }
 | |
|                 }
 | |
|                 return (await OrdTrack.reqTrackOrder()).data;
 | |
|             },
 | |
|             reqTrackOrder: function(params) {
 | |
|                 return new Promise((resolve, reject) => {
 | |
|                     let url = "{{ route('api_track_order') }}?ord_id=" + State.inShowOrdId;
 | |
|                     $.ajax({
 | |
|                         url,
 | |
|                         method: 'GET',
 | |
|                         crossDomain: true,
 | |
|                         processData: true,
 | |
|                         headers: {
 | |
|                             'x-api-key': Helper.getCookie('_trtk'),
 | |
|                         },
 | |
|                         data: params,
 | |
|                         success: (data, textStatus, jqXHR) => {
 | |
|                             if (data.meta.type != 'success') {
 | |
|                                 resolve({
 | |
|                                     type: 'fail',
 | |
|                                     data: null,
 | |
|                                 });
 | |
|                                 Helper.toast('Warning', 'just now', data.meta.message);
 | |
|                                 return false;
 | |
|                             }
 | |
|                             resolve({
 | |
|                                 type: 'success',
 | |
|                                 data: data.data,
 | |
|                             });
 | |
|                         },
 | |
|                         error: (jqXHR, textStatus, error) => {
 | |
|                             if (jqXHR.status >= 500) {
 | |
|                                 Helper.toast('Error', 'just now', 'Cannot get lists trucks');
 | |
|                             } else {
 | |
|                                 Helper.toast('Error', 'just now', jqXHR.responseJSON.meta
 | |
|                                     .message);
 | |
|                             }
 | |
|                             resolve({
 | |
|                                 type: 'error',
 | |
|                                 data: null,
 | |
|                             });
 | |
|                         }
 | |
|                     })
 | |
|                 });
 | |
|             },
 | |
|             showToModal: function({
 | |
|                 order
 | |
|             }) {
 | |
|                 $('#mdlPantau-code').text(`#${State.inShowOrdCode}`);
 | |
|                 $('#mdlPantau').modal('show');
 | |
|             },
 | |
|             showHistoryToMap: function({
 | |
|                 history
 | |
|             }) {
 | |
|                 let key_length = history.length;
 | |
|                 let polyTruckRoutes = history.map((obj, key) => {
 | |
|                     obj.key_index = key + 1 // key_length - key;
 | |
|                     return {
 | |
|                         lat: obj.latitude,
 | |
|                         lng: obj.longitude,
 | |
|                         options: {
 | |
|                             // polyline
 | |
|                             smoothFactor: 1.0,
 | |
|                             noClip: true,
 | |
|                             bubblingMouseEvents: false,
 | |
|                             // circle
 | |
|                             radius: 2,
 | |
|                         },
 | |
|                         // circle
 | |
|                         label: `<strong>${obj.key_index}</strong><br><strong>${obj.nopol1} ${obj.nopol2} ${obj.nopol3}</strong><br>${obj.state_text}<br><br>${decodeURIComponent(obj.fulladdress)}`,
 | |
|                     }
 | |
|                 });
 | |
| 
 | |
|                 let lastPos = history.at(0);
 | |
|                 let icon_vhc = Icon.vechicleIcon(); // moving
 | |
|                 if (lastPos?.ignition == State.stts_ignition.high) {
 | |
|                     if (lastPos?.lst_speed == 0) {
 | |
|                         icon_vhc = Icon.vhcIdleIcon(); // idling
 | |
|                     } else {
 | |
|                         icon_vhc = Icon.vechicleIcon(); // moving
 | |
|                     }
 | |
|                 } else {
 | |
|                     icon_vhc = Icon.vhcIdleIcon(); // stoped
 | |
|                 }
 | |
| 
 | |
|                 let vhcMarker = null;
 | |
|                 if (lastPos) {
 | |
|                     vhcMarker = Leaflet.addMarkers({
 | |
|                         lat: lastPos.latitude,
 | |
|                         lng: lastPos.longitude,
 | |
|                         label: `<strong>${lastPos.nopol1} ${lastPos.nopol2} ${lastPos.nopol3}</strong><br>${lastPos.state_text}<br><br>${decodeURIComponent(lastPos.fulladdress)}`,
 | |
|                         options: {
 | |
|                             icon: icon_vhc,
 | |
|                             // rotationAngle: 290
 | |
|                         }
 | |
|                     });
 | |
|                 }
 | |
| 
 | |
|                 let polyline = null;
 | |
|                 if (lastPos) {
 | |
|                     polyline = Leaflet.addPolylines(polyTruckRoutes);
 | |
|                     Leaflet.map.fitBounds(polyline.getBounds());
 | |
|                     // let ctrWaypoint = Leaflet.addWaypoints(polyTruckRoutes.slice(0, 100))
 | |
|                 }
 | |
| 
 | |
|                 Leaflet.addCircles(polyTruckRoutes, function(circle) {
 | |
|                     window.addEventListener('eventRemoveHistory', function handler(e) {
 | |
|                         circle.remove();
 | |
|                     });
 | |
|                 });
 | |
| 
 | |
|                 // remove marker, circle, event listener and all about this marker
 | |
|                 State.eventRemoveHistory = new CustomEvent('eventRemoveHistory', {
 | |
|                     polyline,
 | |
|                     vhcMarker,
 | |
|                 });
 | |
|                 window.addEventListener('eventRemoveHistory', function handler(e) {
 | |
|                     if (polyline) polyline.remove();
 | |
|                     if (vhcMarker) vhcMarker.remove();
 | |
|                     e.currentTarget.removeEventListener(e.type,
 | |
|                         handler); // window.removeEventListener('remove', this.handler, true);
 | |
|                     State.eventRemoveHistory = null;
 | |
|                 });
 | |
|             },
 | |
|             showDestinationToMap: function({
 | |
|                 order
 | |
|             }) {
 | |
|                 // wkt format from point mysql
 | |
|                 let pck_center = order.pck_center.slice(6, order.pck_center.length - 1).split(' ');
 | |
|                 let drop_center = order.drop_center.slice(6, order.drop_center.length - 1).split(' ');
 | |
|                 let startMarker = Leaflet.addMarkers({
 | |
|                     lat: pck_center[1],
 | |
|                     lng: pck_center[0],
 | |
|                     label: `<strong>${order.pck_name}</strong><br>${order.pck_pic_name}<br>${order.pck_pic_phone_val}<br><br>${order.pck_addr}`,
 | |
|                     options: {
 | |
|                         icon: Icon.titikAwal(),
 | |
|                         // rotationAngle: 290
 | |
|                     }
 | |
|                 });
 | |
|                 let finishMarker = Leaflet.addMarkers({
 | |
|                     lat: drop_center[1],
 | |
|                     lng: drop_center[0],
 | |
|                     label: `<strong>${order.drop_name}</strong><br>${order.drop_pic_name}<br>${order.drop_pic_phone_val}<br><br>${order.drop_addr}`,
 | |
|                     options: {
 | |
|                         icon: Icon.titikAkhir()
 | |
|                     }
 | |
|                 });
 | |
| 
 | |
|                 // remove marker, circle, event listener and all about this marker
 | |
|                 State.eventRemoveDestination = new CustomEvent('eventRemoveDestination', {
 | |
|                     startMarker,
 | |
|                     finishMarker,
 | |
|                 });
 | |
|                 window.addEventListener('eventRemoveDestination', function handler(e) {
 | |
|                     startMarker.removeEventListener('click');
 | |
|                     startMarker.removeEventListener('moveend');
 | |
|                     startMarker.remove();
 | |
|                     finishMarker.removeEventListener('click');
 | |
|                     finishMarker.removeEventListener('moveend');
 | |
|                     finishMarker.remove();
 | |
|                     e.currentTarget.removeEventListener(e.type,
 | |
|                         handler); // window.removeEventListener('remove', this.handler, true);
 | |
|                     State.eventRemoveDestination = null;
 | |
|                 });
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         const Leaflet = {
 | |
|             map: null,
 | |
|             activate: function() {
 | |
|                 // centering indonesia country => .setView([-1.38116, 117.6168817], 5.4);
 | |
|                 Leaflet.map = L.map('map').setView([-7.1451449, 109.9776078], 8);
 | |
|                 L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
 | |
|                     attribution: 'Map data © <a href="https://www.mapbox.com/feedback/">Mapbox</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
 | |
|                     // maxZoom: 20,
 | |
|                     // minZoom: 4,
 | |
|                     id: 'mapbox/streets-v11',
 | |
|                     tileSize: 512,
 | |
|                     zoomOffset: -1,
 | |
|                     accessToken: 'pk.eyJ1IjoibWV1c2luZmlybWFyeSIsImEiOiJja3lsd2xveDAydGhqMnVxaHJsZ2ZncG8yIn0.f7MJAyawHUdCegw7sWjrww',
 | |
|                 }).addTo(Leaflet.map);
 | |
|                 Leaflet.events();
 | |
|                 L.control.scale({
 | |
|                     position: 'bottomright'
 | |
|                 }).addTo(Leaflet.map);
 | |
|                 L.control.zoom({
 | |
|                     position: 'bottomright'
 | |
|                 }).addTo(Leaflet.map);
 | |
| 
 | |
|                 $('#mdlPantau').on('show.bs.modal', function() {
 | |
|                     setTimeout(function() {
 | |
|                         Leaflet.map.invalidateSize();
 | |
|                     }, 10);
 | |
|                 });
 | |
|             },
 | |
|             events: function() {
 | |
|                 // Leaflet.map.on('click', function(e) {
 | |
|                 //     e.latlng.lat, e.latlng.lng
 | |
|                 // })
 | |
|             },
 | |
|             addMarkers: function(locs = [], cb = null) {
 | |
|                 if (locs.constructor === Array) {
 | |
|                     let markers = [];
 | |
|                     for (let i = 0; i < locs.length; i++) {
 | |
|                         let label = locs[i]?.label || '';
 | |
|                         let marker = new L.marker([locs[i].lat, locs[i].lng], locs[i]?.options);
 | |
|                         let popup = new L.Popup({
 | |
|                             autoClose: false,
 | |
|                             closeOnClick: true,
 | |
|                         }).setContent(locs[i]?.label || '').setLatLng([locs[i].lat, locs[i].lng]);
 | |
|                         // marker.bindPopup(locs[i]?.label || '');
 | |
|                         marker.bindPopup(popup);
 | |
|                         marker.bindTooltip(locs[i]?.label || '');
 | |
|                         markers.push(marker);
 | |
|                         if (cb) cb(marker);
 | |
|                         marker.addTo(Leaflet.map);
 | |
|                     }
 | |
|                     return markers;
 | |
|                 } else if (locs.constructor === Object) {
 | |
|                     let label = locs.label;
 | |
|                     let marker = new L.marker([locs.lat, locs.lng], locs?.options);
 | |
|                     let popup = new L.Popup({
 | |
|                         autoClose: false,
 | |
|                         closeOnClick: true,
 | |
|                     }).setContent(locs?.label || '').setLatLng([locs.lat, locs.lng]);
 | |
|                     // marker.bindPopup(locs?.label || '');
 | |
|                     marker.bindPopup(popup);
 | |
|                     marker.bindTooltip(locs?.label || '');
 | |
|                     if (cb) cb(marker);
 | |
|                     marker.addTo(Leaflet.map);
 | |
|                     return marker;
 | |
|                 }
 | |
|             },
 | |
|             addCircles: function(locs = [], cb = null) {
 | |
|                 if (locs.constructor === Array) {
 | |
|                     let circles = [];
 | |
|                     for (let i = 0; i < locs.length; i++) {
 | |
|                         let circle = L.circle([locs[i].lat, locs[i].lng], locs[i]?.options);
 | |
|                         circle.bindPopup(locs[i]?.label || '');
 | |
|                         circle.bindTooltip(locs[i]?.label || '');
 | |
|                         circles.push(circle);
 | |
|                         if (cb) cb(circle);
 | |
|                         circle.addTo(Leaflet.map);
 | |
|                     }
 | |
|                     return circles;
 | |
|                 } else if (locs.constructor === Object) {
 | |
|                     let circle = L.circle([locs.lat, locs.lng], locs?.options);
 | |
|                     circle.bindPopup(locs?.label || '');
 | |
|                     circle.bindTooltip(locs?.label || '');
 | |
|                     if (cb) cb(circle);
 | |
|                     circle.addTo(Leaflet.map);
 | |
|                     return circle;
 | |
|                 }
 | |
|             },
 | |
|             addPolylines: function(locs = [], cb = null) {
 | |
|                 let latLngs = [];
 | |
|                 for (let i = 0; i < locs.length; i++) {
 | |
|                     latLngs.push([locs[i].lat, locs[i].lng]);
 | |
|                 }
 | |
|                 let polyline = L.polyline(latLngs, locs[0]?.options).addTo(Leaflet.map);
 | |
| 
 | |
|                 if (cb) cb(polyline);
 | |
|                 return polyline;
 | |
|             },
 | |
|             // start custom polylines
 | |
|             addCustomPolylines: function(locs = [], cb = null) {
 | |
|                 const radius = 0.5 /* corner smooth radius, keep value in range 0 - 0.5 to avoid artifacts */
 | |
|                 let latLngs = [];
 | |
| 
 | |
|                 for (let i = 0; i < locs.length; i++) {
 | |
|                     latLngs.push([locs[i].lat, locs[i].lng]);
 | |
|                 }
 | |
| 
 | |
|                 let SmoothPoly = L.Polyline.extend({
 | |
|                     // override default method to use custom points-to-path method
 | |
|                     _updatePath: function() {
 | |
|                         let path = Leaflet.roundPathCorners(this._parts, radius)
 | |
|                         this._renderer._setPath(this, path);
 | |
|                     }
 | |
|                 })
 | |
| 
 | |
|                 let polyline = new SmoothPoly(latLngs, locs[0]?.options).addTo(Leaflet.map);
 | |
| 
 | |
|                 if (cb) cb(polyline);
 | |
|                 return polyline;
 | |
|             },
 | |
|             roundPathCorners: function(rings, radius) {
 | |
|                 function moveTowardsFractional(movingPoint, targetPoint, fraction) {
 | |
|                     return {
 | |
|                         x: movingPoint.x + (targetPoint.x - movingPoint.x) * fraction,
 | |
|                         y: movingPoint.y + (targetPoint.y - movingPoint.y) * fraction
 | |
|                     };
 | |
|                 }
 | |
| 
 | |
|                 function pointForCommand(cmd) {
 | |
|                     return {
 | |
|                         x: parseFloat(cmd[cmd.length - 2]),
 | |
|                         y: parseFloat(cmd[cmd.length - 1])
 | |
|                     };
 | |
|                 }
 | |
|                 let resultCommands = [];
 | |
|                 if (+radius) {
 | |
|                     // negative numbers create artifacts
 | |
|                     radius = Math.abs(radius);
 | |
|                 } else {
 | |
|                     radius = 0.15;
 | |
|                 }
 | |
|                 for (let i = 0, len = rings.length; i < len; i++) {
 | |
|                     let commands = rings[i];
 | |
|                     // start point
 | |
|                     resultCommands.push(["M", commands[0].x, commands[0].y]);
 | |
|                     for (let cmdIndex = 1; cmdIndex < commands.length; cmdIndex++) {
 | |
|                         let prevCmd = resultCommands[resultCommands.length - 1];
 | |
|                         let curCmd = commands[cmdIndex];
 | |
|                         let nextCmd = commands[cmdIndex + 1];
 | |
|                         if (nextCmd && prevCmd) {
 | |
|                             // Calc the points we're dealing with
 | |
|                             let prevPoint = pointForCommand(prevCmd); // convert to Object
 | |
|                             let curPoint = curCmd;
 | |
|                             let nextPoint = nextCmd;
 | |
|                             // The start and end of the cuve are just our point moved towards the previous and next points, respectivly
 | |
|                             let curveStart, curveEnd;
 | |
|                             curveStart = moveTowardsFractional(
 | |
|                                 curPoint,
 | |
|                                 prevCmd.origPoint || prevPoint,
 | |
|                                 radius
 | |
|                             );
 | |
|                             curveEnd = moveTowardsFractional(
 | |
|                                 curPoint,
 | |
|                                 nextCmd.origPoint || nextPoint,
 | |
|                                 radius
 | |
|                             );
 | |
|                             // Adjust the current command and add it
 | |
|                             curCmd = Object.values(curveStart);
 | |
|                             curCmd.origPoint = curPoint;
 | |
|                             curCmd.unshift("L");
 | |
|                             resultCommands.push(curCmd);
 | |
|                             // The curve control points are halfway between the start/end of the curve and
 | |
|                             // calculate curve, if radius is different than 0
 | |
|                             if (radius) {
 | |
|                                 let startControl = moveTowardsFractional(curveStart, curPoint, 0.5);
 | |
|                                 let endControl = moveTowardsFractional(curPoint, curveEnd, 0.5);
 | |
|                                 // Create the curve
 | |
|                                 let curveCmd = [
 | |
|                                     "C",
 | |
|                                     startControl.x,
 | |
|                                     startControl.y,
 | |
|                                     endControl.x,
 | |
|                                     endControl.y,
 | |
|                                     curveEnd.x,
 | |
|                                     curveEnd.y
 | |
|                                 ];
 | |
|                                 // Save the original point for fractional calculations
 | |
|                                 curveCmd.origPoint = curPoint;
 | |
|                                 resultCommands.push(curveCmd);
 | |
|                             }
 | |
|                         } else {
 | |
|                             // Pass through commands that don't qualify
 | |
|                             let el = Object.values(curCmd);
 | |
|                             el.unshift("L");
 | |
|                             resultCommands.push(el);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 return (
 | |
|                     resultCommands.reduce(function(str, c) {
 | |
|                         return str + c.join(" ") + " ";
 | |
|                     }, "") || "M0 0"
 | |
|                 );
 | |
|             },
 | |
|             // end custom polylines
 | |
|             addPolygons: function(locs = [], cb = null) {
 | |
|                 let latLngs = [];
 | |
|                 for (let i = 0; i < locs.length; i++) {
 | |
|                     latLngs.push([locs[i].lat, locs[i].lng]);
 | |
|                 }
 | |
|                 let polygon = L.polygon(latLngs, locs[0]?.options).addTo(Leaflet.map);
 | |
|                 polygon.bindPopup(locs[0]?.label || '');
 | |
|                 polygon.bindTooltip(locs[0]?.label || '');
 | |
| 
 | |
|                 if (cb) cb(polygon);
 | |
|                 return polygon;
 | |
|             },
 | |
|             addWaypoints: function(locs = [], cb = null) {
 | |
|                 let latLngs = [];
 | |
|                 for (let i = 0; i < locs.length; i++) {
 | |
|                     latLngs.push(L.latLng(locs[i].lat, locs[i].lng));
 | |
|                 }
 | |
|                 let control = L.Routing.control({
 | |
|                     waypoints: latLngs,
 | |
|                     show: false,
 | |
|                     waypointMode: 'snap',
 | |
|                     createMarker: function() {}
 | |
|                 }).addTo(Leaflet.map);
 | |
|                 if (cb) cb(control);
 | |
|                 return control;
 | |
|             },
 | |
|             drawPolygon: function(lat, lng, options = {}) {
 | |
|                 let polygon = L.polygon([
 | |
|                     [lat, lng]
 | |
|                 ], options).addTo(Leaflet.map);
 | |
|                 return polygon;
 | |
|             },
 | |
|             eventMarkerClick: function(marker, cb = null) {
 | |
|                 marker.on('click', function(e) {
 | |
|                     // console.log(e.target.options); // get passing data from set marker: https://stackoverflow.com/questions/17423261/how-to-pass-data-with-marker-in-leaflet-js
 | |
|                     Leaflet.map.invalidateSize();
 | |
|                     if (Leaflet.map.getZoom() <= 14) {
 | |
|                         Leaflet.map.setView(e.target.getLatLng(), 14);
 | |
|                     }
 | |
|                     if (cb) cb(e);
 | |
|                 });
 | |
|             },
 | |
|             clearLayer: function(type = 'all', cb = null) {
 | |
|                 if (type == 'all') {
 | |
|                     if (State.eventRemoveDestination) window.dispatchEvent(State.eventRemoveDestination);
 | |
|                     if (State.eventRemoveHistory) window.dispatchEvent(State.eventRemoveHistory);
 | |
|                     if (cb) cb();
 | |
|                 } else if (type == 'eventRemoveDestination') {
 | |
|                     if (State.eventRemoveDestination) {
 | |
|                         window.dispatchEvent(State.eventRemoveDestination);
 | |
|                         if (cb) cb();
 | |
|                     }
 | |
|                 } else if (type == 'eventRemoveHistory') {
 | |
|                     if (State.eventRemoveHistory) {
 | |
|                         window.dispatchEvent(State.eventRemoveHistory);
 | |
|                         if (cb) cb();
 | |
|                     }
 | |
|                 }
 | |
|             },
 | |
|             hideLayer: function(type = 'all', cb = null) {
 | |
|                 if (type == 'all') {
 | |
|                     if (State.eventHideDestination) window.dispatchEvent(State.eventHideDestination);
 | |
|                     if (cb) cb();
 | |
|                 } else if (type == 'eventHideDestination') {
 | |
|                     if (State.eventHideDestination) {
 | |
|                         if (State.eventHideDestination) {
 | |
|                             window.dispatchEvent(State.eventHideDestination);
 | |
|                             if (cb) cb();
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             },
 | |
|         };
 | |
| 
 | |
|         const Filter = {
 | |
|             activate: function() {
 | |
|                 Filter.event();
 | |
|             },
 | |
|             event: function() {},
 | |
|             triggerFilterCompany: function() {
 | |
|                 OrdTable.reload();
 | |
|             },
 | |
|         }
 | |
| 
 | |
|         const OrdDelete = {
 | |
|             activate: function() {
 | |
|                 OrdDelete.event();
 | |
|             },
 | |
|             event: function() {
 | |
|                 $('#tOrders').on('click', '.btnDelOrder', function(e) {
 | |
|                     // let id = $(e.target).closest('tr').find('td[data-id]').data('id');
 | |
|                     // let code = $(e.target).closest('tr').find('td[data-code]').data('code');
 | |
|                     let id = $(e.target).closest('a').data('id');
 | |
|                     let code = $(e.target).closest('a').data('code');
 | |
| 
 | |
|                     $('#del-ord_code').text(code);
 | |
| 
 | |
|                     $('#mdlDelOrder').data('id', Number(id));
 | |
|                     $('#mdlDelOrder').data('code', code);
 | |
|                     $('#mdlDelOrder').modal('show');
 | |
|                 });
 | |
| 
 | |
|                 $('#btnSubmitDelOrder').on('click', function(e) {
 | |
|                     const id = Number($('#mdlDelOrder').data('id'));
 | |
|                     const code = Number($('#mdlDelOrder').data('code'));
 | |
|                     OrdDelete.submitDelOrder({
 | |
|                         ord_id: id,
 | |
|                         ord_code: code
 | |
|                     });
 | |
|                 });
 | |
|             },
 | |
|             submitDelOrder: function(data) {
 | |
|                 return new Promise((resolve, reject) => {
 | |
|                     if (typeof $('#btnSubmitDelOrder').attr('disabed') != 'undefined') {
 | |
|                         resolve({
 | |
|                             type: 'fail'
 | |
|                         });
 | |
|                         return false;
 | |
|                     }
 | |
|                     $('#btnSubmitDelOrder').attr('disabed', true);
 | |
|                     $.ajax({
 | |
|                         url: "{{ route('api_delete_order', '') }}/" + data.ord_id,
 | |
|                         method: 'DELETE',
 | |
|                         crossDomain: true,
 | |
|                         processData: true,
 | |
|                         headers: {
 | |
|                             'x-csrf-token': $('meta[name="csrf-token"]').attr('content'),
 | |
|                             'x-api-key': Helper.getCookie('_trtk'),
 | |
|                         },
 | |
|                         data: data,
 | |
|                         success: (data, textStatus, jqXHR) => {
 | |
|                             $('#btnSubmitDelOrder').removeAttr('disabed');
 | |
|                             if (data.meta.type != 'success') {
 | |
|                                 resolve({
 | |
|                                     type: 'fail'
 | |
|                                 });
 | |
|                                 Helper.toast('Warning', 'just now', data.meta.message);
 | |
|                                 return false;
 | |
|                             }
 | |
|                             Helper.toast('Success', 'just now', 'success delete order');
 | |
|                             $('#mdlDelOrder').modal('hide');
 | |
|                             $('#mdlDelOrder').data('id', undefined);
 | |
|                             $('#mdlDelOrder').data('code', undefined);
 | |
|                             OrdTable.reload();
 | |
|                             resolve({
 | |
|                                 type: 'success'
 | |
|                             });
 | |
|                         },
 | |
|                         error: (jqXHR, textStatus, error) => {
 | |
|                             $('#btnSubmitDelOrder').removeAttr('disabed');
 | |
|                             if (jqXHR.status >= 500) {
 | |
|                                 Helper.toast('Error', 'just now', 'please try again');
 | |
|                             } else {
 | |
|                                 Helper.toast('Error', 'just now', jqXHR.responseJSON.meta
 | |
|                                     .message);
 | |
|                             }
 | |
|                             resolve({
 | |
|                                 type: 'error'
 | |
|                             });
 | |
|                         }
 | |
|                     })
 | |
|                 })
 | |
|             },
 | |
|         }
 | |
| 
 | |
|         Wrapper.activate();
 | |
|     </script>
 | |
|     {{-- <script>
 | |
|         var map = L.map('map').setView([-7.1451449, 109.9776078], 8);
 | |
|         L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
 | |
|             attribution: 'Map data © <a href="https://www.mapbox.com/feedback/">Mapbox</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
 | |
|             id: 'mapbox/streets-v11',
 | |
|             tileSize: 512,
 | |
|             zoomOffset: -1,
 | |
|             accessToken: 'pk.eyJ1IjoibWV1c2luZmlybWFyeSIsImEiOiJja3lsd2xveDAydGhqMnVxaHJsZ2ZncG8yIn0.f7MJAyawHUdCegw7sWjrww',
 | |
|         }).addTo(map);
 | |
|         L.control.scale({
 | |
|             position: 'bottomright'
 | |
|         }).addTo(map);
 | |
|         L.control.zoom({
 | |
|             position: 'bottomright'
 | |
|         }).addTo(map);
 | |
| 
 | |
|         $('#mdlPantau').on('show.bs.modal', function(){
 | |
|             setTimeout(function() {
 | |
|                 map.invalidateSize();
 | |
|             }, 10);
 | |
|         });
 | |
|     </script> --}}
 | |
| @endsection
 | 
