inventory_mobile/pstw_centralizesystem/Areas/ItemMovementUser.txt
2025-12-15 15:35:35 +08:00

1986 lines
111 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- Tell the browser to be responsive to screen width -->
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="keywords"
content="wrappixel, admin dashboard, html css dashboard, web dashboard, bootstrap 5 admin, bootstrap 5, css3 dashboard, bootstrap 5 dashboard, Matrix lite admin bootstrap 5 dashboard, frontend, responsive bootstrap 5 admin template, Matrix admin lite design, Matrix admin lite dashboard bootstrap 5 dashboard template" />
<meta name="description"
content="Matrix Admin Lite Free Version is powerful and clean admin dashboard template, inpired from Bootstrap Framework" />
<meta name="robots" content="noindex,nofollow" />
<title>PSTW Centralize Web System</title>
<!-- Favicon icon -->
<link rel="icon"
type="image/png"
sizes="16x16"
href="/assets/images/favicon.png" />
<!-- Custom CSS -->
<link rel="stylesheet" href="/assets/libs/select2/dist/css/select2.min.css" />
<link rel="stylesheet" href="/assets/libs/jquery-minicolors/jquery.minicolors.css" />
<link rel="stylesheet" href="/assets/libs/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css" />
<link rel="stylesheet" href="/assets/libs/quill/dist/quill.snow.css" />
<link href="/dist/css/style.min.css" rel="stylesheet" />
<link href="/lib/printjs/print.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<!-- DataTables CSS-->
<link href="/lib/datatables/datatables.css" rel="stylesheet" />
<!-- Vue Js -->
<script src="/js/vue.global.js"></script>
<!-- QR Js -->
<script src="/lib/qrcode/qrcode.min.js"></script>
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<style>
.btn-teal {
background-color: #20c997; /* Teal color */
color: #ffffff; /* White text */
border: none; /* Remove border */
}
.btn-teal:hover {
background-color: #17a589; /* Darker teal on hover */
color: #ffffff;
}
.btn-teal:focus,
.btn-teal.focus {
box-shadow: 0 0 0 0.2rem rgba(32, 201, 151, 0.5); /* Teal shadow on focus */
}
</style>
<!-- ============================================================== -->
<!-- Preloader - style you can find in spinners.css -->
<!-- ============================================================== -->
<div b-lhtx71ohus id="preloader" class="preloader">
<div b-lhtx71ohus class="lds-ripple">
<div b-lhtx71ohus class="lds-pos"></div>
<div b-lhtx71ohus class="lds-pos"></div>
</div>
</div>
<div b-lhtx71ohus class="modal fade" id="loadingModal" data-bs-backdrop="static" tabindex="-1" aria-hidden="true" style="z-index: 1051;">
<div b-lhtx71ohus class="modal-dialog modal-dialog-centered">
<div b-lhtx71ohus class="modal-content">
<div b-lhtx71ohus class="modal-header">
<button b-lhtx71ohus type="button" class="closeModal" data-dismiss="modal" aria-label="Close">
<span b-lhtx71ohus aria-hidden="true">&times;</span>
</button>
</div>
<div b-lhtx71ohus class="modal-body text-center">
<div b-lhtx71ohus class="spinner-border text-primary" role="status">
<span b-lhtx71ohus class="visually-hidden">Loading...</span>
</div>
<p b-lhtx71ohus class="mt-3">Please wait while we process your request...</p>
</div>
</div>
</div>
</div>
<!-- ============================================================== -->
<!-- Main wrapper - style you can find in pages.scss -->
<!-- ============================================================== -->
<div b-lhtx71ohus id="main-wrapper"
data-layout="vertical"
data-navbarbg="skin5"
data-sidebartype="full"
data-sidebar-position="absolute"
data-header-position="absolute"
data-boxed-layout="full">
<!-- ============================================================== -->
<!-- Topbar header - style you can find in pages.scss -->
<!-- ============================================================== -->
<header b-lhtx71ohus class="topbar" data-navbarbg="skin5">
<nav b-lhtx71ohus class="navbar top-navbar navbar-expand-md navbar-dark">
<div b-lhtx71ohus class="navbar-header" data-logobg="skin5">
<!-- ============================================================== -->
<!-- Logo -->
<!-- ============================================================== -->
<a class="navbar-brand" href="/">
<!-- Logo icon -->
<b b-lhtx71ohus class="logo-icon ps-2">
<!--You can put here icon as well // <i class="wi wi-sunset"></i> //-->
<!-- Dark Logo icon -->
<img b-lhtx71ohus src="/assets/images/logo-icon.png"
alt="homepage"
class="light-logo"
width="25" />
</b>
<!--End Logo icon -->
<!-- Logo text -->
<span b-lhtx71ohus class="logo-text ms-2">
<!-- dark Logo text -->
<img b-lhtx71ohus src="/assets/images/logo-text.png"
alt="homepage"
class="light-logo" />
</span>
<!-- Logo icon -->
<!-- <b class="logo-icon"> -->
<!--You can put here icon as well // <i class="wi wi-sunset"></i> //-->
<!-- Dark Logo icon -->
<!-- <img src="/assets/images/logo-text.png" alt="homepage" class="light-logo" /> -->
<!-- </b> -->
<!--End Logo icon -->
</a>
<!-- ============================================================== -->
<!-- End Logo -->
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- Toggle which is visible on mobile only -->
<!-- ============================================================== -->
<a b-lhtx71ohus class="nav-toggler waves-effect waves-light d-block d-md-none"
href="javascript:void(0)">
<i b-lhtx71ohus class="ti-menu ti-close"></i>
</a>
</div>
<!-- ============================================================== -->
<!-- End Logo -->
<!-- ============================================================== -->
<div b-lhtx71ohus class="navbar-collapse collapse"
id="navbarSupportedContent"
data-navbarbg="skin5">
<!-- ============================================================== -->
<!-- toggle and nav items -->
<!-- ============================================================== -->
<ul b-lhtx71ohus class="navbar-nav float-start me-auto">
<li b-lhtx71ohus class="nav-item d-none d-lg-block">
<a b-lhtx71ohus class="nav-link sidebartoggler waves-effect waves-light"
href="javascript:void(0)"
data-sidebartype="mini-sidebar">
<i b-lhtx71ohus class="mdi mdi-menu font-24"></i>
</a>
</li>
<li b-lhtx71ohus class="nav-item">
<a class="nav-link" href="/">Home</a>
</li>
<li b-lhtx71ohus class="nav-item">
<a class="nav-link" href="/Home/Privacy">Privacy</a>
</li>
<!-- ============================================================== -->
<!-- create new -->
<!-- ============================================================== -->
<!--<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle"
href="#"
id="navbarDropdown"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false">
<span class="d-none d-md-block">
Create New <i class="fa fa-angle-down"></i>
</span>
<span class="d-block d-md-none">
<i class="fa fa-plus"></i>
</span>
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><hr class="dropdown-divider" /></li>
<li>
<a class="dropdown-item" href="#">Something else here</a>
</li>
</ul>
</li> b-lhtx71ohus-->
<!-- ============================================================== -->
<!-- Search -->
<!-- ============================================================== -->
<!--<li class="nav-item search-box">
<a class="nav-link waves-effect waves-dark"
href="javascript:void(0)">
<i class="mdi mdi-magnify fs-4"></i>
</a>
<form class="app-search position-absolute">
<input type="text"
class="form-control"
placeholder="Search &amp; enter" />
<a class="srh-btn"><i class="mdi mdi-window-close"></i></a>
</form>
</li> b-lhtx71ohus-->
</ul>
<!-- ============================================================== -->
<!-- Right side toggle and nav items -->
<!-- ============================================================== -->
<ul b-lhtx71ohus class="navbar-nav float-end">
<!-- ============================================================== -->
<!-- Comment -->
<!-- ============================================================== -->
<li class="nav-item d-inline">
<a id="manage" class="nav-link" title="Manage" href="/Identity/Account/Manage">
Hello core3user@pstw.com.my!
</a>
</li>
<li class="nav-item d-inline">
<a id="logout" class="nav-link" href="javascript:void(0);" onclick="logout()">Logout</a>
</li>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8N0yQF8b8n9Ln4B-pzXVXnL7GEVxhtAQkDaVXT-HBuB49DEXc1BidBbyfMnCrGmGcQmGkusNH0CYkpgxscTTD8DoFRhNd6OadPAm9n-r29QVrWbOmi545Qh5bB4YFvZUkZ_XK33HIz_RNh80qENM181voQY8VXpaFjeHPSWzhRwGpBThuu2aVYStjg2GJcZEXw" /> <script>
function logout() {
const returnUrl = '/';
fetch('/Identity/Account/Logout', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `__RequestVerificationToken=${document.querySelector('input[name="__RequestVerificationToken"]').value}&returnUrl=${encodeURIComponent(returnUrl)}`
}).then(response => {
if (response.ok) {
window.location.href = returnUrl;
} else {
alert('Logout failed.');
}
}).catch(error => {
console.error('Logout error:', error);
});
}
</script>
<!-- ============================================================== -->
<!-- End Comment -->
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- Messages -->
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- End Messages -->
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- User profile and search -->
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- User profile and search -->
<!-- ============================================================== -->
</ul>
</div>
</nav>
</header>
<!-- ============================================================== -->
<!-- End Topbar header -->
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- Left Sidebar - style you can find in sidebar.scss -->
<!-- ============================================================== -->
<aside b-lhtx71ohus class="left-sidebar" data-sidebarbg="skin5">
<!-- Sidebar scroll-->
<div b-lhtx71ohus class="scroll-sidebar">
<!-- Sidebar navigation-->
<nav b-lhtx71ohus class="sidebar-nav">
<ul b-lhtx71ohus id="sidebarnav" class="pt-4">
<li b-lhtx71ohus class="sidebar-item">
<a b-lhtx71ohus class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)"
aria-expanded="false">
<i b-lhtx71ohus class="mdi mdi-receipt"></i><span b-lhtx71ohus class="hide-menu">Administrator </span>
</a>
<ul b-lhtx71ohus aria-expanded="false" class="collapse first-level">
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/Admin">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Admin Dashboard</span>
</a>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/Admin/ModuleAdmin">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Module Administration</span>
</a>
</li>
</ul>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a b-lhtx71ohus class="sidebar-link waves-effect waves-dark sidebar-link"
href="#"
aria-expanded="false">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Dashboard</span>
</a>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a b-lhtx71ohus class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)"
aria-expanded="false">
<i b-lhtx71ohus class="mdi mdi-receipt"></i><span b-lhtx71ohus class="hide-menu">Inventory </span>
</a>
<ul b-lhtx71ohus aria-expanded="false" class="collapse first-level">
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/Inventory/ItemMovement/UserDashboard">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">User Dashboard</span>
</a>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/Inventory/InventoryMaster/ProductRegistration">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Product Registration</span>
</a>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/Inventory/InventoryMaster/ItemRegistration">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Item Registration</span>
</a>
</li>
</ul>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a b-lhtx71ohus class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)"
aria-expanded="false">
<i b-lhtx71ohus class="mdi mdi-receipt"></i><span b-lhtx71ohus class="hide-menu">Report</span>
</a>
<ul b-lhtx71ohus aria-expanded="false" class="collapse first-level">
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/Report/Reporting">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Admin Dashboard</span>
</a>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/Report/Reporting/InventoryReport">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Inventory Report</span>
</a>
</li>
<!--MMS-->
<li b-lhtx71ohus class="sidebar-item">
<a b-lhtx71ohus class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)" aria-expanded="false">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">MMS</span>
</a>
<ul b-lhtx71ohus aria-expanded="false" class="collapse first-level">
<!-- Marine subsection -->
<li b-lhtx71ohus class="sidebar-item">
<a b-lhtx71ohus class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)" aria-expanded="false">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Marine</span>
</a>
<ul b-lhtx71ohus aria-expanded="false" class="collapse second-level">
<!-- Tar Ball Sampling Form link -->
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark" aria-expanded="false" href="/MMS/Marine/TarBallForm">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Tarball Report</span>
</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a b-lhtx71ohus class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)"
aria-expanded="false">
<i b-lhtx71ohus class="mdi mdi-receipt"></i><span b-lhtx71ohus class="hide-menu">User Overtime</span>
</a>
<ul b-lhtx71ohus aria-expanded="false" class="collapse first-level">
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/OTcalculate/Overtime/OtRegister">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">OT Register</span>
</a>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/OTcalculate/Overtime/OtRecords">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">OT Records</span>
</a>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/OTcalculate/Overtime/OtStatus">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">OT Status</span>
</a>
</li>
</ul>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a b-lhtx71ohus class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)"
aria-expanded="false">
<i b-lhtx71ohus class="mdi mdi-receipt"></i><span b-lhtx71ohus class="hide-menu">Overtime Approval</span>
</a>
<ul b-lhtx71ohus aria-expanded="false" class="collapse first-level">
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/OTcalculate/ApprovalDashboard/Approval">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Pending Approval</span>
</a>
</li>
</ul>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a b-lhtx71ohus class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)"
aria-expanded="false">
<i b-lhtx71ohus class="mdi mdi-receipt"></i><span b-lhtx71ohus class="hide-menu">HR Dashboard</span>
</a>
<ul b-lhtx71ohus aria-expanded="false" class="collapse first-level">
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/OTcalculate/HrDashboard/Settings">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Settings</span>
</a>
</li>
</ul>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a b-lhtx71ohus class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)"
aria-expanded="false">
<i b-lhtx71ohus class="mdi mdi-receipt"></i><span b-lhtx71ohus class="hide-menu">Rooms Booking</span>
</a>
<ul b-lhtx71ohus aria-expanded="false" class="collapse first-level">
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/Bookings/Bookings/Managers">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Assign</span>
</a>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/Bookings/Bookings">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">List</span>
</a>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/Bookings/Bookings/Calendar">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Calendar</span>
</a>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/Bookings/Bookings/Room">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Rooms</span>
</a>
</li>
</ul>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a b-lhtx71ohus class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)"
aria-expanded="false">
<i b-lhtx71ohus class="mdi mdi-receipt"></i><span b-lhtx71ohus class="hide-menu">IT Request Form</span>
</a>
<ul b-lhtx71ohus aria-expanded="false" class="collapse first-level">
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/IT/ApprovalDashboard/Admin">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Assignings</span>
</a>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/IT/ApprovalDashboard/Create">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Registeration</span>
</a>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/IT/ApprovalDashboard/MyRequests">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">My Requests</span>
</a>
</li>
<li b-lhtx71ohus class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" aria-expanded="false" href="/IT/ApprovalDashboard/Approval">
<i b-lhtx71ohus class="mdi mdi-view-dashboard"></i><span b-lhtx71ohus class="hide-menu">Approval</span>
</a>
</li>
</ul>
</li>
<!-- <li class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link"
href="charts.html"
aria-expanded="false">
<i class="mdi mdi-chart-bar"></i><span class="hide-menu">Charts</span>
</a>
</li>
<li class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link"
href="widgets.html"
aria-expanded="false">
<i class="mdi mdi-chart-bubble"></i><span class="hide-menu">Widgets</span>
</a>
</li>
<li class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link"
href="tables.html"
aria-expanded="false">
<i class="mdi mdi-border-inside"></i><span class="hide-menu">Tables</span>
</a>
</li>
<li class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link"
href="grid.html"
aria-expanded="false">
<i class="mdi mdi-blur-linear"></i><span class="hide-menu">Full Width</span>
</a>
</li>
<li class="sidebar-item">
<a class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)"
aria-expanded="false">
<i class="mdi mdi-receipt"></i><span class="hide-menu">Forms </span>
</a>
<ul aria-expanded="false" class="collapse first-level">
<li class="sidebar-item">
<a href="form-basic.html" class="sidebar-link">
<i class="mdi mdi-note-outline"></i><span class="hide-menu"> Form Basic </span>
</a>
</li>
<li class="sidebar-item">
<a href="form-wizard.html" class="sidebar-link">
<i class="mdi mdi-note-plus"></i><span class="hide-menu"> Form Wizard </span>
</a>
</li>
</ul>
</li>
<li class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link"
href="pages-buttons.html"
aria-expanded="false">
<i class="mdi mdi-relative-scale"></i><span class="hide-menu">Buttons</span>
</a>
</li>
<li class="sidebar-item">
<a class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)"
aria-expanded="false">
<i class="mdi mdi-face"></i><span class="hide-menu">Icons </span>
</a>
<ul aria-expanded="false" class="collapse first-level">
<li class="sidebar-item">
<a href="icon-material.html" class="sidebar-link">
<i class="mdi mdi-emoticon"></i><span class="hide-menu"> Material Icons </span>
</a>
</li>
<li class="sidebar-item">
<a href="icon-fontawesome.html" class="sidebar-link">
<i class="mdi mdi-emoticon-cool"></i><span class="hide-menu"> Font Awesome Icons </span>
</a>
</li>
</ul>
</li>
<li class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link"
href="pages-elements.html"
aria-expanded="false">
<i class="mdi mdi-pencil"></i><span class="hide-menu">Elements</span>
</a>
</li>
<li class="sidebar-item">
<a class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)"
aria-expanded="false">
<i class="mdi mdi-move-resize-variant"></i><span class="hide-menu">Addons </span>
</a>
<ul aria-expanded="false" class="collapse first-level">
<li class="sidebar-item">
<a href="index2.html" class="sidebar-link">
<i class="mdi mdi-view-dashboard"></i><span class="hide-menu"> Dashboard-2 </span>
</a>
</li>
<li class="sidebar-item">
<a href="pages-gallery.html" class="sidebar-link">
<i class="mdi mdi-multiplication-box"></i><span class="hide-menu"> Gallery </span>
</a>
</li>
<li class="sidebar-item">
<a href="pages-calendar.html" class="sidebar-link">
<i class="mdi mdi-calendar-check"></i><span class="hide-menu"> Calendar </span>
</a>
</li>
<li class="sidebar-item">
<a href="pages-invoice.html" class="sidebar-link">
<i class="mdi mdi-bulletin-board"></i><span class="hide-menu"> Invoice </span>
</a>
</li>
<li class="sidebar-item">
<a href="pages-chat.html" class="sidebar-link">
<i class="mdi mdi-message-outline"></i><span class="hide-menu"> Chat Option </span>
</a>
</li>
</ul>
</li>
<li class="sidebar-item">
<a class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)"
aria-expanded="false">
<i class="mdi mdi-account-key"></i><span class="hide-menu">Authentication </span>
</a>
<ul aria-expanded="false" class="collapse first-level">
<li class="sidebar-item">
<a href="authentication-login.html" class="sidebar-link">
<i class="mdi mdi-all-inclusive"></i><span class="hide-menu"> Login </span>
</a>
</li>
<li class="sidebar-item">
<a href="authentication-register.html" class="sidebar-link">
<i class="mdi mdi-all-inclusive"></i><span class="hide-menu"> Register </span>
</a>
</li>
</ul>
</li>
<li class="sidebar-item">
<a class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)"
aria-expanded="false">
<i class="mdi mdi-alert"></i><span class="hide-menu">Errors </span>
</a>
<ul aria-expanded="false" class="collapse first-level">
<li class="sidebar-item">
<a href="error-403.html" class="sidebar-link">
<i class="mdi mdi-alert-octagon"></i><span class="hide-menu"> Error 403 </span>
</a>
</li>
<li class="sidebar-item">
<a href="error-404.html" class="sidebar-link">
<i class="mdi mdi-alert-octagon"></i><span class="hide-menu"> Error 404 </span>
</a>
</li>
<li class="sidebar-item">
<a href="error-405.html" class="sidebar-link">
<i class="mdi mdi-alert-octagon"></i><span class="hide-menu"> Error 405 </span>
</a>
</li>
<li class="sidebar-item">
<a href="error-500.html" class="sidebar-link">
<i class="mdi mdi-alert-octagon"></i><span class="hide-menu"> Error 500 </span>
</a>
</li>
</ul>
</li>
<li class="sidebar-item p-3">
<a href="https://github.com/wrappixel/matrix-admin-bt5"
target="_blank"
class="
w-100
btn btn-cyan
d-flex
align-items-center
text-white
">
<i class="mdi mdi-cloud-download font-20 me-2"></i>Download
Free
</a>
</li> -->
</ul>
</nav>
<!-- End Sidebar navigation -->
</div>
<!-- End Sidebar scroll-->
</aside>
<!-- ============================================================== -->
<!-- End Left Sidebar - style you can find in sidebar.scss -->
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- Page wrapper -->
<!-- ============================================================== -->
<div b-lhtx71ohus class="page-wrapper">
<!-- ============================================================== -->
<!-- Bread crumb and right sidebar toggle -->
<!-- ============================================================== -->
<div b-lhtx71ohus class="page-breadcrumb">
<div b-lhtx71ohus class="row">
<div b-lhtx71ohus class="col-12 d-flex no-block align-items-center">
<h1 b-lhtx71ohus class="m-0 page-title">Item Movement</h1>
<div b-lhtx71ohus class="ms-auto text-end">
<nav b-lhtx71ohus aria-label="breadcrumb">
<ol b-lhtx71ohus class="breadcrumb">
<li b-lhtx71ohus class="breadcrumb-item"><a b-lhtx71ohus href="#">Home</a></li>
<li b-lhtx71ohus class="breadcrumb-item active" aria-current="page">
Library
</li>
</ol>
</nav>
</div>
</div>
</div>
</div>
<!-- ============================================================== -->
<!-- End Bread crumb and right sidebar toggle -->
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- Container fluid -->
<!-- ============================================================== -->
<div b-lhtx71ohus class="container-fluid">
<!-- ============================================================== -->
<!-- Start Page Content -->
<!-- ============================================================== -->
<div b-lhtx71ohus class="row my-1">
<style>
.text-true {
color: green;
}
.text-false {
color: red;
}
.text-primary {
color: blue; /* Warna asal untuk 'Receive' */
}
.text-warning {
color: orange; /* Warna oren untuk 'Return' */
}
.text-success {
color: greenyellow;
}
.ms-auto {
margin-left: auto !important; /* Push Complete/Incomplete to right */
}
.dropdown {
position: relative;
width: 100%;
}
.dropdown-toggle-box {
display: flex;
align-items: center;
border: 1px solid #ddd;
border-radius: 5px;
overflow: hidden;
}
.dropdown-toggle-box input {
flex: 1;
border: none;
padding: 8px;
}
.dropdown-btn {
border: none;
background-color: #007bff;
color: white;
padding: 8px 12px;
cursor: pointer;
}
.dropdown-content {
position: absolute;
width: 100%;
max-height: 200px;
overflow-y: auto;
background: #fff;
border: 1px solid #ddd;
z-index: 10;
}
.dropdown-content option {
padding: 10px;
cursor: pointer;
display: block;
}
.dropdown-content option:hover {
background-color: #f1f1f1;
}
</style>
<div class="row">
<div class="col-6 col-md-6 col-lg-3">
<div class="card card-hover">
<a href="/Inventory/ItemMovement/ItemRequest">
<div class="box bg-info text-center">
<h1 class="font-light text-white">
<i class="mdi mdi-checkbox-multiple-blank"></i>
</h1>
<h6 class="text-white">Product Request</h6>
</div>
</a>
</div>
</div>
<div class="col-6 col-md-6 col-lg-3">
<div class="card card-hover">
<a href="/Inventory/ItemMovement/QrUser">
<div class="box bg-success text-center">
<h1 class="font-light text-white">
<i class="mdi mdi-checkbox-multiple-blank-circle"></i>
</h1>
<h6 class="text-white">Scan Items</h6>
</div>
</a>
</div>
</div>
<div class="col-6 col-md-6 col-lg-3">
<div class="card card-hover">
<a href="/Inventory/ItemMovement/ItemMovementUser">
<div class="box bg-warning text-center">
<h1 class="font-light text-white">
<i class="mdi mdi-factory"></i>
</h1>
<h6 class="text-white">Item Movement</h6>
</div>
</a>
</div>
</div>
</div>
<div id="ItemMovement" class="row">
<div class="row mb-3">
<h2 for="sortSelect" class="col-sm-1 col-form-h2" style="min-width:150px;">Sort by:</h2>
<div class="col-sm-4">
<select id="sortSelect" class="form-control" v-model="sortBy" v-on:change="handleSorting">
<option value="all">All</option>
<option value="item">Item</option>
<option value="station">Station</option>
</select>
</div>
</div>
<div class="row mb-3" v-if="sortBy === 'item'">
<h4 class="col-sm-1 col-form-h2" style="min-width:150px;">Search Item:</h4>
<div class="col-sm-4">
<input type="text" class="form-control" v-model="searchQuery" placeholder="Search by item code...">
</div>
</div>
<div class="row mb-3" v-if="sortBy === 'station'">
<h4 class="col-sm-1 col-form-h2" style="min-width:150px;">Search Station:</h4>
<div class="col-sm-4">
<div class="dropdown" v-click-outside="closeDropdown">
<!-- Button + Input dalam satu box -->
<div class="dropdown-toggle-box" v-on:click="dropdownOpen = !dropdownOpen">
<input type="text" class="form-control" v-model="searchQueryStation"
placeholder="Search Station..." v-on:focus="dropdownOpen = true" v-on:click.stop />
<button type="button" class="btn btn-primary dropdown-btn" v-on:click.stop="dropdownOpen = !dropdownOpen">
</button>
</div>
<!-- Dropdown list -->
<div v-if="dropdownOpen" class="dropdown-content" v-on:click.stop>
<div v-for="(item, index) in stations"
:key="index" class="dropdown-item" v-on:mousedown.prevent="selectStation(item)">
{{ item.stationName }}
</div>
</div>
</div>
</div>
</div>
<div v-if="sortBy === 'all'">
<h5 style="color:cadetblue">*Each Items will display one record only*</h5>
<div class="row card">
<div class="card-header">
<h2>Pending Item Transit</h2>
</div>
<div class="card-body">
<table class="table table-bordered table-hover table-striped no-wrap" id="itemMovementNotCompleteDatatable"
style="width:100%;border-style: solid; border-width: 1px"></table>
</div>
</div>
<div class="row card">
<div class="card-header">
<h2>Complete Item Movement</h2>
</div>
<div class="card-header">
<h4>All Item Movement</h4>
</div>
<div class="card-body">
<table class="table table-bordered table-hover table-striped no-wrap" id="itemMovementCompleteDatatable"
style="width:100%;border-style: solid; border-width: 1px"></table>
</div>
<div class="card-header">
<h4>Assign Station</h4>
</div>
<div class="card-body">
<table class="table table-bordered table-hover table-striped no-wrap" id="assignStationDatatable"
style="width:100%;border-style: solid; border-width: 1px"></table>
</div>
</div>
</div>
<!--------------------------------------------ITEM CATEGORY---------------------------------------------------------------------->
<div v-if="sortBy === 'item'">
<div v-for="(group, itemId) in paginatedItems" :key="itemId" class="row card">
<div class="card-header d-flex justify-content-between align-items-center">
<h2>Item : {{ group.uniqueID }}</h2>
<button class="btn btn-light" v-on:click="toggleCategory(itemId)">
<i :class="categoryVisible[itemId] ? 'fas fa-chevron-up' : 'fas fa-chevron-down'"></i> Show Details
</button>
</div>
<!-- Hide all details unless button is clicked -->
<div v-show="categoryVisible[itemId]" class="card-body">
<div v-for="(movement, index) in group.movements.sort((a, b) => a.id - b.id).reverse()" :key="movement.id" class="movement-row">
<div v-if="index === 0" class="row">
<strong>Latest Movement</strong>
<div class="col-md-12 d-flex flex-wrap align-items-center gap-3 p-2 border-bottom">
<h3 :class="{'text-primary': movement.toOther === 'On Delivery', 'text-warning': movement.toOther === 'Return',
'text-success': movement.toStation !== null, 'text-info': movement.action === 'Assign' && movement.toStation === null}"
class="flex-shrink-0 text-nowrap" style="max-width:90px; min-width:90px;">
{{ movement.toOther === 'Return' ? 'Return' : (movement.toOther === 'On Delivery' ? 'Receive' : ( movement.toStation !== null ? 'Change' : 'Assign')) }}
</h3>
<!-- Send Date -->
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:285px; min-width:285px;">
<h4 class="fixed-label m-0 text-nowrap">{{movement.action === 'Assign' ? 'Assign Date' : 'Send Date'}}</h4>
<span class="fixed-value text-truncate">{{ formatDate(movement.sendDate) }}</span>
</div>
<!-- Receive Date -->
<div v-if="movement.action !== 'Assign'" class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:290px; min-width:290px;">
<h4 class="fixed-label m-0 text-nowrap">Receive Date:</h4>
<span class="fixed-value text-truncate" style="max-width:160px;">{{ movement.receiveDate || 'Not arrive' }}</span>
</div>
<!-- Action -->
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:150px; min-width:150px;">
<h4 class="fixed-labelStatus m-0 text-nowrap">Action:</h4>
<span class="fixed-value text-truncate">{{ movement.action }}</span>
</div>
<!-- Status -->
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:160px; min-width:160px;">
<h4 class="fixed-labelStatus m-0 text-nowrap">Status:</h4>
<span class="fixed-value text-truncate" style="max-width:90px;">{{ movement.latestStatus || movement.toOther }}</span>
</div>
<!-- More Details Button -->
<button class="btn btn-info btn-sm ms-auto" v-on:click="toggleDetails(movement.id)">
More Details
</button>
<!-- Completion Status -->
<h4 :class="movement.movementComplete == 1 && movement.latestStatus !== 'Ready To Deploy' ? 'text-success' : 'text-danger'"
class="text-nowrap ms-3">
{{ movement.movementComplete == 1 && movement.latestStatus !== 'Ready To Deploy' ? 'Complete' : (movement.latestStatus === 'Ready To Deploy' ? 'Canceled' : 'Incomplete') }}
</h4>
</div>
<div v-show="detailsVisible[movement.id]" class="col-md-12 mt-2">
<div class="row">
<div class="col-md-4 text-center">
<!-- Conditionally render Start Icon -->
<i v-if="movement.toStation" class="fas fa-map-marker-alt"></i>
<i v-else-if="movement.toOther !== 'On Delivery'" class="fas fa-user fa-2x"></i>
<i v-else class="fas fa-warehouse fa-2x"></i>
<p><strong>Start</strong></p>
<p v-if="movement.toUser !== null"><strong>User:</strong> {{ movement.toUserName }}</p>
<p v-if="movement.toStation !== null"><strong>Station:</strong> {{ movement.toStationName }}</p>
<p v-if="movement.toStore !== null"><strong>Store:</strong> {{ movement.toStoreName }}</p>
</div>
<div class="col-md-4 text-center">
<p></p>
<i class="fas fa-arrow-right fa-2x"></i>
<p>{{ movement.latestStatus || movement.toOther }}</p>
<p>
<button class="btn btn-info btn-sm ms-auto" v-on:click="remark(movement.remark)">
Remark
</button>
</p>
<p>
<button class="btn btn-info btn-sm ms-auto" v-on:click="consignmentNote(movement.consignmentNote)">
Consignment Note
</button>
</p>
</div>
<div class="col-md-4 text-center">
<!-- Conditionally render End Icon -->
<i v-if="movement.lastStation" class="fas fa-map-marker-alt"></i>
<i v-else-if="movement.toOther !== 'On Delivery'" class="fas fa-warehouse fa-2x"></i>
<i v-else class="fas fa-user fa-2x"></i>
<p><strong>End</strong></p>
<p v-if="movement.lastUser !== null"><strong>User:</strong> {{ movement.lastUserName }}</p>
<p v-if="movement.lastStation !== null"><strong>Station:</strong> {{ movement.lastStationName }}</p>
<p v-if="movement.lastStore !== null"><strong>Store:</strong> {{ movement.lastStoreName }}</p>
</div>
</div>
</div>
</div>
</div>
<button class="btn btn-light w-100 text-left" v-on:click="toggleHistory(itemId)">
<i :class="historyVisible[itemId] ? 'fas fa-chevron-up' : 'fas fa-chevron-down'"></i> View History
</button>
<div v-show="historyVisible[itemId]" class="history-row">
<div v-for="(movement, i) in group.movements.slice(1)" :key="i" class="row mt-2">
<div class="col-md-12 d-flex flex-wrap align-items-center gap-3 p-2 border-bottom">
<h3 :class="{'text-primary': movement.toOther === 'On Delivery', 'text-warning': movement.toOther === 'Return',
'text-success': movement.toStation !== null, 'text-info': movement.action === 'Assign' && movement.toStation === null}"
class="flex-shrink-0 text-nowrap" style="max-width:90px; min-width:90px;">
{{ movement.toOther === 'Return' ? 'Return' : (movement.toOther === 'On Delivery' ? 'Receive' : ( movement.toStation !== null ? 'Change' : 'Assign')) }}
</h3>
<!-- Send Date -->
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:285px; min-width:285px;">
<h4 class="fixed-label m-0 text-nowrap">{{movement.action === 'Assign' ? 'Assign Date' : 'Send Date'}}</h4>
<span class="fixed-value text-truncate">{{ formatDate(movement.sendDate) }}</span>
</div>
<!-- Receive Date -->
<div v-if="movement.action !== 'Assign'" class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:290px; min-width:290px;">
<h4 class="fixed-label m-0 text-nowrap">Receive Date:</h4>
<span class="fixed-value text-truncate" style="max-width:160px;">{{ movement.receiveDate || 'Not arrive' }}</span>
</div>
<!-- Action -->
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:150px; min-width:150px;">
<h4 class="fixed-labelStatus m-0 text-nowrap">Action:</h4>
<span class="fixed-value text-truncate">{{ movement.action }}</span>
</div>
<!-- Status -->
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:160px; min-width:160px;">
<h4 class="fixed-labelStatus m-0 text-nowrap">Status:</h4>
<span class="fixed-value text-truncate" style="max-width:90px;">{{ movement.latestStatus || movement.toOther }}</span>
</div>
<!-- More Details Button -->
<button class="btn btn-info btn-sm ms-auto" v-on:click="toggleDetails(movement.id)">
More Details
</button>
<!-- Completion Status -->
<h4 :class="movement.movementComplete == 1 && movement.latestStatus !== 'Ready To Deploy' ? 'text-success' : 'text-danger'"
class="text-nowrap ms-3">
{{ movement.movementComplete == 1 && movement.latestStatus !== 'Ready To Deploy' ? 'Complete' : (movement.latestStatus === 'Ready To Deploy' ? 'Canceled' : 'Incomplete') }}
</h4>
</div>
<div v-show="detailsVisible[movement.id]" class="col-md-12 mt-2">
<div class="row">
<div class="col-md-4 text-center">
<!-- Conditionally render Start Icon -->
<i v-if="movement.toStation" class="fas fa-map-marker-alt"></i>
<i v-else-if="movement.toOther !== 'On Delivery'" class="fas fa-user fa-2x"></i>
<i v-else class="fas fa-warehouse fa-2x"></i>
<p><strong>Start</strong></p>
<p v-if="movement.toUser !== null"><strong>User:</strong> {{ movement.toUserName }}</p>
<p v-if="movement.toStation !== null"><strong>Station:</strong> {{ movement.toStationName }}</p>
<p v-if="movement.toStore !== null"><strong>Store:</strong> {{ movement.toStoreName }}</p>
</div>
<div class="col-md-4 text-center">
<p></p>
<i class="fas fa-arrow-right fa-2x"></i>
<p>{{ movement.latestStatus || movement.toOther }}</p>
<p>
<button class="btn btn-info btn-sm ms-auto" v-on:click="remark(movement.remark)">
Remark
</button>
</p>
<p>
<button class="btn btn-info btn-sm ms-auto" v-on:click="consignmentNote(movement.consignmentNote)">
Consignment Note
</button>
</p>
</div>
<div class="col-md-4 text-center">
<!-- Conditionally render End Icon -->
<i v-if="movement.lastStation" class="fas fa-map-marker-alt"></i>
<i v-else-if="movement.toOther !== 'On Delivery'" class="fas fa-warehouse fa-2x"></i>
<i v-else class="fas fa-user fa-2x"></i>
<p><strong>End</strong></p>
<p v-if="movement.lastUser !== null"><strong>User:</strong> {{ movement.lastUserName }}</p>
<p v-if="movement.lastStation !== null"><strong>Station:</strong> {{ movement.lastStationName }}</p>
<p v-if="movement.lastStore !== null"><strong>Store:</strong> {{ movement.lastStoreName }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!--------------------------------------------STATION CATEGORY---------------------------------------------------------------------->
<div v-if="sortBy === 'station'">
<div v-for="(items, station) in filteredStation" :key="stationName"
:class="{'bg-light-gray': station === 'Unassign Station', 'bg-white': station !== 'Unassign Station'}" class="station-category card mt-3">
<!-- Station Header -->
<div class="card-header d-flex justify-content-between align-items-center">
<h3>{{ station }}</h3>
<button class="btn btn-light" v-on:click="toggleCategory(station)">
<i :class="categoryVisible[station] ? 'fas fa-chevron-up' : 'fas fa-chevron-down'"></i> Show Items
</button>
</div>
<!-- Show Items Under Each Station -->
<div v-show="categoryVisible[station]" class="card-body">
<div v-for="(group, itemId) in items" :key="itemId" class="row card">
<!-- Item Header -->
<div class="card-header d-flex justify-content-between align-items-center">
<h2>Item : {{ group.uniqueID }}</h2>
<button class="btn btn-light" v-on:click="toggleCategory(itemId)">
<i :class="categoryVisible[itemId] ? 'fas fa-chevron-up' : 'fas fa-chevron-down'"></i> Show Details
</button>
</div>
<!-- Show Movements for Each Item -->
<div v-show="categoryVisible[itemId]" class="card-body">
<div v-for="(movement, index) in group.movements.sort((a, b) => a.id - b.id).reverse()" :key="movement.id" class="movement-row">
<div v-if="index === 0" class="row">
<strong>Latest Movement</strong>
<div class="col-md-12 d-flex flex-wrap align-items-center gap-3 p-2 border-bottom">
<h3 :class="{'text-primary': movement.toOther === 'On Delivery', 'text-warning': movement.toOther === 'Return',
'text-success': movement.toStation !== null, 'text-info': movement.action === 'Assign' && movement.toStation === null}"
class="flex-shrink-0 text-nowrap" style="max-width:90px; min-width:90px;">
{{ movement.toOther === 'Return' ? 'Return' : (movement.toOther === 'On Delivery' ? 'Receive' : ( movement.toStation !== null ? 'Change' : 'Assign')) }}
</h3>
<!-- Send Date -->
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:285px; min-width:285px;">
<h4 class="fixed-label m-0 text-nowrap">{{movement.action === 'Assign' ? 'Assign Date' : 'Send Date'}}</h4>
<span class="fixed-value text-truncate">{{ formatDate(movement.sendDate) }}</span>
</div>
<!-- Receive Date -->
<div v-if="movement.action !== 'Assign'" class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:290px; min-width:290px;">
<h4 class="fixed-label m-0 text-nowrap">Receive Date:</h4>
<span class="fixed-value text-truncate" style="max-width:160px;">{{ movement.receiveDate || 'Not arrive' }}</span>
</div>
<!-- Action -->
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:150px; min-width:150px;">
<h4 class="fixed-labelStatus m-0 text-nowrap">Action:</h4>
<span class="fixed-value text-truncate">{{ movement.action }}</span>
</div>
<!-- Status -->
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:160px; min-width:160px;">
<h4 class="fixed-labelStatus m-0 text-nowrap">Status:</h4>
<span class="fixed-value text-truncate" style="max-width:90px;">{{ movement.latestStatus || movement.toOther }}</span>
</div>
<!-- More Details Button -->
<button class="btn btn-info btn-sm ms-auto" v-on:click="toggleDetails(movement.id)">
More Details
</button>
<!-- Completion Status -->
<h4 :class="movement.movementComplete == 1 && movement.latestStatus !== 'Ready To Deploy' ? 'text-success' : 'text-danger'"
class="text-nowrap ms-3">
{{ movement.movementComplete == 1 && movement.latestStatus !== 'Ready To Deploy' ? 'Complete' : (movement.latestStatus === 'Ready To Deploy' ? 'Canceled' : 'Incomplete') }}
</h4>
</div>
<div v-show="detailsVisible[movement.id]" class="col-md-12 mt-2">
<div class="row">
<div class="col-md-4 text-center">
<i v-if="movement.toStation" class="fas fa-map-marker-alt"></i>
<i v-else-if="movement.toOther !== 'On Delivery'" class="fas fa-user fa-2x"></i>
<i v-else class="fas fa-warehouse fa-2x"></i>
<p><strong>Start</strong></p>
<p v-if="movement.toUser !== null"><strong>User:</strong> {{ movement.toUserName }}</p>
<p v-if="movement.toStation !== null"><strong>Station:</strong> {{ movement.toStationName }}</p>
<p v-if="movement.toStore !== null"><strong>Store:</strong> {{ movement.toStoreName }}</p>
</div>
<div class="col-md-4 text-center">
<i class="fas fa-arrow-right fa-2x"></i>
<p>{{ movement.latestStatus || movement.toOther }}</p>
<p>
<button class="btn btn-info btn-sm ms-auto" v-on:click="remark(movement.remark)">
Remark
</button>
</p>
<p>
<button class="btn btn-info btn-sm ms-auto" v-on:click="consignmentNote(movement.consignmentNote)">
Consignment Note
</button>
</p>
</div>
<div class="col-md-4 text-center">
<i v-if="movement.lastStation" class="fas fa-map-marker-alt"></i>
<i v-else-if="movement.toOther !== 'On Delivery'" class="fas fa-warehouse fa-2x"></i>
<i v-else class="fas fa-user fa-2x"></i>
<p><strong>End</strong></p>
<p v-if="movement.lastUser !== null"><strong>User:</strong> {{ movement.lastUserName }}</p>
<p v-if="movement.lastStation !== null"><strong>Station:</strong> {{ movement.lastStationName }}</p>
<p v-if="movement.lastStore !== null"><strong>Store:</strong> {{ movement.lastStoreName }}</p>
</div>
</div>
</div>
</div>
</div>
<!-- Single View History Button -->
<button class="btn btn-light w-100 text-left" v-on:click="toggleHistory(itemId)">
<i :class="historyVisible[itemId] ? 'fas fa-chevron-up' : 'fas fa-chevron-down'"></i> View History
</button>
<div v-show="historyVisible[itemId]" class="history-row">
<div v-for="(movement, i) in group.movements.slice(1)" :key="i" class="row mt-2">
<div class="col-md-12 d-flex flex-wrap align-items-center gap-3 p-2 border-bottom">
<!-- Movement Type -->
<h3 :class="{'text-primary': movement.toOther === 'On Delivery', 'text-warning': movement.toOther === 'Return',
'text-success': movement.toStation !== null, 'text-info': movement.action === 'Assign' && movement.toStation === null}"
class="flex-shrink-0 text-nowrap" style="max-width:90px; min-width:90px;">
{{ movement.toOther === 'Return' ? 'Return' : (movement.toOther === 'On Delivery' ? 'Receive' : ( movement.toStation !== null ? 'Change' : 'Assign')) }}
</h3>
<!-- Send Date -->
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:285px; min-width:285px;">
<h4 class="fixed-label m-0 text-nowrap">{{movement.action === 'Assign' ? 'Assign Date' : 'Send Date'}}</h4>
<span class="fixed-value text-truncate">{{ formatDate(movement.sendDate) }}</span>
</div>
<!-- Receive Date -->
<div v-if="movement.action !== 'Assign'" class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:290px; min-width:290px;">
<h4 class="fixed-label m-0 text-nowrap">Receive Date:</h4>
<span class="fixed-value text-truncate" style="max-width:160px;">{{ movement.receiveDate || 'Not arrive' }}</span>
</div>
<!-- Action -->
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:150px; min-width:150px;">
<h4 class="fixed-labelStatus m-0 text-nowrap">Action:</h4>
<span class="fixed-value text-truncate">{{ movement.action }}</span>
</div>
<!-- Status -->
<div class="d-flex flex-wrap align-items-center gap-2 flex-grow-1" style="max-width:160px; min-width:160px;">
<h4 class="fixed-labelStatus m-0 text-nowrap">Status:</h4>
<span class="fixed-value text-truncate" style="max-width:90px;">{{ movement.latestStatus || movement.toOther }}</span>
</div>
<!-- More Details Button -->
<button class="btn btn-info btn-sm ms-auto" v-on:click="toggleDetails(movement.id)">
More Details
</button>
<!-- Completion Status -->
<h4 :class="movement.movementComplete == 1 && movement.latestStatus !== 'Ready To Deploy' ? 'text-success' : 'text-danger'"
class="text-nowrap ms-3">
{{ movement.movementComplete == 1 && movement.latestStatus !== 'Ready To Deploy' ? 'Complete' : (movement.latestStatus === 'Ready To Deploy' ? 'Canceled' : 'Incomplete') }}
</h4>
</div>
<!-- Details Section (Hidden by Default) -->
<div v-show="detailsVisible[movement.id]" class="col-md-12 mt-2">
<div class="row">
<div class="col-md-4 text-center">
<!-- Conditionally render Start Icon -->
<i v-if="movement.toStation" class="fas fa-map-marker-alt"></i>
<i v-else-if="movement.toOther !== 'On Delivery'" class="fas fa-user fa-2x"></i>
<i v-else class="fas fa-warehouse fa-2x"></i>
<p><strong>Start</strong></p>
<p v-if="movement.toUser !== null"><strong>User:</strong> {{ movement.toUserName }}</p>
<p v-if="movement.toStation !== null"><strong>Station:</strong> {{ movement.toStationName }}</p>
<p v-if="movement.toStore !== null"><strong>Store:</strong> {{ movement.toStoreName }}</p>
</div>
<div class="col-md-4 text-center">
<p></p>
<i class="fas fa-arrow-right fa-2x"></i>
<p>{{ movement.latestStatus || movement.toOther }}</p>
<p>
<button class="btn btn-info btn-sm ms-auto" v-on:click="remark(movement.remark)">
Remark
</button>
</p>
<p>
<button class="btn btn-info btn-sm ms-auto" v-on:click="consignmentNote(movement.consignmentNote)">
Consignment Note
</button>
</p>
</div>
<div class="col-md-4 text-center">
<!-- Conditionally render End Icon -->
<i v-if="movement.lastStation" class="fas fa-map-marker-alt"></i>
<i v-else-if="movement.toOther !== 'On Delivery'" class="fas fa-warehouse fa-2x"></i>
<i v-else class="fas fa-user fa-2x"></i>
<p><strong>End</strong></p>
<p v-if="movement.lastUser !== null"><strong>User:</strong> {{ movement.lastUserName }}</p>
<p v-if="movement.lastStation !== null"><strong>Station:</strong> {{ movement.lastStationName }}</p>
<p v-if="movement.lastStore !== null"><strong>Store:</strong> {{ movement.lastStoreName }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!--------------------------------------------REMARK & CONSIGNMENT NOTE CATEGORY---------------------------------------------------------------------->
<div class="modal fade" id="remarkModal" tabindex="-1" aria-labelledby="remarkModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="remarkModalLabel">Remark</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="remarkContent">
<!-- Remark Content Here -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="consignmentModal" tabindex="-1" aria-labelledby="consignmentModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="consignmentModalLabel">Consignment Note</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body text-center">
<img v-if="/\.(jpeg|jpg|png|gif)$/i.test(consignmentNoteUrl)" :src="consignmentNoteUrl" class="img-fluid" alt="Consignment Note Image">
<iframe v-else-if="/\.pdf$/i.test(consignmentNoteUrl)" :src="consignmentNoteUrl" style="width:100%; height: 80vh;"></iframe>
<a v-else class="btn btn-primary">There's no Folder or Picture</a>
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-center align-items-center mt-3" v-if="sortBy === 'item' && totalPages > 0">
<button class="btn btn-secondary mx-1" v-on:click="goToPage(currentPage - 1)" :disabled="currentPage === 1">
Previous
</button>
<span class="mx-2">Page {{ currentPage }} of {{ totalPages }}</span>
<button class="btn btn-secondary mx-1" v-on:click="goToPage(currentPage + 1)" :disabled="currentPage === totalPages">
Next
</button>
</div>
<div class="d-flex justify-content-center align-items-center mt-3" v-if="sortBy === 'station' && totalPagesStation > 0">
<button class="btn btn-secondary mx-1" v-on:click="goToPageStation(currentPageStation - 1)" :disabled="currentPageStation === 1">
Previous
</button>
<span class="mx-2">Page {{ currentPageStation }} of {{ itemsPerPageStation }}</span>
<button class="btn btn-secondary mx-1" v-on:click="goToPageStation(currentPageStation + 1)" :disabled="currentPageStation === totalPages">
Next
</button>
</div>
</div>
</div>
<!-- ============================================================== -->
<!-- End PAge Content -->
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- Right sidebar -->
<!-- ============================================================== -->
<!-- .right-sidebar -->
<!-- ============================================================== -->
<!-- End Right sidebar -->
<!-- ============================================================== -->
</div>
<!-- ============================================================== -->
<!-- End Container fluid -->
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- footer -->
<!-- ============================================================== -->
<footer b-lhtx71ohus class="footer text-center">
All Rights Reserved by PSTW. Designed and Developed by
<a b-lhtx71ohus href="https://www.wrappixel.com">WrapPixel</a>.
</footer>
<!-- ============================================================== -->
<!-- End footer -->
<!-- ============================================================== -->
</div>
<!-- ============================================================== -->
<!-- End Page wrapper -->
<!-- ============================================================== -->
</div>
<!-- ============================================================== -->
<!-- End Wrapper -->
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- All Jquery -->
<!-- ============================================================== -->
<script src="/assets/libs/jquery/dist/jquery.min.js"></script>
<script src="/dist/js/jquery-ui.min.js"></script>
<!-- VUE Multiselect-->
<script src="/lib/vue-multiselect/vue-multiselect.js"></script>
<link href="/lib/vue-multiselect/vue-multiselect.min.css" rel="stylesheet" />
<!-- VUE Date Picker-->
<link href="/lib/vue-datepicker/mainvuedate.css" rel="stylesheet" />
<script src="/lib/vue-datepicker/vue-datepicker.iife.js"></script>
<!-- Bootstrap tether Core JavaScript -->
<script src="/assets/libs/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<!-- slimscrollbar scrollbar JavaScript -->
<script src="/assets/libs/perfect-scrollbar/dist/perfect-scrollbar.jquery.min.js"></script>
<script src="/assets/extra-libs/sparkline/sparkline.js"></script>
<!--Wave Effects -->
<script src="/dist/js/waves.js"></script>
<!--Menu sidebar -->
<script src="/dist/js/sidebarmenu.js"></script>
<!--Custom JavaScript -->
<script src="/dist/js/custom.min.js"></script>
<!--Form JS-->
<script src="/assets/libs/inputmask/dist/min/jquery.inputmask.bundle.min.js"></script>
<script src="/dist/js/pages/mask/mask.init.js"></script>
<script src="/assets/libs/select2/dist/js/select2.full.min.js"></script>
<script src="/assets/libs/jquery-asColor/dist/jquery-asColor.min.js"></script>
<script src="/assets/libs/jquery-asGradient/dist/jquery-asGradient.js"></script>
<script src="/assets/libs/jquery-asColorPicker/dist/jquery-asColorPicker.min.js"></script>
<script src="/assets/libs/jquery-minicolors/jquery.minicolors.min.js"></script>
<script src="/assets/libs/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js"></script>
<script src="/assets/libs/quill/dist/quill.min.js"></script>
<script src="/lib/printjs/print.min.js"></script>
<script src="/lib/html2canvas/html2canvas.min.js"></script>
<script src="/lib/html2canvas/dom-to-image.min.js"></script>
<!-- Datatables JS-->
<script src="/lib/datatables/datatables.js"></script>
<script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<script>
$(function () {
app.mount('#ItemMovement');
});
const app = Vue.createApp({
data() {
return {
userId: null,
itemMovements: [],
assignStationDatatable: null,
itemMovementCompleteDatatable: null,
itemMovementNotCompleteDatatable: null,
searchQuery: "",
searchQueryStation: "",
searchStation: "",
sortBy: "all",
historyVisible: {},
detailsVisible: {},
categoryVisible: {},
consignmentNoteUrl: "",
stationName: "",
currentPage: 1,
itemsPerPage: 10,
currentPageStation: 1,
itemsPerPageStation: 10,
dropdownOpen: false,
currentUser: null,
stations:[],
};
},
computed: {
paginatedItems() {
const start = (this.currentPage - 1) * this.itemsPerPage;
const end = start + this.itemsPerPage;
return Object.fromEntries(
Object.entries(this.filteredItems).slice(start, end)
);
},
totalPages() {
return Math.ceil(Object.keys(this.filteredItems).length / this.itemsPerPage);
},
totalPagesStation() {
return Math.ceil(Object.keys(this.filteredStation).length / this.itemsPerPage);
},
processedGroupedItems() {
let grouped = this.itemMovements.reduce((acc, movement) => {
if (!acc[movement.itemId]) {
acc[movement.itemId] = {
uniqueID: movement.uniqueID,
movements: [],
};
}
acc[movement.itemId].movements.push(movement);
return acc;
}, {});
let filteredGrouped = {};
for (let itemId in grouped) {
let movements = grouped[itemId].movements
.sort((a, b) => b.id - a.id); // Newest to oldest
let stopIndex = movements.findIndex(m =>
m.toOther === 'Return' && m.movementComplete == 1
);
let nextIndex = movements.findIndex(m =>
m.latestStatus === 'Ready To Deploy' && m.movementComplete == 1
);
if (stopIndex !== -1) {
movements = movements.slice(0, stopIndex);
}
if (nextIndex !== -1) {
movements = movements.slice(0, nextIndex);
}
if (movements.length > 0) {
filteredGrouped[itemId] = {
uniqueID: grouped[itemId].uniqueID,
movements: movements,
};
}
}
return filteredGrouped;
},
groupedByStation() {
let groupedByItem = this.itemMovements.reduce((acc, movement) => {
if (!acc[movement.uniqueID]) {
acc[movement.uniqueID] = {
uniqueID: movement.uniqueID,
movements: [],
};
}
acc[movement.uniqueID].movements.push(movement);
return acc;
}, {});
let groupedByStation = {};
Object.keys(groupedByItem).forEach(itemId => {
let movements = groupedByItem[itemId].movements
.sort((a, b) => b.id - a.id); // Newest → Oldest
// Find first occurrence of 'Return' complete
let stopIndex = movements.findIndex(m =>
m.toOther === 'Return' && m.movementComplete == 1
);
let nextIndex = movements.findIndex(m =>
m.latestStatus === 'Ready To Deploy' && m.movementComplete == 1
);
if (stopIndex !== -1) {
movements = movements.slice(0, stopIndex);
}
if (nextIndex !== -1) {
movements = movements.slice(0, nextIndex);
}
if (movements.length > 0) {
let latestMovement = movements[0];
let station = latestMovement.lastStationName || latestMovement.toStationName || "Self Assigned";
if (!groupedByStation[station]) {
groupedByStation[station] = {};
}
groupedByStation[station][itemId] = { uniqueID: itemId, movements };
}
});
// 4⃣ **Sort stations & move 'Unassign Station' to last**
let sortedKeys = Object.keys(groupedByStation).sort((a, b) => {
if (a === "Unassign Station") return 1;
if (b === "Unassign Station") return -1;
return a.localeCompare(b);
});
let sortedGrouped = {};
sortedKeys.forEach(key => {
sortedGrouped[key] = groupedByStation[key];
});
return sortedGrouped;
},
filteredItems() {
if (!this.searchQuery.trim()) {
return this.processedGroupedItems;
}
const searchLower = this.searchQuery.toLowerCase();
let grouped = this.processedGroupedItems;
let filtered = {};
Object.keys(grouped).forEach(item => {
if (item.toLowerCase().includes(searchLower)) {
if (grouped[item] > 0) {
filtered[item] = grouped[item];
}
}
});
return filtered;
},
filteredStation() {
if (!this.searchQueryStation) {
return this.groupedByStation;
}
let searchQueryStation = this.searchQueryStation.toLowerCase();
let grouped = this.groupedByStation;
let filtered = {};
Object.keys(grouped).forEach(station => {
if (station.toLowerCase().includes(searchQueryStation)) {
filtered[station] = grouped[station];
}
});
return filtered;
},
},
async mounted() {
this.fetchItemMovement();
await this.fetchUser();
await Promise.all([
this.fetchStation(),
]);
},
methods: {
formatDate(dateString) {
if (!dateString) return '';
const date = new Date(dateString);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
paginatedItemsStation(item) {
const start = (this.currentPageStation - 1) * this.itemsPerPageStation;
const end = start + this.itemsPerPageStation;
return Object.fromEntries(
Object.entries(item).slice(start, end)
);
},
selectStation(item) {
this.searchQueryStation = item.stationName;
this.dropdownOpen = false;
},
closeDropdown() {
this.dropdownOpen = false; // Tutup dropdown
},
goToPage(page) {
if (page >= 1 && page <= this.totalPages) {
this.currentPage = page;
}
},
goToPageStation(page) {
if (page >= 1 && page <= this.itemsPerPageStation) {
this.currentPageStation = page;
}
},
remark(remark) {
document.getElementById("remarkContent").innerText = remark || "No remark message provide.";
let modal = new bootstrap.Modal(document.getElementById("remarkModal"));
modal.show();
},
remark(remark) {
document.getElementById("remarkContent").innerText = remark || "No remark message provide.";
let modal = new bootstrap.Modal(document.getElementById("remarkModal"));
modal.show();
},
consignmentNote(consignmentNote) {
if (!consignmentNote) {
this.consignmentNoteUrl = "No consignment note available.";
new bootstrap.Modal(document.getElementById('consignmentModal')).show();
return;
}
// Pastikan URL betul
this.consignmentNoteUrl = consignmentNote;
// Tunggu Vue update sebelum buka modal
this.$nextTick(() => {
new bootstrap.Modal(document.getElementById('consignmentModal')).show();
});
},
async fetchItemMovement() {
try {
const response = await fetch("/InvMainAPI/ItemMovementUser", {
method: "POST",
headers: { "Content-Type": "application/json" },
});
if (!response.ok) throw new Error("Failed to fetch item movement");
const data = await response.json();
this.itemMovements = data.map((movement) => ({
...movement,
showDetails: false,
}));
this.renderTables();
} catch (error) {
console.error("Error fetching item:", error);
}
},
async fetchStation() {
try {
const response = await fetch('/InvMainAPI/StationList', {
method: 'POST', // Specify the HTTP method
headers: {
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error('Failed to fetch Station');
}
const data = await response.json();
this.stations = data.filter(station => station.stationPicID === this.userId);
} catch (error) {
console.error('Error fetching Station:', error);
}
},
async fetchUser() {
try {
const response = await fetch(`/IdentityAPI/GetUserInformation/`, {
method: 'POST',
});
if (response.ok) {
const data = await response.json();
this.currentUser = data?.userInfo || null;
this.userId = await this.currentUser.id;
}
else {
console.error(`Failed to fetch user: ${response.statusText}`);
}
}
catch (error) {
console.error('There was a problem with the fetch operation:', error);
}
},
handleSorting() {
this.renderTables();
},
renderTables() {
if (this.sortBy === "all") {
this.initAllTables();
}
},
initAllTables() {
if (this.itemMovementNotCompleteDatatable) {
this.itemMovementNotCompleteDatatable.destroy();
}
if (this.itemMovementCompleteDatatable) {
this.itemMovementCompleteDatatable.destroy();
}
if (this.assignStationDatatable) {
this.assignStationDatatable.destroy();
}
// Get latest movement per uniqueID after filtering
function getLatestMovements(data) {
let latestMovements = {};
data.forEach(movement => {
let id = movement.uniqueID;
if (!latestMovements[id] || latestMovements[id].id < movement.id) {
latestMovements[id] = movement;
}
});
return Object.values(latestMovements);
}
// Filter movements based on conditions
function filterMovements(movements) {
let stopIndex = movements.findIndex(m =>
m.toOther === 'Return' && m.movementComplete == 1
);
let nextIndex = movements.findIndex(m =>
m.latestStatus === 'Ready To Deploy' && m.movementComplete == 1
);
if (stopIndex !== -1) {
movements = movements.slice(0, stopIndex);
}
if (nextIndex !== -1) {
movements = movements.slice(0, nextIndex);
}
return movements;
}
let latestMovements = getLatestMovements(this.itemMovements);
let notCompleteData = [];
let completeData = [];
let completeStationData = [];
latestMovements.forEach(movement => {
let filteredMovements = filterMovements([movement]);
if (filteredMovements.length > 0) {
if (movement.movementComplete == 0) {
notCompleteData.push(movement);
} else if (movement.movementComplete == 1 && movement.action !== "Assign") {
completeData.push(movement);
} else {
completeStationData.push(movement);
}
}
});
// Table 1: Not Complete Movements
this.itemMovementNotCompleteDatatable = $("#itemMovementNotCompleteDatatable").DataTable({
data: notCompleteData,
columns: [
{ title: "Unique Id", data: "id" },
{ title: "Product Name", data: "productName", render: (data, type, full) => { return `${data} <br> ${renderFile(full.productImage)}`; } },
{ title: "Product Code", data: "uniqueID" },
{ title: "Action", data: "action" },
{ title: "Send Date", data: "sendDate", render: this.formatDate.bind(this) },
{ title: "Start Status", data: "toOther" },
{ title: "From User", data: "toUserName" },
{ title: "Last User", data: "lastUserName" },
{ title: "From Station", data: "toStationName" },
{ title: "From Store", data: "toStoreName" },
{ title: "Quantity", data: "quantity" },
{ title: "Note", data: "consignmentNote", render: renderFile },
{ title: "Remark", data: "remark" },
],
responsive: true,
});
// Table 2: Completed Movements
this.itemMovementCompleteDatatable = $("#itemMovementCompleteDatatable").DataTable({
data: completeData,
columns: [
{ title: "Unique Id", data: "id" },
{ title: "Product Name", data: "productName", render: (data, type, full) => { return `${data} <br> ${renderFile(full.productImage)}`; } },
{ title: "Product Code", data: "uniqueID" },
{ title: "Send Date", data: "sendDate", render: this.formatDate.bind(this) },
{ title: "Receive Date", data: "receiveDate" },
{ title: "Action", data: "action" },
{ title: "Start Status", data: "toOther" },
{ title: "Latest Status", data: "latestStatus" },
{ title: "From User", data: "toUserName" },
{ title: "Last User", data: "lastUserName" },
{ title: "From Station", data: "toStationName" },
{ title: "Last Station", data: "lastStationName" },
{ title: "From Store", data: "toStoreName" },
{ title: "Last Store", data: "lastStoreName" },
{ title: "Qty", data: "quantity" },
{ title: "Note", data: "consignmentNote", render: renderFile },
{ title: "Remark", data: "remark" },
],
responsive: true,
});
// Table 3: Station Movements
this.assignStationDatatable = $("#assignStationDatatable").DataTable({
data: completeStationData,
columns: [
{ title: "Unique Id", data: "id" },
{ title: "Product Name", data: "productName", render: (data, type, full) => { return `${data} <br> ${renderFile(full.productImage)}`; }},
{ title: "Product Code", data: "uniqueID" },
{ title: "Assign Date", data: "sendDate", render: this.formatDate.bind(this) },
{ title: "Action", data: "action" },
{ title: "Station User PIC", data: "toUserName" },
{ title: "From Station", data: "toStationName" },
{ title: "Last Station", data: "lastStationName" },
{ title: "Qty", data: "quantity" },
{ title: "Note", data: "consignmentNote", render: renderFile },
{ title: "Remark", data: "remark" },
],
responsive: true,
});
// Function to render file (image/PDF)
function renderFile(data, type, full, meta) {
if (!data) {
return "No Document";
}
var isImage = /\.(jpeg|jpg|png|gif)$/i.test(data);
var isPdf = /\.pdf$/i.test(data);
if (isImage) {
return `<a href="${data}" target="_blank" data-lightbox="image-1">
<img src="${data}" alt="Image" class="img-thumbnail" style="width: 100px; height: 100px;" />
</a>`;
} else if (isPdf) {
return `<a href="${data}" target="_blank">
<img src="https://upload.wikimedia.org/wikipedia/commons/8/87/PDF_file_icon.svg"
alt="PDF Document" class="img-thumbnail"
style="width: 50px; height: 50px;" />
<br>View PDF
</a>`;
} else {
return `<a href="${data}" target="_blank">Download File</a>`;
}
}
},
toggleCategory(itemId) {
this.categoryVisible[itemId] = !this.categoryVisible[itemId];
this.detailsVisible = {};
this.historyVisible = {};
},
toggleHistory(itemId) {
// Jika item yang ditekan sudah terbuka, tutup
if (this.historyVisible[itemId]) {
this.historyVisible[itemId] = false;
} else {
// Tutup semua history lain dahulu
this.historyVisible = {};
// Buka hanya item yang ditekan
this.historyVisible[itemId] = true;
}
},
toggleDetails(movementId) {
this.detailsVisible[movementId] = !this.detailsVisible[movementId];
},
},
directives: {
clickOutside: {
beforeMount(el, binding) {
el.clickOutsideEvent = (event) => {
if (!(el.contains(event.target))) {
binding.value?.(); // Guna optional chaining untuk elak error
}
};
document.body.addEventListener("click", el.clickOutsideEvent);
},
unmounted(el) {
document.body.removeEventListener("click", el.clickOutsideEvent);
}
}
}
});
</script>
</body>
</html>