fix ui itemmovement admin
update product image
@ -660,69 +660,118 @@
|
||||
},
|
||||
|
||||
groupedByStation() {
|
||||
let grouped = {};
|
||||
this.items.forEach((movement) => {
|
||||
// let grouped = {};
|
||||
// this.items.forEach((movement) => {
|
||||
|
||||
if (movement.toStation !== null) {
|
||||
let station = movement.toStationName;
|
||||
let itemId = movement.uniqueID;
|
||||
// if (movement.toStation !== null) {
|
||||
// let station = movement.toStationName;
|
||||
// let itemId = movement.uniqueID;
|
||||
|
||||
if (!grouped[station]) {
|
||||
grouped[station] = {};
|
||||
}
|
||||
// if (!grouped[station]) {
|
||||
// grouped[station] = {};
|
||||
// }
|
||||
|
||||
if (!grouped[station][itemId]) {
|
||||
grouped[station][itemId] = { uniqueID: itemId, movements: [] };
|
||||
}
|
||||
// if (!grouped[station][itemId]) {
|
||||
// grouped[station][itemId] = { uniqueID: itemId, movements: [] };
|
||||
// }
|
||||
|
||||
grouped[station][itemId].movements.push(movement);
|
||||
}
|
||||
// grouped[station][itemId].movements.push(movement);
|
||||
// }
|
||||
|
||||
if (movement.lastStation !== null) {
|
||||
let station = movement.lastStationName;
|
||||
let itemId = movement.uniqueID;
|
||||
// if (movement.lastStation !== null) {
|
||||
// let station = movement.lastStationName;
|
||||
// let itemId = movement.uniqueID;
|
||||
|
||||
if (!grouped[station]) {
|
||||
grouped[station] = {};
|
||||
}
|
||||
// if (!grouped[station]) {
|
||||
// grouped[station] = {};
|
||||
// }
|
||||
|
||||
if (!grouped[station][itemId]) {
|
||||
grouped[station][itemId] = { uniqueID: itemId, movements: [] };
|
||||
}
|
||||
// if (!grouped[station][itemId]) {
|
||||
// grouped[station][itemId] = { uniqueID: itemId, movements: [] };
|
||||
// }
|
||||
|
||||
grouped[station][itemId].movements.push(movement);
|
||||
}
|
||||
if (movement.lastStation == null && movement.toStation == null) {
|
||||
// grouped[station][itemId].movements.push(movement);
|
||||
// }
|
||||
// if (movement.lastStation == null && movement.toStation == null) {
|
||||
|
||||
let station = "Self Assigned";
|
||||
let itemId = movement.uniqueID;
|
||||
// let station = "Self Assigned";
|
||||
// let itemId = movement.uniqueID;
|
||||
|
||||
if (!grouped[station]) {
|
||||
grouped[station] = {};
|
||||
}
|
||||
// if (!grouped[station]) {
|
||||
// grouped[station] = {};
|
||||
// }
|
||||
|
||||
if (!grouped[station][itemId]) {
|
||||
grouped[station][itemId] = { uniqueID: itemId, movements: [] };
|
||||
}
|
||||
// if (!grouped[station][itemId]) {
|
||||
// grouped[station][itemId] = { uniqueID: itemId, movements: [] };
|
||||
// }
|
||||
|
||||
grouped[station][itemId].movements.push(movement);
|
||||
}
|
||||
// grouped[station][itemId].movements.push(movement);
|
||||
// }
|
||||
|
||||
});
|
||||
// });
|
||||
|
||||
// Sort stations and move "Unassign Station" to the last position
|
||||
let sortedKeys = Object.keys(grouped).sort((a, b) => {
|
||||
if (a === "Unassign Station") return 1;
|
||||
// let sortedKeys = Object.keys(grouped).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] = grouped[key];
|
||||
// });
|
||||
|
||||
|
||||
// return sortedGrouped;
|
||||
|
||||
let grouped = {};
|
||||
|
||||
// Process each movement and store only the latest assigned station
|
||||
this.items.forEach((movement) => {
|
||||
let station = null;
|
||||
|
||||
if (movement.lastStation !== null) {
|
||||
station = movement.lastStationName; // Latest assigned station
|
||||
} else if (movement.toStation !== null) {
|
||||
station = movement.toStationName; // If no new station, use last known station
|
||||
} else {
|
||||
station = "Self Assigned"; // No station history
|
||||
}
|
||||
|
||||
let itemId = movement.uniqueID;
|
||||
|
||||
// Ensure only the latest assigned station keeps the item
|
||||
if (!grouped[itemId]) {
|
||||
grouped[itemId] = { uniqueID: itemId, station: station, movements: [] };
|
||||
}
|
||||
|
||||
// Always update the latest station for this item
|
||||
grouped[itemId].station = station;
|
||||
grouped[itemId].movements.push(movement);
|
||||
});
|
||||
|
||||
// Convert to station-based grouping
|
||||
let stationGrouped = {};
|
||||
Object.values(grouped).forEach(({ uniqueID, station, movements }) => {
|
||||
if (!stationGrouped[station]) {
|
||||
stationGrouped[station] = {};
|
||||
}
|
||||
stationGrouped[station][uniqueID] = { uniqueID, movements };
|
||||
});
|
||||
|
||||
// Sort stations and move "Unassign Station" last
|
||||
let sortedKeys = Object.keys(stationGrouped).sort((a, b) => {
|
||||
if (a === "Unassign Station") return 1;
|
||||
if (b === "Unassign Station") return -1;
|
||||
return a.localeCompare(b);
|
||||
return a.localeCompare(b);
|
||||
});
|
||||
|
||||
let sortedGrouped = {};
|
||||
sortedKeys.forEach((key) => {
|
||||
sortedGrouped[key] = grouped[key];
|
||||
sortedGrouped[key] = stationGrouped[key];
|
||||
});
|
||||
|
||||
|
||||
return sortedGrouped;
|
||||
},
|
||||
filteredItems() {
|
||||
|
||||
@ -59,7 +59,7 @@
|
||||
@* <label class="col-sm-4 col-form-label hidden-label">Request Id</label> *@
|
||||
<div class="col-sm-8">
|
||||
<div class="dropdown">
|
||||
<input type="text" id="currentRequestId" name="currentRequestId" v-model="currentRequestId" class="form-control" hidden />
|
||||
<input type="text" id="currentrequestID" name="currentrequestID" v-model="currentrequestID" class="form-control" hidden />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -121,7 +121,7 @@
|
||||
@* <label class="col-sm-4 col-form-label hidden-label">Request Id</label> *@
|
||||
<div class="col-sm-8">
|
||||
<div class="dropdown">
|
||||
<input type="text" id="currentRequestId" name="currentRequestId" v-model="currentRequestId" class="form-control" hidden />
|
||||
<input type="text" id="currentrequestID" name="currentrequestID" v-model="currentrequestID" class="form-control" hidden />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -183,7 +183,7 @@
|
||||
const app = Vue.createApp({
|
||||
data() {
|
||||
return {
|
||||
requestId : null,
|
||||
requestID : null,
|
||||
userId : null,
|
||||
stationId : null,
|
||||
productId : null,
|
||||
@ -206,7 +206,7 @@
|
||||
loading: false,
|
||||
request: [],
|
||||
currentUser: null,
|
||||
currentRequestId: "",
|
||||
currentrequestID: "",
|
||||
rejectremark: "",
|
||||
approveremark: "",
|
||||
}
|
||||
@ -289,16 +289,29 @@
|
||||
"columns": [
|
||||
{
|
||||
"title": "Request ID",
|
||||
"data": "requestId",
|
||||
"data": "requestID",
|
||||
},
|
||||
{
|
||||
"title": "Action",
|
||||
"data" :"requestID",
|
||||
"render": function (data, type, row) {
|
||||
var actiontButtons = `<div class="row" style="padding: 5px;"> <button type="button" class="btn btn-success approve-btn" data-id="${data}">Approve</button></div> <div class="row" style="padding: 5px;"><button type="button" class="btn btn-danger reject-btn" data-id="${data}">Reject</button></div>`;
|
||||
return actiontButtons
|
||||
},
|
||||
"className": "align-middle",
|
||||
},
|
||||
{
|
||||
"title": "Product Name",
|
||||
"data": "productName",
|
||||
},
|
||||
{
|
||||
"title": "User ID",
|
||||
"title": "Requested by User",
|
||||
"data": "userName",
|
||||
},
|
||||
{
|
||||
"title": "Requested by Station",
|
||||
"data": "stationName",
|
||||
},
|
||||
{
|
||||
"title": "Product Category",
|
||||
"data": "productCategory",
|
||||
@ -356,24 +369,24 @@
|
||||
"title": "Approval Date",
|
||||
"data": "approvalDate",
|
||||
},
|
||||
{
|
||||
"title": "Reject",
|
||||
"data" :"requestId",
|
||||
"render": function (data, type, row) {
|
||||
var rejectButton = `<button type="button" class="btn btn-danger reject-btn" data-id="${data}">Reject</button>`;
|
||||
return rejectButton
|
||||
},
|
||||
"className": "align-middle",
|
||||
},
|
||||
{
|
||||
"title": "Approve",
|
||||
"data": "requestId",
|
||||
"render": function (data) {
|
||||
var approveButton = `<button type="button" class="btn btn-success approve-btn" data-id="${data}">Approve</button>`;
|
||||
return approveButton;
|
||||
},
|
||||
"className": "align-middle",
|
||||
}
|
||||
// {
|
||||
// "title": "Reject",
|
||||
// "data" :"requestID",
|
||||
// "render": function (data, type, row) {
|
||||
// var rejectButton = `<button type="button" class="btn btn-danger reject-btn" data-id="${data}">Reject</button>`;
|
||||
// return rejectButton
|
||||
// },
|
||||
// "className": "align-middle",
|
||||
// },
|
||||
// {
|
||||
// "title": "Approve",
|
||||
// "data": "requestID",
|
||||
// "render": function (data) {
|
||||
// var approveButton = `<button type="button" class="btn btn-success approve-btn" data-id="${data}">Approve</button>`;
|
||||
// return approveButton;
|
||||
// },
|
||||
// "className": "align-middle",
|
||||
// }
|
||||
],
|
||||
responsive: true,
|
||||
drawCallback: function (settings) {
|
||||
@ -381,10 +394,10 @@
|
||||
// const api = this.api();
|
||||
// api.rows().every(function () {
|
||||
// const data = this.data(); Row data
|
||||
// const containerId = `qr${data.requestId}`;
|
||||
// const containerId = `qr${data.requestID}`;
|
||||
// const container = $(`#${containerId}`);
|
||||
// container.empty();
|
||||
// container.append(`${data.requestId}`);
|
||||
// container.append(`${data.requestID}`);
|
||||
// console.log(container[0]);
|
||||
// if (container) {
|
||||
// Generate QR code only if not already generated
|
||||
@ -409,16 +422,20 @@
|
||||
"columns": [
|
||||
{
|
||||
"title": "Request ID",
|
||||
"data": "requestId",
|
||||
"data": "requestID",
|
||||
},
|
||||
{
|
||||
"title": "Product Name",
|
||||
"data": "productName",
|
||||
},
|
||||
{
|
||||
"title": "User ID",
|
||||
"title": "Requested by User",
|
||||
"data": "userName",
|
||||
},
|
||||
{
|
||||
"title": "Requested by Station",
|
||||
"data": "stationName",
|
||||
},
|
||||
{
|
||||
"title": "Product Category",
|
||||
"data": "productCategory",
|
||||
@ -481,7 +498,7 @@
|
||||
// "data" :null,
|
||||
// "render": function (data, type, row) {
|
||||
// return `<button type="button" class="btn btn-danger reject-btn"
|
||||
// data-id="${row.requestId}"
|
||||
// data-id="${row.requestID}"
|
||||
// data-remark="${row.remark || ''}">
|
||||
// Reject
|
||||
// </button>`;
|
||||
@ -490,7 +507,7 @@
|
||||
// },
|
||||
// {
|
||||
// "title": "Approve",
|
||||
// "data": "requestId",
|
||||
// "data": "requestID",
|
||||
// "render": function (data) {
|
||||
// var approveButton = `<button type="button" class="btn btn-success approve-btn" data-id="${data}">Approve</button>`;
|
||||
// return approveButton;
|
||||
@ -506,13 +523,13 @@
|
||||
|
||||
// Attach click event listener to the delete buttons
|
||||
$('#requestDatatable tbody').on('click', '.reject-btn', function () {
|
||||
const requestId = $(this).data('id');
|
||||
self.rejectRequestModal(requestId);
|
||||
const requestID = $(this).data('id');
|
||||
self.rejectRequestModal(requestID);
|
||||
});
|
||||
|
||||
$('#requestDatatable tbody').on('click', '.approve-btn', function () {
|
||||
const requestId = $(this).data('id');
|
||||
self.approveRequestModal(requestId);
|
||||
const requestID = $(this).data('id');
|
||||
self.approveRequestModal(requestID);
|
||||
});
|
||||
|
||||
$('#requestDatatable tbody').on('click', '.print-btn', function () {
|
||||
@ -740,9 +757,9 @@
|
||||
|
||||
};
|
||||
|
||||
let requestId = this.currentRequestId;
|
||||
let requestID = this.currentrequestID;
|
||||
try {
|
||||
const response = await fetch(`/InvMainAPI/ApproveRequest/${requestId}`, {
|
||||
const response = await fetch(`/InvMainAPI/ApproveRequest/${requestID}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@ -756,7 +773,7 @@
|
||||
alert(result.message);
|
||||
|
||||
//static update
|
||||
const row = $(`.approve-btn[data-id="${requestId}"]`).closest('tr');
|
||||
const row = $(`.approve-btn[data-id="${requestID}"]`).closest('tr');
|
||||
let rowData = this.requestDatatable.row(row).data();
|
||||
|
||||
// Update the status and remark
|
||||
@ -789,11 +806,11 @@
|
||||
|
||||
};
|
||||
|
||||
let requestId = this.currentRequestId;
|
||||
let requestID = this.currentrequestID;
|
||||
|
||||
try {
|
||||
|
||||
const response = await fetch(`/InvMainAPI/RejectRequest/${requestId}`, {
|
||||
const response = await fetch(`/InvMainAPI/RejectRequest/${requestID}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@ -806,7 +823,7 @@
|
||||
// If the form submission was successful, display a success message
|
||||
// alert('Success!', 'Request has been Rejected.', 'success');
|
||||
|
||||
const row = $(`.approve-btn[data-id="${requestId}"]`).closest('tr');
|
||||
const row = $(`.approve-btn[data-id="${requestID}"]`).closest('tr');
|
||||
let rowData = this.requestDatatable.row(row).data();
|
||||
|
||||
// Update the status and remark
|
||||
@ -834,9 +851,9 @@
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
async rejectRequestModal(requestId, remark) {
|
||||
async rejectRequestModal(requestID, remark) {
|
||||
|
||||
this.currentRequestId = requestId;
|
||||
this.currentrequestID = requestID;
|
||||
this.rejectremark = remark;
|
||||
|
||||
|
||||
@ -844,9 +861,9 @@
|
||||
|
||||
|
||||
},
|
||||
async approveRequestModal(requestId, remark) {
|
||||
async approveRequestModal(requestID, remark) {
|
||||
|
||||
this.currentRequestId = requestId;
|
||||
this.currentrequestID = requestID;
|
||||
this.approveremark = remark;
|
||||
|
||||
|
||||
|
||||
@ -981,15 +981,17 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
||||
public async Task<IActionResult> ItemRequestList()
|
||||
{
|
||||
|
||||
var itemRequestList = await _centralDbContext.Requests.Include(i => i.Product).Include(i => i.User).ToListAsync();
|
||||
var itemRequestList = await _centralDbContext.Requests.Include(i => i.Product).Include(i => i.User).Include(i => i.Station).ToListAsync();
|
||||
return Json(itemRequestList.Select(i => new
|
||||
{
|
||||
i.requestID,
|
||||
productName = i.Product?.ProductName,
|
||||
i.ProductId,
|
||||
productImage = i.Product?.ImageProduct,
|
||||
userName = i.User?.FullName,
|
||||
i.status,
|
||||
i.StationId,
|
||||
stationName = i.Station?.StationName,
|
||||
i.RequestQuantity,
|
||||
i.requestDate,
|
||||
i.ProductCategory,
|
||||
|
||||
BIN
wwwroot/Media/Inventory/Images/101780-00.jpg
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
wwwroot/Media/Inventory/Images/1405A233741512.jpg
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
wwwroot/Media/Inventory/Images/43i.png
Normal file
|
After Width: | Height: | Size: 118 KiB |
BIN
wwwroot/Media/Inventory/Images/599502-00.jpg
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
wwwroot/Media/Inventory/Images/CM15480140.jpg
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
wwwroot/Media/Inventory/Images/Latitude 7410.jpg
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
wwwroot/Media/Inventory/Images/Latitude 7410i.jpg
Normal file
|
After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 980 KiB |
BIN
wwwroot/Media/Inventory/Images/TEOM-1405DF.jpg
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
wwwroot/Media/Inventory/Images/i117.jpg
Normal file
|
After Width: | Height: | Size: 26 KiB |