Files
gps-frontend/resources/views/menu_v1/transactions.blade.php
meusinfirmary 470e132ff5 update
2025-05-29 17:52:19 +07:00

1426 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> --}}
<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>
</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">Tutup</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">Tutup</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>
<button id="btnSubmitDelOrder" type="button" class="btn btn-sm btn-secondary">Yes, delete</button>
</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 &copy; <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 &copy; <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