Update
This commit is contained in:
parent
815769fab7
commit
0636109ac9
@ -1044,35 +1044,35 @@
|
|||||||
this.loading = true;
|
this.loading = true;
|
||||||
await this.fetchUser();
|
await this.fetchUser();
|
||||||
try {
|
try {
|
||||||
// const token = localStorage.getItem('token'); // Get the token from localStorage
|
|
||||||
const response = await fetch('/InvMainAPI/ItemMovementList', {
|
const response = await fetch('/InvMainAPI/ItemMovementList', {
|
||||||
method: 'POST', // Specify the HTTP method
|
method: 'POST',
|
||||||
headers: {
|
headers: { 'Content-Type': 'application/json' }
|
||||||
'Content-Type': 'application/json', // Set content type
|
|
||||||
// 'Authorization': `Bearer ${token}` // Include the token in the headers
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) throw new Error('Failed to fetch item');
|
||||||
throw new Error('Failed to fetch item');
|
|
||||||
}
|
|
||||||
if(this.currentRole == "Super Admin"){
|
|
||||||
this.items = await response.json();
|
|
||||||
this.initAllTables();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
|
if(this.currentRole == "Super Admin"){
|
||||||
|
this.items = data;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
const myStationIds = this.stations
|
||||||
|
.filter(s => s.stationPicID === this.currentUser.id)
|
||||||
|
.map(s => s.stationId);
|
||||||
|
|
||||||
this.items = data.filter(item =>
|
this.items = data.filter(item =>
|
||||||
item.lastUser === this.currentUser.id ||
|
item.lastUser === this.currentUser.id ||
|
||||||
item.toUser === this.currentUser.id ||
|
item.toUser === this.currentUser.id ||
|
||||||
|
(item.lastStation && myStationIds.includes(item.lastStation)) ||
|
||||||
|
(item.toStation && myStationIds.includes(item.toStation)) ||
|
||||||
item.lastStore === this.currentUser.store ||
|
item.lastStore === this.currentUser.store ||
|
||||||
item.toStore === this.currentUser.store
|
item.toStore === this.currentUser.store
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.initAllTables();
|
this.initAllTables();
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.itemDatatable) {
|
if (this.itemDatatable) {
|
||||||
this.itemDatatable.clear().destroy();
|
this.itemDatatable.clear().destroy();
|
||||||
}
|
}
|
||||||
@ -1081,7 +1081,6 @@
|
|||||||
catch (error) {
|
catch (error) {
|
||||||
console.error('Error fetching item:', error);
|
console.error('Error fetching item:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
},
|
},
|
||||||
async fetchUser() {
|
async fetchUser() {
|
||||||
@ -1164,10 +1163,10 @@
|
|||||||
{ title: "Action", data: "action" },
|
{ title: "Action", data: "action" },
|
||||||
{ title: "Send Date", data: "sendDate" , render: this.formatDate.bind(this)},
|
{ title: "Send Date", data: "sendDate" , render: this.formatDate.bind(this)},
|
||||||
{ title: "From User", data: "lastUserName" },
|
{ title: "From User", data: "lastUserName" },
|
||||||
{ title: "Last User", data: "toUserName" },
|
|
||||||
{ title: "From Station", data: "lastStationName" },
|
{ title: "From Station", data: "lastStationName" },
|
||||||
{ title: "Last Station", data: "toStationName" },
|
|
||||||
{ title: "From Store", data: "lastStoreName" },
|
{ title: "From Store", data: "lastStoreName" },
|
||||||
|
{ title: "Last User", data: "toUserName" },
|
||||||
|
{ title: "Last Station", data: "toStationName" },
|
||||||
{ title: "Last Store", data: "toStoreName" },
|
{ title: "Last Store", data: "toStoreName" },
|
||||||
{ title: "Start Status", data: "toOther" },
|
{ title: "Start Status", data: "toOther" },
|
||||||
{ title: "Product Category", data: "productCategory" },
|
{ title: "Product Category", data: "productCategory" },
|
||||||
@ -1189,10 +1188,10 @@
|
|||||||
{ title: "Receive Date", data: "receiveDate", render: this.formatDate.bind(this) },
|
{ title: "Receive Date", data: "receiveDate", render: this.formatDate.bind(this) },
|
||||||
{ title: "Action", data: "action" },
|
{ title: "Action", data: "action" },
|
||||||
{ title: "From User", data: "lastUserName" },
|
{ title: "From User", data: "lastUserName" },
|
||||||
{ title: "Last User", data: "toUserName" },
|
|
||||||
{ title: "From Station", data: "lastStationName" },
|
{ title: "From Station", data: "lastStationName" },
|
||||||
{ title: "Last Station", data: "toStationName" },
|
|
||||||
{ title: "From Store", data: "lastStoreName" },
|
{ title: "From Store", data: "lastStoreName" },
|
||||||
|
{ title: "Last User", data: "toUserName" },
|
||||||
|
{ title: "Last Station", data: "toStationName" },
|
||||||
{ title: "Last Store", data: "toStoreName" },
|
{ title: "Last Store", data: "toStoreName" },
|
||||||
{ title: "Start Status", data: "toOther" },
|
{ title: "Start Status", data: "toOther" },
|
||||||
{ title: "Latest Status", data: "latestStatus" },
|
{ title: "Latest Status", data: "latestStatus" },
|
||||||
@ -1205,7 +1204,11 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.assignStationDatatable = $("#assignStationDatatable").DataTable({
|
this.assignStationDatatable = $("#assignStationDatatable").DataTable({
|
||||||
data: this.items.filter((m) => m.action === "Assign" ),
|
data: this.items.filter((m) =>
|
||||||
|
m.action === "Assign" ||
|
||||||
|
m.action === "Change" ||
|
||||||
|
m.toStation !== null
|
||||||
|
),
|
||||||
columns: [
|
columns: [
|
||||||
{ title: "Unique Id", data: "id" },
|
{ title: "Unique Id", data: "id" },
|
||||||
{ title: "Product Name", data: "productName", render: (data, type, full) => { return `${data} <br> ${renderFile(full.productImage)}`; } },
|
{ title: "Product Name", data: "productName", render: (data, type, full) => { return `${data} <br> ${renderFile(full.productImage)}`; } },
|
||||||
|
|||||||
@ -337,7 +337,7 @@
|
|||||||
<div class="form-group row d-flex align-items-center">
|
<div class="form-group row d-flex align-items-center">
|
||||||
<label class="col-sm-2 col-form-label">Quantity:</label>
|
<label class="col-sm-2 col-form-label">Quantity:</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input type="number" class="form-control" v-model="quantity" required />
|
<input type="number" class="form-control" v-model="quantity" min="1" required />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -426,11 +426,11 @@
|
|||||||
// Show the modal
|
// Show the modal
|
||||||
$('.modal').modal('hide');
|
$('.modal').modal('hide');
|
||||||
});
|
});
|
||||||
$('.submit-button').on('click', function () {
|
// $('.submit-button').on('click', function () {
|
||||||
// Show the modal
|
// Show the modal
|
||||||
$('#rejectModal').modal('hide');
|
// $('#rejectModal').modal('hide');
|
||||||
$('#approveModal').modal('hide');
|
// $('#approveModal').modal('hide');
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
const app = Vue.createApp({
|
const app = Vue.createApp({
|
||||||
data() {
|
data() {
|
||||||
@ -536,7 +536,7 @@
|
|||||||
// Prepare data as JSON (No file upload)
|
// Prepare data as JSON (No file upload)
|
||||||
const requestDatas = {
|
const requestDatas = {
|
||||||
ProductId: this.productId,
|
ProductId: this.productId,
|
||||||
StationId: this.stationId,
|
// StationId: this.stationId,
|
||||||
UserId: this.userId,
|
UserId: this.userId,
|
||||||
ProductCategory: this.productCategory,
|
ProductCategory: this.productCategory,
|
||||||
RequestQuantity: this.quantity,
|
RequestQuantity: this.quantity,
|
||||||
@ -720,8 +720,8 @@
|
|||||||
"columns": [
|
"columns": [
|
||||||
{ "title": "Request ID", "data": "requestID" },
|
{ "title": "Request ID", "data": "requestID" },
|
||||||
{ "title": "Product", "data": "productName", "render": renderDocument },
|
{ "title": "Product", "data": "productName", "render": renderDocument },
|
||||||
{ "title": "From Store", "data": "fromStoreItem" },
|
{ "title": "From Store", "data": "fromStoreName" },
|
||||||
{ "title": "Assign Store", "data": "assignStoreItem" },
|
{ "title": "Assign Store", "data": "assignStoreName" },
|
||||||
{ "title": "Product Category", "data": "productCategory" },
|
{ "title": "Product Category", "data": "productCategory" },
|
||||||
{ "title": "Request Quantity", "data": "requestQuantity" },
|
{ "title": "Request Quantity", "data": "requestQuantity" },
|
||||||
{ "title": "Document/Picture", "data": "document", "render": renderDocument },
|
{ "title": "Document/Picture", "data": "document", "render": renderDocument },
|
||||||
@ -748,8 +748,8 @@
|
|||||||
{ "title": "Action", "data": "requestID", "render": renderActionButtons, "className": "align-middle" },
|
{ "title": "Action", "data": "requestID", "render": renderActionButtons, "className": "align-middle" },
|
||||||
{ "title": "Product", "data": "productName", "render": renderDocument },
|
{ "title": "Product", "data": "productName", "render": renderDocument },
|
||||||
{ "title": "Requested by User", "data": "userName" },
|
{ "title": "Requested by User", "data": "userName" },
|
||||||
{ "title": "From Store", "data": "fromStoreItem" },
|
{ "title": "From Store", "data": "fromStoreName" },
|
||||||
{ "title": "Assign Store", "data": "assignStoreItem" },
|
{ "title": "Assign Store", "data": "assignStoreName" },
|
||||||
{ "title": "Product Category", "data": "productCategory" },
|
{ "title": "Product Category", "data": "productCategory" },
|
||||||
{ "title": "Request Quantity", "data": "requestQuantity" },
|
{ "title": "Request Quantity", "data": "requestQuantity" },
|
||||||
{ "title": "Document/Picture", "data": "document", "render": renderDocument },
|
{ "title": "Document/Picture", "data": "document", "render": renderDocument },
|
||||||
@ -766,8 +766,8 @@
|
|||||||
{ "title": "Request ID", "data": "requestID" },
|
{ "title": "Request ID", "data": "requestID" },
|
||||||
{ "title": "Product", "data": "productName", "render": renderDocument },
|
{ "title": "Product", "data": "productName", "render": renderDocument },
|
||||||
{ "title": "Requested by User", "data": "userName" },
|
{ "title": "Requested by User", "data": "userName" },
|
||||||
{ "title": "From Store", "data": "fromStoreItem" },
|
{ "title": "From Store", "data": "fromStoreName" },
|
||||||
{ "title": "Assign Store", "data": "assignStoreItem" },
|
{ "title": "Assign Store", "data": "assignStoreName" },
|
||||||
{ "title": "Product Category", "data": "productCategory" },
|
{ "title": "Product Category", "data": "productCategory" },
|
||||||
{ "title": "Request Quantity", "data": "requestQuantity" },
|
{ "title": "Request Quantity", "data": "requestQuantity" },
|
||||||
{ "title": "Document/Picture", "data": "document", "render": renderDocument },
|
{ "title": "Document/Picture", "data": "document", "render": renderDocument },
|
||||||
@ -976,107 +976,79 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async approveRequest() {
|
async approveRequest() {
|
||||||
// if (!confirm("Are you sure you want to approve this request?")) {
|
|
||||||
// return;
|
if (!this.approveremark || this.approveremark.trim() === "") {
|
||||||
// }
|
alert("Please enter a remark before approving this request.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const formData = {
|
const formData = {
|
||||||
RemarkMasterInv: this.rejectremark,
|
RemarkMasterInv: this.approveremark,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let requestID = this.currentrequestID;
|
let requestID = this.currentrequestID;
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/InvMainAPI/ApproveRequest/${requestID}`, {
|
const response = await fetch(`/InvMainAPI/ApproveRequest/${requestID}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: { 'Content-Type': 'application/json' },
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(formData)
|
body: JSON.stringify(formData)
|
||||||
|
|
||||||
});
|
});
|
||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
alert(result.message);
|
alert(result.message);
|
||||||
|
this.approveremark = "";
|
||||||
//static update
|
this.fetchRequest();
|
||||||
const row = $(`.approve-btn[data-id="${requestID}"]`).closest('tr');
|
|
||||||
let rowData = this.requestDatatable.row(row).data();
|
|
||||||
|
|
||||||
// Update the status and remark
|
|
||||||
rowData.status = "Approved";
|
|
||||||
|
|
||||||
// Remove row from requestDatatable
|
|
||||||
this.requestDatatable.row(row).remove().draw();
|
|
||||||
|
|
||||||
// Add updated row to settledrequestDatatable
|
|
||||||
this.settledrequestDatatable.row.add(rowData).draw();
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
alert(result.message);
|
alert(result.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.error("Error approving request:", error);
|
console.error("Error approving request:", error);
|
||||||
// alert("An error occurred while approving the request.");
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
$('#approveModal').modal('hide');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async rejectRequest() {
|
async rejectRequest() {
|
||||||
|
if (!this.rejectremark || this.rejectremark.trim() === "") {
|
||||||
|
alert("Please enter a remark before rejecting this request.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const formData = {
|
const formData = {
|
||||||
RemarkMasterInv: this.rejectremark,
|
RemarkMasterInv: this.rejectremark,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let requestID = this.currentrequestID;
|
let requestID = this.currentrequestID;
|
||||||
|
this.loading = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
const response = await fetch(`/InvMainAPI/RejectRequest/${requestID}`, {
|
const response = await fetch(`/InvMainAPI/RejectRequest/${requestID}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: { 'Content-Type': 'application/json' },
|
||||||
'Content-Type': 'application/json',
|
|
||||||
// 'Authorization': `Bearer ${this.token}`
|
|
||||||
},
|
|
||||||
body: JSON.stringify(formData)
|
body: JSON.stringify(formData)
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
// If the form submission was successful, display a success message
|
alert('Request has been Rejected.');
|
||||||
// alert('Success!', 'Request has been Rejected.', 'success');
|
this.rejectremark = "";
|
||||||
|
this.fetchRequest();
|
||||||
const row = $(`.approve-btn[data-id="${requestID}"]`).closest('tr');
|
|
||||||
let rowData = this.requestDatatable.row(row).data();
|
|
||||||
|
|
||||||
// Update the status and remark
|
|
||||||
rowData.status = "Rejected";
|
|
||||||
rowData.remarkMasterInv = this.rejectremark;
|
|
||||||
|
|
||||||
// Remove row from requestDatatable
|
|
||||||
this.requestDatatable.row(row).remove().draw();
|
|
||||||
|
|
||||||
// Add updated row to settledrequestDatatable
|
|
||||||
this.settledrequestDatatable.row.add(rowData).draw();
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Failed to submit form.');
|
throw new Error('Failed to submit form.');
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
|
|
||||||
// Displaying error message
|
|
||||||
alert('Inventory PSTW Error', `An error occurred: ${error.message}`, 'error');
|
alert('Inventory PSTW Error', `An error occurred: ${error.message}`, 'error');
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
$('#rejectModal').modal('hide');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async rejectRequestModal(requestID, remark) {
|
async rejectRequestModal(requestID, remark) {
|
||||||
|
|||||||
@ -280,8 +280,10 @@
|
|||||||
<button type="button" v-on:click="ReturnMessage" class="btn btn-warning m-2" style="width: 200px; padding: 10px;">
|
<button type="button" v-on:click="ReturnMessage" class="btn btn-warning m-2" style="width: 200px; padding: 10px;">
|
||||||
<i class="fas fa-undo me-2"></i>Return Item
|
<i class="fas fa-undo me-2"></i>Return Item
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button type="button" v-on:click="StationMessage" class="btn btn-primary m-2" style="width: 200px; padding: 10px;">
|
<button type="button" v-on:click="StationMessage" class="btn btn-primary m-2" style="width: 200px; padding: 10px;">
|
||||||
<i class="fas fa-broadcast-tower me-2"></i>Deploy To Station
|
<i class="fas fa-broadcast-tower me-2"></i>
|
||||||
|
{{ (thisItem?.currentStationId || thisItem?.toStationId) ? "Change Station" : "Deploy To Station" }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -353,11 +355,24 @@
|
|||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-sm-4 col-form-label">To User:</label>
|
<label class="col-sm-4 col-form-label">To User:</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<div class="dropdown">
|
<div class="custom-searchable-dropdown" style="position: relative;" @@click.stop>
|
||||||
<select class="btn btn-primary dropdown-toggle col-md-10" v-model="selectedUser" required style="width: 100%;">
|
<div class="input-group">
|
||||||
<option class="btn-light" value="" disabled selected>Select User</option>
|
<input type="text" class="form-control" v-model="userSearchQuery"
|
||||||
<option class="btn-light" v-for="(user, index) in userlist" :key="index" :value="user.id">{{user.fullName}}</option>
|
placeholder="Search and Select User..."
|
||||||
</select>
|
@@focus ="userDropdownOpen = true" />
|
||||||
|
<button type="button" class="btn btn-primary" @@click ="userDropdownOpen = !userDropdownOpen">
|
||||||
|
{{ userDropdownOpen ? '▲' : '▼' }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<ul class="list-group shadow-sm" v-if="userDropdownOpen" style="position: absolute; z-index: 1000; width: 100%; max-height: 200px; overflow-y: auto;">
|
||||||
|
<li class="list-group-item text-muted" v-if="searchedUserList.length === 0">No users found</li>
|
||||||
|
<li class="list-group-item list-group-item-action"
|
||||||
|
v-for="(user, index) in searchedUserList" :key="index"
|
||||||
|
@@click ="selectUser(user.id, user.fullName)"
|
||||||
|
style="cursor: pointer;">
|
||||||
|
{{ user.fullName }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -411,12 +426,24 @@
|
|||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-sm-4 col-form-label">To Station:</label>
|
<label class="col-sm-4 col-form-label">To Station:</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<div class="dropdown">
|
<div class="custom-searchable-dropdown" style="position: relative;" @@click.stop>
|
||||||
<select class="btn btn-primary dropdown-toggle col-md-10" v-model="selectedStation" required style="width: 100%;">
|
<div class="input-group">
|
||||||
<option class="btn-light" value="" disabled selected>Select Station</option>
|
<input type="text" class="form-control" v-model="stationSearchQuery"
|
||||||
<option class="btn-light" v-for="(station, index) in stationlist" :key="index" :value="station.stationId">{{station.stationName}}</option>
|
placeholder="Search and Select Station..."
|
||||||
</select>
|
@@focus ="stationDropdownOpen = true" />
|
||||||
|
<button type="button" class="btn btn-primary" @@click ="stationDropdownOpen = !stationDropdownOpen">
|
||||||
|
{{ stationDropdownOpen ? '▲' : '▼' }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<ul class="list-group shadow-sm" v-if="stationDropdownOpen" style="position: absolute; z-index: 1000; width: 100%; max-height: 200px; overflow-y: auto;">
|
||||||
|
<li class="list-group-item text-muted" v-if="searchedStationListForDropdown.length === 0">No stations found</li>
|
||||||
|
<li class="list-group-item list-group-item-action"
|
||||||
|
v-for="(station, index) in searchedStationListForDropdown" :key="index"
|
||||||
|
@@click ="selectStation(station.stationId, station.stationName)"
|
||||||
|
style="cursor: pointer;">
|
||||||
|
{{ station.stationName }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -538,11 +565,24 @@
|
|||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-sm-4 col-form-label">To Supplier:</label>
|
<label class="col-sm-4 col-form-label">To Supplier:</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<div class="dropdown">
|
<div class="custom-searchable-dropdown" style="position: relative;" @@click.stop>
|
||||||
<select class="btn btn-primary dropdown-toggle col-md-10" v-model="selectedSupplier" required style="width: 100%;">
|
<div class="input-group">
|
||||||
<option class="btn-light" value="" disabled selected>Select Supplier</option>
|
<input type="text" class="form-control" v-model="supplierSearchQuery"
|
||||||
<option class="btn-light" v-for="(supplier, index) in supplierlist" :key="index" :value="supplier.supplierCompName">{{supplier.supplierCompName}}</option>
|
placeholder="Search and Select Supplier..."
|
||||||
</select>
|
@@focus ="supplierDropdownOpen = true" />
|
||||||
|
<button type="button" class="btn btn-primary" @@click ="supplierDropdownOpen = !supplierDropdownOpen">
|
||||||
|
{{ supplierDropdownOpen ? '▲' : '▼' }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<ul class="list-group shadow-sm" v-if="supplierDropdownOpen" style="position: absolute; z-index: 1000; width: 100%; max-height: 200px; overflow-y: auto;">
|
||||||
|
<li class="list-group-item text-muted" v-if="searchedSupplierList.length === 0">No suppliers found</li>
|
||||||
|
<li class="list-group-item list-group-item-action"
|
||||||
|
v-for="(supplier, index) in searchedSupplierList" :key="index"
|
||||||
|
@@click ="selectSupplier(supplier.supplierCompName)"
|
||||||
|
style="cursor: pointer;">
|
||||||
|
{{ supplier.supplierCompName }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -664,7 +704,7 @@
|
|||||||
<div class="form-group row mb-3">
|
<div class="form-group row mb-3">
|
||||||
<label class="col-sm-4 col-form-label">Remark:</label>
|
<label class="col-sm-4 col-form-label">Remark:</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input type="text" class="form-control" v-model="remark" required />
|
<input type="text" class="form-control" v-model="remark"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mb-3">
|
<div class="form-group row mb-3">
|
||||||
@ -683,43 +723,51 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@* Model Deploy to Station *@
|
@* Model Deploy to Station *@
|
||||||
<div class="modal fade" id="stationMessageModal" tabindex="-1" role="dialog">
|
<div class="modal fade" id="stationMessageModal" tabindex="-1" role="dialog" aria-labelledby="stationModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h5 class="modal-title">Deploy to Station</h5>
|
<h5 class="modal-title" id="stationModalLabel">
|
||||||
<button type="button" class="close closeModal" data-dismiss="modal">
|
{{ (thisItem?.currentStationId || thisItem?.toStationId) ? "Change Station" : "Deploy to Station" }}
|
||||||
<span>×</span>
|
</h5>
|
||||||
|
<button type="button" class="close closeModal" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<form v-on:submit.prevent="confirmDeployStation">
|
<form v-on:submit.prevent="confirmDeployStation">
|
||||||
|
|
||||||
<div class="form-group row mb-3">
|
<div class="form-group row mb-3">
|
||||||
<label class="col-sm-4 col-form-label">Select Station:</label>
|
<label class="col-sm-4 col-form-label">Deploy Station : </label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<select class="form-select" v-model="selectedStation" required>
|
<select class="btn btn-primary dropdown-toggle col-md-10" v-model="selectedStation" required>
|
||||||
<option value="" disabled>-- Select Station --</option>
|
<option class="btn-light" value="" disabled selected>-- Select Station --</option>
|
||||||
<option v-for="station in filteredStationList" :key="station.stationId" :value="station.stationId">
|
<option v-if="filteredStationList.length === 0" class="btn-light" disabled>No Station Assigned to You</option>
|
||||||
|
<option class="btn-light" v-for="station in filteredStationList" :key="station.stationId" :value="station.stationId">
|
||||||
{{ station.stationName }}
|
{{ station.stationName }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group row mb-3">
|
<div class="form-group row mb-3">
|
||||||
<label class="col-sm-4 col-form-label">Remark:</label>
|
<label class="col-sm-4 col-form-label">Remark:</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input type="text" class="form-control" v-model="remark" placeholder="Optional" />
|
<input type="text" class="form-control" v-model="remark" placeholder="Optional" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group row mb-3">
|
<div class="form-group row mb-3">
|
||||||
<label class="col-sm-4 col-form-label">Consignment Note:</label>
|
<label class="col-sm-4 col-form-label">Consignment Note:</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input type="file" class="form-control-file" v-on:change="handleFileUpload" accept="image/*, application/pdf" />
|
<input type="file" class="form-control-file" v-on:change="handleFileUpload" accept="image/*, application/pdf" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center">
|
|
||||||
<button type="submit" class="btn btn-success">Confirm Deployment</button>
|
<button type="submit" class="btn btn-primary">
|
||||||
</div>
|
{{ (thisItem?.currentStationId || thisItem?.toStationId) ? "Confirm Change" : "Confirm Deployment" }}
|
||||||
|
</button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -794,7 +842,16 @@
|
|||||||
videoInputDevices: [],
|
videoInputDevices: [],
|
||||||
selectedCameraId: null,
|
selectedCameraId: null,
|
||||||
scanStartTime: null,
|
scanStartTime: null,
|
||||||
scanTime: null
|
scanTime: null,
|
||||||
|
|
||||||
|
supplierDropdownOpen: false,
|
||||||
|
supplierSearchQuery: "",
|
||||||
|
|
||||||
|
userDropdownOpen: false,
|
||||||
|
userSearchQuery: "",
|
||||||
|
|
||||||
|
stationDropdownOpen: false,
|
||||||
|
stationSearchQuery: "",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -875,6 +932,22 @@
|
|||||||
station.stationPicID == this.currentUser.id
|
station.stationPicID == this.currentUser.id
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
searchedUserList() {
|
||||||
|
if (!this.userlist) return [];
|
||||||
|
if (!this.userSearchQuery) return this.userlist;
|
||||||
|
return this.userlist.filter(u => u.fullName.toLowerCase().includes(this.userSearchQuery.toLowerCase()));
|
||||||
|
},
|
||||||
|
searchedSupplierList() {
|
||||||
|
if (!this.supplierlist) return [];
|
||||||
|
if (!this.supplierSearchQuery) return this.supplierlist;
|
||||||
|
return this.supplierlist.filter(s => s.supplierCompName.toLowerCase().includes(this.supplierSearchQuery.toLowerCase()));
|
||||||
|
},
|
||||||
|
searchedStationListForDropdown() {
|
||||||
|
if (!this.stationlist) return [];
|
||||||
|
if (!this.stationSearchQuery) return this.stationlist;
|
||||||
|
return this.stationlist.filter(s => s.stationName.toLowerCase().includes(this.stationSearchQuery.toLowerCase()));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// Split Url dapatkan unique ID Je
|
// Split Url dapatkan unique ID Je
|
||||||
@ -904,6 +977,27 @@
|
|||||||
this.error = message;
|
this.error = message;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
selectUser(userId, userName) {
|
||||||
|
this.selectedUser = userId;
|
||||||
|
this.userSearchQuery = userName;
|
||||||
|
this.userDropdownOpen = false;
|
||||||
|
},
|
||||||
|
selectSupplier(supplierName) {
|
||||||
|
this.selectedSupplier = supplierName;
|
||||||
|
this.supplierSearchQuery = supplierName;
|
||||||
|
this.supplierDropdownOpen = false;
|
||||||
|
},
|
||||||
|
selectStation(stationId, stationName) {
|
||||||
|
this.selectedStation = stationId;
|
||||||
|
this.stationSearchQuery = stationName;
|
||||||
|
this.stationDropdownOpen = false;
|
||||||
|
},
|
||||||
|
closeAllDropdowns() {
|
||||||
|
this.userDropdownOpen = false;
|
||||||
|
this.supplierDropdownOpen = false;
|
||||||
|
this.stationDropdownOpen = false;
|
||||||
|
},
|
||||||
|
|
||||||
//Setting Camera
|
//Setting Camera
|
||||||
async onCameraReady(videoElement) {
|
async onCameraReady(videoElement) {
|
||||||
|
|
||||||
@ -1189,8 +1283,8 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
this.resetForm();
|
this.resetScanner();
|
||||||
window.location.href = '/Inventory/InventoryMaster/ItemMovement';
|
// window.location.href = '/Inventory/InventoryMaster/ItemMovement';
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Failed to submit form.');
|
throw new Error('Failed to submit form.');
|
||||||
}
|
}
|
||||||
@ -1276,7 +1370,9 @@
|
|||||||
this.cancelRemark = "";
|
this.cancelRemark = "";
|
||||||
this.quantity = 1; // Reset quantity when the form is reset
|
this.quantity = 1; // Reset quantity when the form is reset
|
||||||
this.maxQuantity = null; // Clear maxQuantity on form reset
|
this.maxQuantity = null; // Clear maxQuantity on form reset
|
||||||
|
this.userSearchQuery = "";
|
||||||
|
this.supplierSearchQuery = "";
|
||||||
|
this.stationSearchQuery = "";
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1585,7 +1681,7 @@
|
|||||||
alert('Success! Item has been deployed to the station.');
|
alert('Success! Item has been deployed to the station.');
|
||||||
$('#stationMessageModal').modal('hide');
|
$('#stationMessageModal').modal('hide');
|
||||||
this.resetScanner();
|
this.resetScanner();
|
||||||
window.location.href = '/Inventory/InventoryMaster/ItemMovement';
|
// window.location.href = '/Inventory/InventoryMaster/ItemMovement';
|
||||||
} else {
|
} else {
|
||||||
const errorText = await response.text();
|
const errorText = await response.text();
|
||||||
throw new Error(errorText || 'Failed to deploy station.');
|
throw new Error(errorText || 'Failed to deploy station.');
|
||||||
|
|||||||
@ -963,6 +963,70 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
initAllTables() {
|
initAllTables() {
|
||||||
if (this.itemMovementNotCompleteDatatable) {
|
if (this.itemMovementNotCompleteDatatable) {
|
||||||
this.itemMovementNotCompleteDatatable.destroy();
|
this.itemMovementNotCompleteDatatable.destroy();
|
||||||
@ -974,55 +1038,39 @@
|
|||||||
this.assignStationDatatable.destroy();
|
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 notCompleteData = [];
|
||||||
let completeData = [];
|
let completeData = [];
|
||||||
let completeStationData = [];
|
let completeStationData = [];
|
||||||
|
|
||||||
latestMovements.forEach(movement => {
|
|
||||||
let filteredMovements = filterMovements([movement]);
|
|
||||||
|
|
||||||
if (filteredMovements.length > 0) {
|
let latestMovementsMap = {};
|
||||||
|
|
||||||
|
this.itemMovements.forEach(movement => {
|
||||||
|
let id = movement.uniqueID;
|
||||||
|
|
||||||
|
|
||||||
|
if (!latestMovementsMap[id] || latestMovementsMap[id].id < movement.id) {
|
||||||
|
latestMovementsMap[id] = movement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push ALL station history to the Assign Station table!
|
||||||
|
if (movement.movementComplete == 1 && (movement.action === "Assign" || movement.action === "Change" || movement.toStation !== null)) {
|
||||||
|
completeStationData.push(movement);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let latestMovements = Object.values(latestMovementsMap);
|
||||||
|
|
||||||
|
latestMovements.forEach(movement => {
|
||||||
|
let isReturned = movement.toOther === 'Return' && movement.movementComplete == 1;
|
||||||
|
let isReady = movement.latestStatus === 'Ready To Deploy' && movement.movementComplete == 1;
|
||||||
|
|
||||||
|
if (!isReturned && !isReady) {
|
||||||
if (movement.movementComplete == 0) {
|
if (movement.movementComplete == 0) {
|
||||||
notCompleteData.push(movement);
|
notCompleteData.push(movement);
|
||||||
} else if (movement.movementComplete == 1 && movement.action !== "Assign") {
|
} else if (movement.movementComplete == 1 && movement.action !== "Assign") {
|
||||||
completeData.push(movement);
|
completeData.push(movement);
|
||||||
} else {
|
|
||||||
completeStationData.push(movement);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1038,10 +1086,10 @@
|
|||||||
{ title: "Send Date", data: "sendDate", render: this.formatDate.bind(this) },
|
{ title: "Send Date", data: "sendDate", render: this.formatDate.bind(this) },
|
||||||
{ title: "Start Status", data: "toOther" },
|
{ title: "Start Status", data: "toOther" },
|
||||||
{ title: "From User", data: "lastUserName" },
|
{ title: "From User", data: "lastUserName" },
|
||||||
{ title: "Last User", data: "toUserName" },
|
|
||||||
{ title: "From Station", data: "lastStationName" },
|
{ title: "From Station", data: "lastStationName" },
|
||||||
{ title: "Last Station", data: "toStationName" },
|
|
||||||
{ title: "From Store", data: "lastStoreName" },
|
{ title: "From Store", data: "lastStoreName" },
|
||||||
|
{ title: "Last User", data: "toUserName" },
|
||||||
|
{ title: "Last Station", data: "toStationName" },
|
||||||
{ title: "Last Store", data: "toStoreName" },
|
{ title: "Last Store", data: "toStoreName" },
|
||||||
{ title: "Quantity", data: "quantity" },
|
{ title: "Quantity", data: "quantity" },
|
||||||
{ title: "Note", data: "consignmentNote", render: renderFile },
|
{ title: "Note", data: "consignmentNote", render: renderFile },
|
||||||
@ -1063,10 +1111,10 @@
|
|||||||
{ title: "Start Status", data: "toOther" },
|
{ title: "Start Status", data: "toOther" },
|
||||||
{ title: "Latest Status", data: "latestStatus" },
|
{ title: "Latest Status", data: "latestStatus" },
|
||||||
{ title: "From User", data: "lastUserName" },
|
{ title: "From User", data: "lastUserName" },
|
||||||
{ title: "Last User", data: "toUserName" },
|
|
||||||
{ title: "From Station", data: "lastStationName" },
|
{ title: "From Station", data: "lastStationName" },
|
||||||
{ title: "Last Station", data: "toStationName" },
|
|
||||||
{ title: "From Store", data: "lastStoreName" },
|
{ title: "From Store", data: "lastStoreName" },
|
||||||
|
{ title: "Last User", data: "toUserName" },
|
||||||
|
{ title: "Last Station", data: "toStationName" },
|
||||||
{ title: "Last Store", data: "toStoreName" },
|
{ title: "Last Store", data: "toStoreName" },
|
||||||
{ title: "Qty", data: "quantity" },
|
{ title: "Qty", data: "quantity" },
|
||||||
{ title: "Note", data: "consignmentNote", render: renderFile },
|
{ title: "Note", data: "consignmentNote", render: renderFile },
|
||||||
|
|||||||
@ -196,7 +196,7 @@
|
|||||||
<div class="form-group row d-flex align-items-center">
|
<div class="form-group row d-flex align-items-center">
|
||||||
<label class="col-sm-2 col-form-label">Quantity:</label>
|
<label class="col-sm-2 col-form-label">Quantity:</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input type="number" class="form-control" v-model="quantity" required />
|
<input type="number" class="form-control" v-model="quantity" min="1" required />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -114,7 +114,9 @@
|
|||||||
<div class="col-12 mb-3">
|
<div class="col-12 mb-3">
|
||||||
<p class="h5 fw-bold">
|
<p class="h5 fw-bold">
|
||||||
<i class="fas fa-user-tie me-2 text-secondary"></i>PIC:
|
<i class="fas fa-user-tie me-2 text-secondary"></i>PIC:
|
||||||
<span class="text-muted">{{ thisItem.currentUserFullName || thisItem.currentUser || 'N/A' }}</span>
|
<span class="text-muted">
|
||||||
|
{{ currentUser?.fullName || 'N/A' }}
|
||||||
|
</span>
|
||||||
@* <span class="text-muted">{{thisItem.currentUserFullName}}</span> *@
|
@* <span class="text-muted">{{thisItem.currentUserFullName}}</span> *@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -123,7 +125,7 @@
|
|||||||
<div class="col-12 mb-3">
|
<div class="col-12 mb-3">
|
||||||
<p class="h5 fw-bold">
|
<p class="h5 fw-bold">
|
||||||
<i class="fas fa-user-tie me-2 text-secondary"></i>Station:
|
<i class="fas fa-user-tie me-2 text-secondary"></i>Station:
|
||||||
<span class="text-muted">{{thisItem.currentStation || 'No Station Deploy (Self Assign)' }}</span>
|
<span class="text-muted">{{ thisItem.toStationName || 'No Station Deploy (Self Assign)' }}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -135,14 +137,25 @@
|
|||||||
<i class="fas fa-info-circle me-2"></i>Receiver Information
|
<i class="fas fa-info-circle me-2"></i>Receiver Information
|
||||||
</h5>
|
</h5>
|
||||||
<ul class="list-group list-group-flush">
|
<ul class="list-group list-group-flush">
|
||||||
<!-- User -->
|
|
||||||
<li class="list-group-item">
|
<li class="list-group-item" v-if="thisItem.toUser || thisItem.toUserFullName">
|
||||||
<div class="d-flex justify-content-between align-items-start">
|
<div class="d-flex justify-content-between align-items-start">
|
||||||
<span class="fw-bold">
|
<span class="fw-bold">
|
||||||
<i class="fas fa-user me-2 text-secondary"></i>User:
|
<i class="fas fa-user me-2 text-secondary"></i>User:
|
||||||
</span>
|
</span>
|
||||||
<span class="text-muted text-end" style="max-width: 70%; word-wrap: break-word;">
|
<span class="text-muted text-end" style="max-width: 70%; word-wrap: break-word;">
|
||||||
{{ thisItem.currentUserFullName || thisItem.currentUser || 'N/A' }}
|
{{ thisItem.toUserFullName || thisItem.toUserName || 'N/A' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="list-group-item" v-if="thisItem.toStationId || thisItem.toStation">
|
||||||
|
<div class="d-flex justify-content-between align-items-start">
|
||||||
|
<span class="fw-bold">
|
||||||
|
<i class="fas fa-charging-station me-2 text-secondary"></i>Station:
|
||||||
|
</span>
|
||||||
|
<span class="text-muted text-end">
|
||||||
|
{{ thisItem.toStationName || thisItem.toStation || 'N/A' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@ -159,13 +172,24 @@
|
|||||||
<i class="fas fa-info-circle me-2"></i>Sender Information
|
<i class="fas fa-info-circle me-2"></i>Sender Information
|
||||||
</h5>
|
</h5>
|
||||||
<ul class="list-group list-group-flush">
|
<ul class="list-group list-group-flush">
|
||||||
<!-- User -->
|
|
||||||
<li class="list-group-item">
|
<li class="list-group-item" v-if="thisItem.lastStation">
|
||||||
|
<div class="d-flex justify-content-between align-items-start">
|
||||||
|
<span class="fw-bold">
|
||||||
|
<i class="fas fa-charging-station me-2 text-secondary"></i>Station:
|
||||||
|
</span>
|
||||||
|
<span class="text-muted text-end">
|
||||||
|
{{ thisItem.currentStation || 'N/A' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="list-group-item" v-else-if="thisItem.lastUser">
|
||||||
<div class="d-flex justify-content-between align-items-start">
|
<div class="d-flex justify-content-between align-items-start">
|
||||||
<span class="fw-bold">
|
<span class="fw-bold">
|
||||||
<i class="fas fa-user me-2 text-secondary"></i>User:
|
<i class="fas fa-user me-2 text-secondary"></i>User:
|
||||||
</span>
|
</span>
|
||||||
<span class="text-muted text-end" style="max-width: 70%; word-wrap: break-word;">
|
<span class="text-muted text-end">
|
||||||
{{ thisItem.currentUserFullName || thisItem.currentUser || 'N/A' }}
|
{{ thisItem.currentUserFullName || thisItem.currentUser || 'N/A' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -480,7 +504,7 @@
|
|||||||
|
|
||||||
ToOther: "Delivered",
|
ToOther: "Delivered",
|
||||||
Action: "Assign",
|
Action: "Assign",
|
||||||
Quantity: this.thisItem.quantity || 1,
|
Quantity: this.thisItem.movementQuantity || 1,
|
||||||
Remark: this.remark,
|
Remark: this.remark,
|
||||||
ConsignmentNote: this.consignmentNote,
|
ConsignmentNote: this.consignmentNote,
|
||||||
SendDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
SendDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
|
|||||||
@ -50,7 +50,7 @@ namespace PSTW_CentralSystem.Controllers.API
|
|||||||
.Select(u => new
|
.Select(u => new
|
||||||
{
|
{
|
||||||
id = u.Id,
|
id = u.Id,
|
||||||
email = u.NormalizedEmail,
|
fullName = u.FullName,
|
||||||
company = u.Department!.Company!.CompanyName,
|
company = u.Department!.Company!.CompanyName,
|
||||||
department = u.Department,
|
department = u.Department,
|
||||||
role = userRole,
|
role = userRole,
|
||||||
|
|||||||
@ -970,6 +970,9 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
ToStoreName = item.Movement?.NextStore?.StoreName,
|
ToStoreName = item.Movement?.NextStore?.StoreName,
|
||||||
LastStation = item.Movement?.LastStation,
|
LastStation = item.Movement?.LastStation,
|
||||||
ToStationName = item.Movement?.NextStation?.StationName,
|
ToStationName = item.Movement?.NextStation?.StationName,
|
||||||
|
|
||||||
|
ToUserFullName = item.Movement?.NextUser?.FullName,
|
||||||
|
|
||||||
item.Movement?.ToOther,
|
item.Movement?.ToOther,
|
||||||
item.Movement?.LatestStatus,
|
item.Movement?.LatestStatus,
|
||||||
item.Movement?.ToUser,
|
item.Movement?.ToUser,
|
||||||
@ -1330,6 +1333,12 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
return NotFound("Item movement record not found.");
|
return NotFound("Item movement record not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fetch the StationIds where the user is the PIC
|
||||||
|
var userStationIds = await _centralDbContext.Stations
|
||||||
|
.Where(s => s.StationPicID == user.Id)
|
||||||
|
.Select(s => s.StationId)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
var itemMovementUser = await _centralDbContext.ItemMovements
|
var itemMovementUser = await _centralDbContext.ItemMovements
|
||||||
.Include(i => i.Item)
|
.Include(i => i.Item)
|
||||||
.ThenInclude(i => i.Product)
|
.ThenInclude(i => i.Product)
|
||||||
@ -1339,7 +1348,10 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
.Include(i => i.NextStore)
|
.Include(i => i.NextStore)
|
||||||
.Include(i => i.NextStation)
|
.Include(i => i.NextStation)
|
||||||
.Include(i => i.NextUser)
|
.Include(i => i.NextUser)
|
||||||
.Where(i => i.LastUser == user.Id || i.ToUser == user.Id)
|
.Where(i => i.LastUser == user.Id ||
|
||||||
|
i.ToUser == user.Id ||
|
||||||
|
(i.LastStation != null && userStationIds.Contains(i.LastStation.Value)) ||
|
||||||
|
(i.ToStation != null && userStationIds.Contains(i.ToStation.Value)))
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
return Json(itemMovementUser.Select(i => new
|
return Json(itemMovementUser.Select(i => new
|
||||||
@ -1377,7 +1389,6 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
{
|
{
|
||||||
return BadRequest(ex.Message);
|
return BadRequest(ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -1622,12 +1633,20 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
|
|
||||||
var masterDeptId = masterUser.departmentId;
|
var masterDeptId = masterUser.departmentId;
|
||||||
|
|
||||||
|
var myStoreIds = await _centralDbContext.InventoryMasters
|
||||||
|
.Where(im => im.UserId == currentUserId)
|
||||||
|
.Select(im => im.StoreId)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
// 4. Fetch requests where the Requester belongs to the same department
|
// 4. Fetch requests where the Requester belongs to the same department
|
||||||
var itemRequestList = await _centralDbContext.Requests
|
var itemRequestList = await _centralDbContext.Requests
|
||||||
.Include(i => i.Product)
|
.Include(i => i.Product)
|
||||||
.Include(i => i.User)
|
.Include(i => i.User)
|
||||||
.Include(i => i.Station)
|
.Include(i => i.Station)
|
||||||
.Where(i => i.User.departmentId == masterDeptId)
|
.Include(i => i.Store)
|
||||||
|
.Include(i => i.Stores)
|
||||||
|
.Where(i => i.User.departmentId == masterDeptId ||
|
||||||
|
(i.fromStoreItem.HasValue && myStoreIds.Contains(i.fromStoreItem.Value)))
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
return Json(itemRequestList.Select(i => new
|
return Json(itemRequestList.Select(i => new
|
||||||
@ -1649,7 +1668,9 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
i.remarkMasterInv,
|
i.remarkMasterInv,
|
||||||
i.remarkUser,
|
i.remarkUser,
|
||||||
i.assignStoreItem,
|
i.assignStoreItem,
|
||||||
i.fromStoreItem
|
i.fromStoreItem,
|
||||||
|
fromStoreName = i.Store?.StoreName ?? "N/A",
|
||||||
|
assignStoreName = i.Stores?.StoreName ?? "N/A",
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2113,6 +2134,18 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
stationMovement.ConsignmentNote = "/" + relativePath;
|
stationMovement.ConsignmentNote = "/" + relativePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close the previous active movement record
|
||||||
|
var currentItem = await _centralDbContext.Items.FindAsync(stationMovement.ItemId);
|
||||||
|
if (currentItem != null && currentItem.MovementId.HasValue)
|
||||||
|
{
|
||||||
|
var previousMovement = await _centralDbContext.ItemMovements.FindAsync(currentItem.MovementId.Value);
|
||||||
|
if (previousMovement != null)
|
||||||
|
{
|
||||||
|
previousMovement.MovementComplete = true; // Close the old history
|
||||||
|
_centralDbContext.ItemMovements.Update(previousMovement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_centralDbContext.ItemMovements.Add(stationMovement);
|
_centralDbContext.ItemMovements.Add(stationMovement);
|
||||||
await _centralDbContext.SaveChangesAsync();
|
await _centralDbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user