fix ui itemmovement admin
update product image
@ -660,69 +660,118 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
groupedByStation() {
|
groupedByStation() {
|
||||||
let grouped = {};
|
// let grouped = {};
|
||||||
this.items.forEach((movement) => {
|
// this.items.forEach((movement) => {
|
||||||
|
|
||||||
if (movement.toStation !== null) {
|
// if (movement.toStation !== null) {
|
||||||
let station = movement.toStationName;
|
// let station = movement.toStationName;
|
||||||
let itemId = movement.uniqueID;
|
// let itemId = movement.uniqueID;
|
||||||
|
|
||||||
if (!grouped[station]) {
|
// if (!grouped[station]) {
|
||||||
grouped[station] = {};
|
// grouped[station] = {};
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (!grouped[station][itemId]) {
|
// if (!grouped[station][itemId]) {
|
||||||
grouped[station][itemId] = { uniqueID: itemId, movements: [] };
|
// grouped[station][itemId] = { uniqueID: itemId, movements: [] };
|
||||||
}
|
// }
|
||||||
|
|
||||||
grouped[station][itemId].movements.push(movement);
|
// grouped[station][itemId].movements.push(movement);
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (movement.lastStation !== null) {
|
// if (movement.lastStation !== null) {
|
||||||
let station = movement.lastStationName;
|
// let station = movement.lastStationName;
|
||||||
let itemId = movement.uniqueID;
|
// let itemId = movement.uniqueID;
|
||||||
|
|
||||||
if (!grouped[station]) {
|
// if (!grouped[station]) {
|
||||||
grouped[station] = {};
|
// grouped[station] = {};
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (!grouped[station][itemId]) {
|
// if (!grouped[station][itemId]) {
|
||||||
grouped[station][itemId] = { uniqueID: itemId, movements: [] };
|
// grouped[station][itemId] = { uniqueID: itemId, movements: [] };
|
||||||
}
|
// }
|
||||||
|
|
||||||
grouped[station][itemId].movements.push(movement);
|
// grouped[station][itemId].movements.push(movement);
|
||||||
}
|
// }
|
||||||
if (movement.lastStation == null && movement.toStation == null) {
|
// if (movement.lastStation == null && movement.toStation == null) {
|
||||||
|
|
||||||
let station = "Self Assigned";
|
// let station = "Self Assigned";
|
||||||
let itemId = movement.uniqueID;
|
// let itemId = movement.uniqueID;
|
||||||
|
|
||||||
if (!grouped[station]) {
|
// if (!grouped[station]) {
|
||||||
grouped[station] = {};
|
// grouped[station] = {};
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (!grouped[station][itemId]) {
|
// if (!grouped[station][itemId]) {
|
||||||
grouped[station][itemId] = { uniqueID: itemId, movements: [] };
|
// 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
|
// Sort stations and move "Unassign Station" to the last position
|
||||||
let sortedKeys = Object.keys(grouped).sort((a, b) => {
|
// let sortedKeys = Object.keys(grouped).sort((a, b) => {
|
||||||
if (a === "Unassign Station") return 1;
|
// 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;
|
if (b === "Unassign Station") return -1;
|
||||||
return a.localeCompare(b);
|
return a.localeCompare(b);
|
||||||
});
|
});
|
||||||
|
|
||||||
let sortedGrouped = {};
|
let sortedGrouped = {};
|
||||||
sortedKeys.forEach((key) => {
|
sortedKeys.forEach((key) => {
|
||||||
sortedGrouped[key] = grouped[key];
|
sortedGrouped[key] = stationGrouped[key];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return sortedGrouped;
|
return sortedGrouped;
|
||||||
},
|
},
|
||||||
filteredItems() {
|
filteredItems() {
|
||||||
|
|||||||
@ -59,7 +59,7 @@
|
|||||||
@* <label class="col-sm-4 col-form-label hidden-label">Request Id</label> *@
|
@* <label class="col-sm-4 col-form-label hidden-label">Request Id</label> *@
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<div class="dropdown">
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -121,7 +121,7 @@
|
|||||||
@* <label class="col-sm-4 col-form-label hidden-label">Request Id</label> *@
|
@* <label class="col-sm-4 col-form-label hidden-label">Request Id</label> *@
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<div class="dropdown">
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -183,7 +183,7 @@
|
|||||||
const app = Vue.createApp({
|
const app = Vue.createApp({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
requestId : null,
|
requestID : null,
|
||||||
userId : null,
|
userId : null,
|
||||||
stationId : null,
|
stationId : null,
|
||||||
productId : null,
|
productId : null,
|
||||||
@ -206,7 +206,7 @@
|
|||||||
loading: false,
|
loading: false,
|
||||||
request: [],
|
request: [],
|
||||||
currentUser: null,
|
currentUser: null,
|
||||||
currentRequestId: "",
|
currentrequestID: "",
|
||||||
rejectremark: "",
|
rejectremark: "",
|
||||||
approveremark: "",
|
approveremark: "",
|
||||||
}
|
}
|
||||||
@ -289,16 +289,29 @@
|
|||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
"title": "Request ID",
|
"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",
|
"title": "Product Name",
|
||||||
"data": "productName",
|
"data": "productName",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "User ID",
|
"title": "Requested by User",
|
||||||
"data": "userName",
|
"data": "userName",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": "Requested by Station",
|
||||||
|
"data": "stationName",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "Product Category",
|
"title": "Product Category",
|
||||||
"data": "productCategory",
|
"data": "productCategory",
|
||||||
@ -356,24 +369,24 @@
|
|||||||
"title": "Approval Date",
|
"title": "Approval Date",
|
||||||
"data": "approvalDate",
|
"data": "approvalDate",
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
"title": "Reject",
|
// "title": "Reject",
|
||||||
"data" :"requestId",
|
// "data" :"requestID",
|
||||||
"render": function (data, type, row) {
|
// "render": function (data, type, row) {
|
||||||
var rejectButton = `<button type="button" class="btn btn-danger reject-btn" data-id="${data}">Reject</button>`;
|
// var rejectButton = `<button type="button" class="btn btn-danger reject-btn" data-id="${data}">Reject</button>`;
|
||||||
return rejectButton
|
// return rejectButton
|
||||||
},
|
// },
|
||||||
"className": "align-middle",
|
// "className": "align-middle",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
"title": "Approve",
|
// "title": "Approve",
|
||||||
"data": "requestId",
|
// "data": "requestID",
|
||||||
"render": function (data) {
|
// "render": function (data) {
|
||||||
var approveButton = `<button type="button" class="btn btn-success approve-btn" data-id="${data}">Approve</button>`;
|
// var approveButton = `<button type="button" class="btn btn-success approve-btn" data-id="${data}">Approve</button>`;
|
||||||
return approveButton;
|
// return approveButton;
|
||||||
},
|
// },
|
||||||
"className": "align-middle",
|
// "className": "align-middle",
|
||||||
}
|
// }
|
||||||
],
|
],
|
||||||
responsive: true,
|
responsive: true,
|
||||||
drawCallback: function (settings) {
|
drawCallback: function (settings) {
|
||||||
@ -381,10 +394,10 @@
|
|||||||
// const api = this.api();
|
// const api = this.api();
|
||||||
// api.rows().every(function () {
|
// api.rows().every(function () {
|
||||||
// const data = this.data(); Row data
|
// const data = this.data(); Row data
|
||||||
// const containerId = `qr${data.requestId}`;
|
// const containerId = `qr${data.requestID}`;
|
||||||
// const container = $(`#${containerId}`);
|
// const container = $(`#${containerId}`);
|
||||||
// container.empty();
|
// container.empty();
|
||||||
// container.append(`${data.requestId}`);
|
// container.append(`${data.requestID}`);
|
||||||
// console.log(container[0]);
|
// console.log(container[0]);
|
||||||
// if (container) {
|
// if (container) {
|
||||||
// Generate QR code only if not already generated
|
// Generate QR code only if not already generated
|
||||||
@ -409,16 +422,20 @@
|
|||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
"title": "Request ID",
|
"title": "Request ID",
|
||||||
"data": "requestId",
|
"data": "requestID",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Product Name",
|
"title": "Product Name",
|
||||||
"data": "productName",
|
"data": "productName",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "User ID",
|
"title": "Requested by User",
|
||||||
"data": "userName",
|
"data": "userName",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": "Requested by Station",
|
||||||
|
"data": "stationName",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "Product Category",
|
"title": "Product Category",
|
||||||
"data": "productCategory",
|
"data": "productCategory",
|
||||||
@ -481,7 +498,7 @@
|
|||||||
// "data" :null,
|
// "data" :null,
|
||||||
// "render": function (data, type, row) {
|
// "render": function (data, type, row) {
|
||||||
// return `<button type="button" class="btn btn-danger reject-btn"
|
// return `<button type="button" class="btn btn-danger reject-btn"
|
||||||
// data-id="${row.requestId}"
|
// data-id="${row.requestID}"
|
||||||
// data-remark="${row.remark || ''}">
|
// data-remark="${row.remark || ''}">
|
||||||
// Reject
|
// Reject
|
||||||
// </button>`;
|
// </button>`;
|
||||||
@ -490,7 +507,7 @@
|
|||||||
// },
|
// },
|
||||||
// {
|
// {
|
||||||
// "title": "Approve",
|
// "title": "Approve",
|
||||||
// "data": "requestId",
|
// "data": "requestID",
|
||||||
// "render": function (data) {
|
// "render": function (data) {
|
||||||
// var approveButton = `<button type="button" class="btn btn-success approve-btn" data-id="${data}">Approve</button>`;
|
// var approveButton = `<button type="button" class="btn btn-success approve-btn" data-id="${data}">Approve</button>`;
|
||||||
// return approveButton;
|
// return approveButton;
|
||||||
@ -506,13 +523,13 @@
|
|||||||
|
|
||||||
// Attach click event listener to the delete buttons
|
// Attach click event listener to the delete buttons
|
||||||
$('#requestDatatable tbody').on('click', '.reject-btn', function () {
|
$('#requestDatatable tbody').on('click', '.reject-btn', function () {
|
||||||
const requestId = $(this).data('id');
|
const requestID = $(this).data('id');
|
||||||
self.rejectRequestModal(requestId);
|
self.rejectRequestModal(requestID);
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#requestDatatable tbody').on('click', '.approve-btn', function () {
|
$('#requestDatatable tbody').on('click', '.approve-btn', function () {
|
||||||
const requestId = $(this).data('id');
|
const requestID = $(this).data('id');
|
||||||
self.approveRequestModal(requestId);
|
self.approveRequestModal(requestID);
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#requestDatatable tbody').on('click', '.print-btn', function () {
|
$('#requestDatatable tbody').on('click', '.print-btn', function () {
|
||||||
@ -740,9 +757,9 @@
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let requestId = this.currentRequestId;
|
let requestID = this.currentrequestID;
|
||||||
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',
|
||||||
@ -756,7 +773,7 @@
|
|||||||
alert(result.message);
|
alert(result.message);
|
||||||
|
|
||||||
//static update
|
//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();
|
let rowData = this.requestDatatable.row(row).data();
|
||||||
|
|
||||||
// Update the status and remark
|
// Update the status and remark
|
||||||
@ -789,11 +806,11 @@
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let requestId = this.currentRequestId;
|
let requestID = this.currentrequestID;
|
||||||
|
|
||||||
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',
|
||||||
@ -806,7 +823,7 @@
|
|||||||
// If the form submission was successful, display a success message
|
// If the form submission was successful, display a success message
|
||||||
// alert('Success!', 'Request has been Rejected.', 'success');
|
// 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();
|
let rowData = this.requestDatatable.row(row).data();
|
||||||
|
|
||||||
// Update the status and remark
|
// Update the status and remark
|
||||||
@ -834,9 +851,9 @@
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async rejectRequestModal(requestId, remark) {
|
async rejectRequestModal(requestID, remark) {
|
||||||
|
|
||||||
this.currentRequestId = requestId;
|
this.currentrequestID = requestID;
|
||||||
this.rejectremark = remark;
|
this.rejectremark = remark;
|
||||||
|
|
||||||
|
|
||||||
@ -844,9 +861,9 @@
|
|||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
async approveRequestModal(requestId, remark) {
|
async approveRequestModal(requestID, remark) {
|
||||||
|
|
||||||
this.currentRequestId = requestId;
|
this.currentrequestID = requestID;
|
||||||
this.approveremark = remark;
|
this.approveremark = remark;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -981,15 +981,17 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
public async Task<IActionResult> ItemRequestList()
|
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
|
return Json(itemRequestList.Select(i => new
|
||||||
{
|
{
|
||||||
i.requestID,
|
i.requestID,
|
||||||
productName = i.Product?.ProductName,
|
productName = i.Product?.ProductName,
|
||||||
i.ProductId,
|
i.ProductId,
|
||||||
|
productImage = i.Product?.ImageProduct,
|
||||||
userName = i.User?.FullName,
|
userName = i.User?.FullName,
|
||||||
i.status,
|
i.status,
|
||||||
i.StationId,
|
i.StationId,
|
||||||
|
stationName = i.Station?.StationName,
|
||||||
i.RequestQuantity,
|
i.RequestQuantity,
|
||||||
i.requestDate,
|
i.requestDate,
|
||||||
i.ProductCategory,
|
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 |