Compare commits
No commits in common. "eab793195191fd2e2d39328b2280a1b0dbddf7b4" and "8d3385f6736674262e260b387eeb31b25a3e95c1" have entirely different histories.
eab7931951
...
8d3385f673
@ -1162,13 +1162,11 @@
|
|||||||
{ 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)}`; } },
|
||||||
{ title: "Product Code", data: "uniqueID" },
|
{ title: "Product Code", data: "uniqueID" },
|
||||||
{ 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: "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 Store", data: "toStoreName" },
|
|
||||||
{ title: "Start Status", data: "toOther" },
|
{ title: "Start Status", data: "toOther" },
|
||||||
{ title: "Product Category", data: "productCategory" },
|
{ title: "Product Category", data: "productCategory" },
|
||||||
{ title: "Qty", data: "quantity" },
|
{ title: "Qty", data: "quantity" },
|
||||||
|
|||||||
@ -97,37 +97,6 @@
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="card shadow-sm border-0">
|
<div class="card shadow-sm border-0">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title mb-4 text-primary">
|
|
||||||
<i class="fas fa-info-circle me-2"></i>Current Information
|
|
||||||
</h5>
|
|
||||||
<ul class="list-group list-group-flush">
|
|
||||||
<li class="list-group-item">
|
|
||||||
<div class="d-flex justify-content-between align-items-start">
|
|
||||||
<span class="fw-bold">
|
|
||||||
<i class="fas fa-user me-2 text-secondary"></i>User:
|
|
||||||
</span>
|
|
||||||
<span class="text-muted text-end" style="max-width: 70%; word-wrap: break-word;">
|
|
||||||
{{ thisItem.currentUserFullName || thisItem.currentUser || 'N/A' }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
|
||||||
<span class="fw-bold">
|
|
||||||
<i class="mdi mdi-factory me-2 text-secondary"></i>Store:
|
|
||||||
</span>
|
|
||||||
<span class="text-muted">{{ thisItem.currentStore || 'N/A' }}</span>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
|
||||||
<span class="fw-bold">
|
|
||||||
<i class="fas fa-map-marker-alt me-2 text-secondary"></i>Station:
|
|
||||||
</span>
|
|
||||||
<span class="text-muted">{{ thisItem.currentStation || 'N/A' }}</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
@* <div class="card-body">
|
|
||||||
<h5 class="card-title mb-4 text-primary">
|
<h5 class="card-title mb-4 text-primary">
|
||||||
<i class="fas fa-info-circle me-2"></i>Current Information
|
<i class="fas fa-info-circle me-2"></i>Current Information
|
||||||
</h5>
|
</h5>
|
||||||
@ -157,7 +126,7 @@
|
|||||||
<span class="text-muted">{{ thisItem.lastStationName || 'N/A' }}</span>
|
<span class="text-muted">{{ thisItem.lastStationName || 'N/A' }}</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div> *@
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -196,7 +165,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="itemlateststatus == 'On Delivery' && (this.thisItem.lastUser == this.currentUser.id || this.thisItem.lastStore == this.currentUser.store)">
|
<div v-if="itemlateststatus == 'On Delivery' && this.thisItem.lastUser == this.currentUser.id">
|
||||||
<h3 class="register-heading">Cancel Item Movement</h3>
|
<h3 class="register-heading">Cancel Item Movement</h3>
|
||||||
<div class="col-sm-3"></div>
|
<div class="col-sm-3"></div>
|
||||||
<div class="col-sm-6 offset-sm-3">
|
<div class="col-sm-6 offset-sm-3">
|
||||||
@ -225,23 +194,7 @@
|
|||||||
|
|
||||||
<div style="display: flex; justify-content: center; margin-top: 20px;">
|
<div style="display: flex; justify-content: center; margin-top: 20px;">
|
||||||
<button type="submit" class="btn btn-primary" style="width: 200px; padding: 10px; font-size: 16px;">
|
<button type="submit" class="btn btn-primary" style="width: 200px; padding: 10px; font-size: 16px;">
|
||||||
Receive Item for Store
|
Receive Item
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="itemlateststatus == 'On Delivery' && isStationPIC">
|
|
||||||
<h2 class="register-heading">Receive Item</h2>
|
|
||||||
<div class="col-sm-3"></div>
|
|
||||||
<div class="col-sm-6 offset-sm-3">
|
|
||||||
<form v-on:submit.prevent="receiveItemMovement" data-aos="fade-right">
|
|
||||||
<div class="row register-form">
|
|
||||||
<div style="display: flex; justify-content: center; margin-top: 20px;">
|
|
||||||
<button type="submit" class="btn btn-primary" style="width: 200px; padding: 10px; font-size: 16px;">
|
|
||||||
Receive for Station
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -274,7 +227,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@* Inv Master Return Item & Deploy to Station*@
|
@* Inv Master Return Item & Deploy to Station*@
|
||||||
<div v-if="itemlateststatus == 'Delivered' && (this.thisItem.toUser == this.currentUser.id || this.thisItem.toStore == this.currentUser.store || this.isStationPIC )">
|
<div v-if="itemlateststatus == 'Delivered' && thisItem.toUser == currentUser.id">
|
||||||
<h2 class="text-center register-heading">Item Actions</h2>
|
<h2 class="text-center register-heading">Item Actions</h2>
|
||||||
<div class="col-sm-12 d-flex justify-content-center mt-3">
|
<div class="col-sm-12 d-flex justify-content-center mt-3">
|
||||||
<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;">
|
||||||
@ -864,17 +817,6 @@
|
|||||||
return isPIC;
|
return isPIC;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
isStationPIC() {
|
|
||||||
if (!this.thisItem || !this.stationlist || !this.currentUser) return false;
|
|
||||||
|
|
||||||
// Now this.thisItem.toStation will have the ID from the backend
|
|
||||||
const targetStationId = this.thisItem.toStation;
|
|
||||||
|
|
||||||
return this.stationlist.some(station =>
|
|
||||||
station.stationId == targetStationId &&
|
|
||||||
station.stationPicID == this.currentUser.id
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// Split Url dapatkan unique ID Je
|
// Split Url dapatkan unique ID Je
|
||||||
@ -996,24 +938,24 @@
|
|||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
resetScanner(){
|
resetScanner(){
|
||||||
this.thisItem = null;
|
this.thisItem = null;
|
||||||
this.resetForm();
|
this.resetForm();
|
||||||
},
|
},
|
||||||
handleFileUpload(event) {
|
handleFileUpload(event) {
|
||||||
const file = event.target.files[0];
|
const file = event.target.files[0];
|
||||||
|
|
||||||
if (file) {
|
if (file) {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = (e) => {
|
reader.onload = (e) => {
|
||||||
this.document = e.target.result.split(',')[1]; // Get Base64 string (remove metadata)
|
this.document = e.target.result.split(',')[1]; // Get Base64 string (remove metadata)
|
||||||
};
|
};
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
} else {
|
} else {
|
||||||
this.document = null;
|
this.document = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async addItemMovement() {
|
async addItemMovement() {
|
||||||
// Client-side validation for quantity
|
// Client-side validation for quantity
|
||||||
if (this.thisItem && this.thisItem.category === "Disposable" && this.quantity > this.thisItem.quantity) {
|
if (this.thisItem && this.thisItem.category === "Disposable" && this.quantity > this.thisItem.quantity) {
|
||||||
alert('Error!', `The quantity you entered (${this.quantity}) exceeds the available stock (${this.thisItem.quantity}). Please enter a quantity less than or equal to the available stock.`, 'error');
|
alert('Error!', `The quantity you entered (${this.quantity}) exceeds the available stock (${this.thisItem.quantity}). Please enter a quantity less than or equal to the available stock.`, 'error');
|
||||||
@ -1031,57 +973,20 @@
|
|||||||
const now = new Date();
|
const now = new Date();
|
||||||
const formData = {
|
const formData = {
|
||||||
|
|
||||||
...(this.selectedAction === 'user' ? {
|
...(this.selectedAction === 'user' ? { lastStore: this.currentUser.store, lastUser: this.currentUser.id, toOther: 'On Delivery', SendDate: this.assigndate, toUser: this.selectedUser, MovementComplete: false, Remark: this.remark, ConsignmentNote: this.document} : {}),
|
||||||
lastStore: null,
|
|
||||||
lastUser: this.currentUser.id,
|
|
||||||
toOther: 'On Delivery',
|
|
||||||
SendDate: this.assigndate,
|
|
||||||
toUser: this.selectedUser,
|
|
||||||
MovementComplete: false,
|
|
||||||
Remark: this.remark,
|
|
||||||
ConsignmentNote: this.document} : {}),
|
|
||||||
|
|
||||||
...(this.selectedAction === 'station' ? {
|
...(this.selectedAction === 'station' ? {
|
||||||
lastStore: this.currentUser.store,
|
lastStore: this.currentUser.store,
|
||||||
lastUser: this.currentUser.id,
|
lastUser: this.currentUser.id,
|
||||||
toOther: 'On Delivery',
|
toOther: 'On Delivery',
|
||||||
SendDate: this.assigndate,
|
SendDate: this.assigndate,
|
||||||
toStation: this.selectedStation,
|
toStation: this.selectedStation,
|
||||||
|
toUser: this.selectedStationPIC,
|
||||||
MovementComplete: false,
|
MovementComplete: false,
|
||||||
Remark: this.remark,
|
Remark: this.remark,
|
||||||
ConsignmentNote: this.document} : {}),
|
ConsignmentNote: this.document} : {}),
|
||||||
|
...(this.selectedAction === 'store' ? { lastStore: this.currentUser.store, lastUser: this.currentUser.id, toOther: 'On Delivery', SendDate: this.assigndate, toStore: this.selectedStore, MovementComplete: false, Remark: this.remark, ConsignmentNote: this.document} : {}),
|
||||||
...(this.selectedAction === 'store' ? {
|
...(this.selectedAction === 'supplier' ? { lastStore: this.currentUser.store, lastUser: this.currentUser.id, toOther: this.selectedOther, SendDate: this.assigndate, Remark: this.remark + '. Item sent to ' + this.selectedSupplier + ' for ' + this.selectedOther, ConsignmentNote: this.document, toUser: this.currentUser.id, toStore: this.currentUser.store, MovementComplete: false, } : {}),
|
||||||
lastStore: this.currentUser.store,
|
...(this.selectedAction === 'faulty' ? { lastStore: this.currentUser.store, lastUser: this.currentUser.id,toOther: 'Faulty', SendDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(), ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(), Remark: this.remark, ConsignmentNote: this.document, MovementComplete: true, } : {}),
|
||||||
lastUser: null,
|
|
||||||
toOther: 'On Delivery',
|
|
||||||
SendDate: this.assigndate,
|
|
||||||
toStore: this.selectedStore,
|
|
||||||
MovementComplete: false,
|
|
||||||
Remark: this.remark,
|
|
||||||
ConsignmentNote: this.document} : {}),
|
|
||||||
|
|
||||||
...(this.selectedAction === 'supplier' ? {
|
|
||||||
lastStore: this.currentUser.store,
|
|
||||||
lastUser: this.currentUser.id,
|
|
||||||
toOther: this.selectedOther,
|
|
||||||
SendDate: this.assigndate,
|
|
||||||
Remark: this.remark + '. Item sent to ' + this.selectedSupplier + ' for ' + this.selectedOther,
|
|
||||||
ConsignmentNote: this.document,
|
|
||||||
toUser: this.currentUser.id,
|
|
||||||
toStore: this.currentUser.store,
|
|
||||||
MovementComplete: false, } : {}),
|
|
||||||
|
|
||||||
...(this.selectedAction === 'faulty' ? {
|
|
||||||
lastStore: this.currentUser.store,
|
|
||||||
lastUser: this.currentUser.id,
|
|
||||||
toOther: 'Faulty',
|
|
||||||
SendDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
|
||||||
ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
|
||||||
Remark: this.remark,
|
|
||||||
ConsignmentNote: this.document,
|
|
||||||
MovementComplete: true, } : {}),
|
|
||||||
|
|
||||||
ItemId: this.thisItem.itemID,
|
ItemId: this.thisItem.itemID,
|
||||||
Action: 'Stock Out',
|
Action: 'Stock Out',
|
||||||
@ -1131,7 +1036,7 @@
|
|||||||
|
|
||||||
// If it's On Delivery and the current user/store is the target toUser/toStore, set to Delivered
|
// If it's On Delivery and the current user/store is the target toUser/toStore, set to Delivered
|
||||||
if (this.thisItem.toOther === "On Delivery" &&
|
if (this.thisItem.toOther === "On Delivery" &&
|
||||||
(this.thisItem.toUser == this.currentUser.id || this.thisItem.toStore == this.currentUser.store || this.isStationPIC))
|
(this.thisItem.toUser == this.currentUser.id || this.thisItem.toStore == this.currentUser.store))
|
||||||
{
|
{
|
||||||
statusToSave = "Delivered";
|
statusToSave = "Delivered";
|
||||||
}
|
}
|
||||||
@ -1145,42 +1050,15 @@
|
|||||||
statusToSave = "Ready To Deploy";
|
statusToSave = "Ready To Deploy";
|
||||||
}
|
}
|
||||||
|
|
||||||
let receiveToUser = null;
|
|
||||||
let receiveToStore = null;
|
|
||||||
let receiveToStation = null;
|
|
||||||
|
|
||||||
if (this.thisItem.toStation) {
|
|
||||||
// Only keep Station. Clear User and Store as requested.
|
|
||||||
receiveToUser = null;
|
|
||||||
receiveToStore = null;
|
|
||||||
receiveToStation = this.thisItem.toStation;
|
|
||||||
}
|
|
||||||
else if (this.thisItem.toStore) {
|
|
||||||
receiveToUser = null;
|
|
||||||
receiveToStore = this.currentUser.store;
|
|
||||||
}
|
|
||||||
else if (this.thisItem.toUser) {
|
|
||||||
receiveToUser = this.currentUser.id;
|
|
||||||
receiveToStore = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. BINA PAKEJ DATA (Lengkap dengan Last & To)
|
|
||||||
const formData = {
|
const formData = {
|
||||||
Id: this.thisItem.movementId,
|
Id: this.thisItem.movementId,
|
||||||
ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
Remark: this.thisItem.remark,
|
Remark: this.thisItem.remark,
|
||||||
LatestStatus: statusToSave,
|
ToUser: this.thisItem.touser == null ? this.currentUser.id : this.thisItem.touser,
|
||||||
|
ToStore: this.currentUser.store,
|
||||||
// Data Penerima (Update kepada siapa yang klik receive sekarang)
|
LatestStatus: statusToSave // Uses the prioritized status from above
|
||||||
ToUser: receiveToUser,
|
|
||||||
ToStore: receiveToStore,
|
|
||||||
ToStation: receiveToStation,
|
|
||||||
|
|
||||||
// Data Penghantar (Kekalkan maklumat asal sebagai rujukan sejarah)
|
|
||||||
LastUser: this.thisItem.lastUser,
|
|
||||||
LastStore: this.thisItem.lastStore,
|
|
||||||
LastStation: this.thisItem.lastStation
|
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/InvMainAPI/UpdateItemMovementMaster', {
|
const response = await fetch('/InvMainAPI/UpdateItemMovementMaster', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -1222,15 +1100,10 @@
|
|||||||
this.selectedDepartment != null &&
|
this.selectedDepartment != null &&
|
||||||
this.selectedDepartment !== ""
|
this.selectedDepartment !== ""
|
||||||
);
|
);
|
||||||
|
// Debugging logs to help you verify in the browser console
|
||||||
// Debugging logs
|
|
||||||
console.log('Item Store ID:', this.thisItem.lastStore);
|
console.log('Item Store ID:', this.thisItem.lastStore);
|
||||||
console.log('User Master Store ID:', this.currentUser.store);
|
console.log('User Master Store ID:', this.currentUser.store);
|
||||||
console.log('Is User Authorized Master for this item?', this.itemassignedtouser);
|
console.log('Is User Authorized Master for this item?', this.itemassignedtouser);
|
||||||
console.log("Scanned Item Data:", this.thisItem);
|
|
||||||
console.log("Target Station ID:", this.thisItem.toStation);
|
|
||||||
console.log("Current User ID:", this.currentUser.id);
|
|
||||||
console.log("Full Station List:", this.stationlist);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// If the response is not OK (e.g., 404 Not Found)
|
// If the response is not OK (e.g., 404 Not Found)
|
||||||
@ -1321,13 +1194,10 @@
|
|||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
Id: this.thisItem.movementId,
|
Id: this.thisItem.movementId,
|
||||||
ToUser: originalMovementDetails.toUser,
|
|
||||||
ToStore: originalMovementDetails.toStore,
|
|
||||||
ToStation: originalMovementDetails.toStation,
|
|
||||||
MovementComplete: true,
|
MovementComplete: true,
|
||||||
LatestStatus: 'Cancelled',
|
LatestStatus: 'Cancelled',
|
||||||
// Append the cancellation remark to the current remark
|
// Append the cancellation remark to the current remark
|
||||||
Remark: `Current: ${currentRemark.trim()}${currentRemark.trim() ? ' / ' : ''}Movement cancelled: ${this.cancelRemark}`
|
Remark: `${currentRemark.trim()}${currentRemark.trim() ? ' / ' : ''}Movement cancelled: ${this.cancelRemark}`
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1472,30 +1342,39 @@
|
|||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const formData = {
|
const formData = {
|
||||||
ItemId: this.thisItem.itemID,
|
// ItemId: this.thisItem.itemID,
|
||||||
|
// LastStore: this.thisItem.lastStore,
|
||||||
|
// LastUser: this.thisItem.lastUser, This will be handled by the API logic
|
||||||
|
// ToOther: "Return",
|
||||||
|
// SendDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
|
// Action: "StockIn",
|
||||||
|
// Quantity: this.thisItem.quantity || 1,
|
||||||
|
// Remark: this.remark + " (Returned)",
|
||||||
|
// ConsignmentNote: this.document, The base64 string from handleFileUpload
|
||||||
|
// Date: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
|
// ToUser: this.currentUser.id,
|
||||||
|
// ToStore: this.thisItem.lastStore,
|
||||||
|
// LatestStatus: null,
|
||||||
|
// MovementComplete: false
|
||||||
|
|
||||||
// ORIGIN: Where is it right now?
|
ItemId: this.thisItem.itemID,
|
||||||
LastUser: this.thisItem.toUser,
|
LastStation: this.thisItem.currentStationId,
|
||||||
LastStore: this.thisItem.toStore,
|
LastStore: this.thisItem.currentStoreId,
|
||||||
LastStation: this.thisItem.toStation,
|
LastUser: this.currentUser.id,
|
||||||
|
ToOther: "Return",
|
||||||
// DESTINATION: Set to null here. The C# backend will query the DB
|
SendDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
// and fill these in automatically based on history!
|
Action: "StockIn",
|
||||||
ToUser: null,
|
// Quantity: this.thisItem.quantity,
|
||||||
ToStore: null,
|
Quantity: this.thisItem.movementQuantity || 1,
|
||||||
ToStation: null,
|
Remark: this.remark,
|
||||||
|
ConsignmentNote: this.consignmentNote,
|
||||||
ToOther: "Return",
|
Date: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
SendDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
ToUser: this.thisItem.lastUser,
|
||||||
Action: "StockIn",
|
ToStore: this.thisItem.lastStore,
|
||||||
Quantity: this.thisItem.movementQuantity || 1,
|
// ToStation: this.thisItem.lastStation,
|
||||||
Remark: this.remark,
|
LatestStatus: null,
|
||||||
ConsignmentNote: this.document,
|
ReceiveDate: null,
|
||||||
Date: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
MovementComplete: false,
|
||||||
|
|
||||||
LatestStatus: null,
|
|
||||||
ReceiveDate: null,
|
|
||||||
MovementComplete: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -1508,7 +1387,7 @@
|
|||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
alert('Success! Item is now on delivery to be returned.');
|
alert('Success! Item is now on delivery to be returned.');
|
||||||
$('#returnMessageModal').modal('hide');
|
$('#returnMessageModal').modal('hide');
|
||||||
this.resetScanner();
|
this.resetScanner(); // Reset view back to scanner
|
||||||
window.location.href = '/Inventory/InventoryMaster/ItemMovement';
|
window.location.href = '/Inventory/InventoryMaster/ItemMovement';
|
||||||
} else {
|
} else {
|
||||||
const errorText = await response.text();
|
const errorText = await response.text();
|
||||||
@ -1525,56 +1404,35 @@
|
|||||||
$("#stationMessageModal").modal("show");
|
$("#stationMessageModal").modal("show");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
async confirmDeployStation() {
|
async confirmDeployStation() {
|
||||||
if (!this.selectedStation) {
|
if (!this.selectedStation) {
|
||||||
alert("Please select a station.");
|
alert("Please select a station.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
const formData = {
|
||||||
|
ItemId: this.thisItem.itemID,
|
||||||
|
LastStation: this.thisItem.lastStation || this.thisItem.currentStationId || null,
|
||||||
|
LastStore: this.currentUser.store,
|
||||||
|
LastUser: this.currentUser.id,
|
||||||
|
ToOther: "Delivered",
|
||||||
|
SendDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
|
Action: "Assign",
|
||||||
|
Quantity: this.thisItem.quantity || 1,
|
||||||
|
Remark: this.remark || "Deployed to station",
|
||||||
|
ConsignmentNote: this.document, // Base64 from file upload
|
||||||
|
Date: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
|
ToUser: this.currentUser.id,
|
||||||
|
ToStore: this.currentUser.store,
|
||||||
|
ToStation: this.selectedStation, // The new station ID selected in modal
|
||||||
|
LatestStatus: "Delivered",
|
||||||
|
receiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
|
MovementComplete: true
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const now = new Date();
|
|
||||||
|
|
||||||
// 1. LOGIC: Dynamically Identify the Origin (Where is the item right now?)
|
|
||||||
let originUser = null;
|
|
||||||
let originStore = null;
|
|
||||||
let originStation = null;
|
|
||||||
|
|
||||||
if (this.thisItem.toStation || this.thisItem.currentStationId) {
|
|
||||||
originStation = this.thisItem.toStation || this.thisItem.currentStationId;
|
|
||||||
} else if (this.thisItem.toStore) {
|
|
||||||
originStore = this.thisItem.toStore;
|
|
||||||
} else if (this.thisItem.toUser) {
|
|
||||||
originUser = this.thisItem.toUser;
|
|
||||||
} else {
|
|
||||||
originUser = this.currentUserId; // Fallback
|
|
||||||
}
|
|
||||||
|
|
||||||
const formData = {
|
|
||||||
ItemId: this.thisItem.itemID,
|
|
||||||
|
|
||||||
// ORIGINS: Shift the current location to the "Last" fields
|
|
||||||
LastStation: originStation,
|
|
||||||
LastStore: originStore,
|
|
||||||
LastUser: originUser,
|
|
||||||
|
|
||||||
// DESTINATIONS: To the newly selected station (User and Store must be null)
|
|
||||||
ToStation: this.selectedStation,
|
|
||||||
ToUser: null,
|
|
||||||
ToStore: null,
|
|
||||||
|
|
||||||
ToOther: "Delivered",
|
|
||||||
Action: "Assign",
|
|
||||||
Quantity: this.thisItem.movementQuantity || 1,
|
|
||||||
Remark: this.remark ? (this.remark + ' / Deployed to station') : 'Deployed to station',
|
|
||||||
ConsignmentNote: this.document, // Ensure this matches how your file is stored in Vue data
|
|
||||||
SendDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
|
||||||
Date: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
|
||||||
ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
|
||||||
|
|
||||||
LatestStatus: "Delivered",
|
|
||||||
MovementComplete: true
|
|
||||||
};
|
|
||||||
|
|
||||||
const response = await fetch('/InvMainAPI/StationItemMovementUser', {
|
const response = await fetch('/InvMainAPI/StationItemMovementUser', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
|||||||
@ -1040,9 +1040,7 @@
|
|||||||
{ title: "From User", data: "lastUserName" },
|
{ title: "From User", data: "lastUserName" },
|
||||||
{ title: "Last User", data: "toUserName" },
|
{ 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 Store", data: "toStoreName" },
|
|
||||||
{ title: "Quantity", data: "quantity" },
|
{ title: "Quantity", data: "quantity" },
|
||||||
{ title: "Note", data: "consignmentNote", render: renderFile },
|
{ title: "Note", data: "consignmentNote", render: renderFile },
|
||||||
{ title: "Remark", data: "remark" },
|
{ title: "Remark", data: "remark" },
|
||||||
|
|||||||
@ -114,8 +114,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>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">{{thisItem.currentUserFullName}}</span>
|
||||||
@* <span class="text-muted">{{thisItem.currentUserFullName}}</span> *@
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -142,7 +141,7 @@
|
|||||||
<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.currentUser }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@ -166,7 +165,7 @@
|
|||||||
<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.currentUser }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@ -449,42 +448,21 @@
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
||||||
// 1. LOGIC: Identify the Origin (Last location)
|
|
||||||
let originUser = null;
|
|
||||||
let originStore = null;
|
|
||||||
let originStation = null;
|
|
||||||
|
|
||||||
if (this.thisItem.toStation || this.thisItem.currentStationId) {
|
|
||||||
originStation = this.thisItem.toStation || this.thisItem.currentStationId;
|
|
||||||
} else if (this.thisItem.toStore) {
|
|
||||||
originStore = this.thisItem.toStore;
|
|
||||||
} else if (this.thisItem.toUser) {
|
|
||||||
originUser = this.thisItem.toUser;
|
|
||||||
} else {
|
|
||||||
originUser = this.currentUserId; // Fallback to current user if not found
|
|
||||||
}
|
|
||||||
|
|
||||||
const formData = {
|
const formData = {
|
||||||
ItemId: this.thisItem.itemID,
|
ItemId: this.thisItem.itemID,
|
||||||
|
LastStation: this.thisItem.currentStationId,
|
||||||
// ORIGINS: Based on the logic above
|
LastStore: this.thisItem.lastStore,
|
||||||
LastStation: originStation,
|
LastUser: this.currentUserId,
|
||||||
LastStore: originStore,
|
|
||||||
LastUser: originUser,
|
|
||||||
|
|
||||||
// DESTINATIONS: Explicitly set to only the Station
|
|
||||||
ToStation: this.selectedStation,
|
|
||||||
ToUser: null,
|
|
||||||
ToStore: null,
|
|
||||||
|
|
||||||
ToOther: "Delivered",
|
ToOther: "Delivered",
|
||||||
|
SendDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
Action: "Assign",
|
Action: "Assign",
|
||||||
Quantity: this.thisItem.quantity || 1,
|
Quantity: this.thisItem.quantity,
|
||||||
Remark: this.remark,
|
Remark: this.remark,
|
||||||
ConsignmentNote: this.consignmentNote,
|
ConsignmentNote: this.consignmentNote,
|
||||||
SendDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
|
||||||
Date: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
Date: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
|
ToUser: this.currentUserId,
|
||||||
|
ToStore: this.thisItem.lastStore,
|
||||||
|
ToStation: this.selectedStation,
|
||||||
LatestStatus: "Delivered",
|
LatestStatus: "Delivered",
|
||||||
ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
MovementComplete: true,
|
MovementComplete: true,
|
||||||
@ -504,7 +482,6 @@
|
|||||||
alert('Success! Item assign to the Station.');
|
alert('Success! Item assign to the Station.');
|
||||||
$('#stationMessage').modal('hide');
|
$('#stationMessage').modal('hide');
|
||||||
this.displayStatus = "return";
|
this.displayStatus = "return";
|
||||||
this.resetForm();
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Failed to submit form.');
|
throw new Error('Failed to submit form.');
|
||||||
}
|
}
|
||||||
@ -524,42 +501,12 @@
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
||||||
let receiveToUser = null;
|
|
||||||
let receiveToStore = null;
|
|
||||||
let receiveToStation = null;
|
|
||||||
|
|
||||||
if (this.thisItem.toStation) {
|
|
||||||
// Only keep Station. Clear User and Store as requested.
|
|
||||||
receiveToUser = null;
|
|
||||||
receiveToStore = null;
|
|
||||||
receiveToStation = this.thisItem.toStation;
|
|
||||||
}
|
|
||||||
else if (this.thisItem.toStore) {
|
|
||||||
receiveToUser = null;
|
|
||||||
receiveToStore = this.currentUser.store;
|
|
||||||
}
|
|
||||||
else if (this.thisItem.toUser) {
|
|
||||||
receiveToUser = this.currentUser.id;
|
|
||||||
receiveToStore = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const formData = {
|
const formData = {
|
||||||
Id: this.thisItem.id,
|
Id: this.thisItem.id,
|
||||||
// ToStore: this.thisItem.lastStore,
|
ToStore: this.thisItem.lastStore,
|
||||||
LatestStatus: "Delivered",
|
LatestStatus: "Delivered",
|
||||||
ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
ReceiveDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
MovementComplete: true,
|
MovementComplete: true,
|
||||||
|
|
||||||
// Data Penerima (Update kepada siapa yang klik receive sekarang)
|
|
||||||
ToUser: receiveToUser,
|
|
||||||
ToStore: receiveToStore,
|
|
||||||
ToStation: receiveToStation,
|
|
||||||
|
|
||||||
// Data Penghantar (Kekalkan maklumat asal sebagai rujukan sejarah)
|
|
||||||
LastUser: this.thisItem.lastUser,
|
|
||||||
LastStore: this.thisItem.lastStore,
|
|
||||||
LastStation: this.thisItem.lastStation
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await fetch('/InvMainAPI/UpdateItemMovementUser', {
|
const response = await fetch('/InvMainAPI/UpdateItemMovementUser', {
|
||||||
@ -590,47 +537,29 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
async returnItemMovement() {
|
async returnItemMovement() {
|
||||||
|
|
||||||
if (!confirm("Are you sure you want to return this item?")) {
|
if (!confirm("Are you sure you want to return this item?")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 1. LOGIC: Identify the Origin (Last location)
|
|
||||||
let returnLastUser = null;
|
|
||||||
let returnLastStore = null;
|
|
||||||
let returnLastStation = null;
|
|
||||||
|
|
||||||
if (this.thisItem.toStation || this.thisItem.currentStationId) {
|
|
||||||
returnLastStation = this.thisItem.toStation || this.thisItem.currentStationId;
|
|
||||||
} else if (this.thisItem.toStore) {
|
|
||||||
returnLastStore = this.thisItem.toStore;
|
|
||||||
} else if (this.thisItem.toUser) {
|
|
||||||
returnLastUser = this.thisItem.toUser;
|
|
||||||
} else {
|
|
||||||
returnLastUser = this.currentUserId; // Fallback to current user if not found
|
|
||||||
}
|
|
||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const formData = {
|
const formData = {
|
||||||
ItemId: this.thisItem.itemID,
|
ItemId: this.thisItem.itemID,
|
||||||
|
LastStation: this.thisItem.currentStationId,
|
||||||
// ORIGINS: Where the item is currently sitting
|
LastStore: this.thisItem.currentStoreId,
|
||||||
LastUser: returnLastUser,
|
LastUser: this.currentUserId,
|
||||||
LastStore: returnLastStore,
|
|
||||||
LastStation: returnLastStation,
|
|
||||||
|
|
||||||
// DESTINATIONS: Set to null (the C# API logic overrides this)
|
|
||||||
ToUser: null,
|
|
||||||
ToStore: null,
|
|
||||||
ToStation: null,
|
|
||||||
|
|
||||||
ToOther: "Return",
|
ToOther: "Return",
|
||||||
|
SendDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
Action: "StockIn",
|
Action: "StockIn",
|
||||||
|
// Quantity: this.thisItem.quantity,
|
||||||
Quantity: this.thisItem.movementQuantity || 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(),
|
|
||||||
Date: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
Date: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
|
||||||
|
ToUser: this.InventoryMasterId,
|
||||||
|
ToStore: this.thisItem.lastStore,
|
||||||
|
ToStation: this.thisItem.lastStation,
|
||||||
LatestStatus: null,
|
LatestStatus: null,
|
||||||
ReceiveDate: null,
|
ReceiveDate: null,
|
||||||
MovementComplete: false,
|
MovementComplete: false,
|
||||||
@ -669,27 +598,22 @@
|
|||||||
this.thisItem = await response.json();
|
this.thisItem = await response.json();
|
||||||
// this.fetchStore(this.thisItem.lastStore);
|
// this.fetchStore(this.thisItem.lastStore);
|
||||||
|
|
||||||
// Check if the current user is the PIC of the destination station
|
console.log("Current Station ID:", this.thisItem.currentStationId);
|
||||||
const isPicOfTargetStation = this.stationList.some(
|
console.log("To Station ID:", this.thisItem.toStationId);
|
||||||
station => station.stationId == this.thisItem.toStationId
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log("Is PIC of Target Station:", isPicOfTargetStation);
|
// 1. ARRIVED/RECEIVE LOGIC: Check if YOU are the "ToUser"
|
||||||
|
|
||||||
// 1. ARRIVED/RECEIVE LOGIC
|
|
||||||
// Allow access if the user is the 'ToUser' OR the 'Station PIC'
|
|
||||||
if (this.thisItem.movementId != null &&
|
if (this.thisItem.movementId != null &&
|
||||||
this.thisItem.toOther === "On Delivery" &&
|
this.thisItem.toOther === "On Delivery" &&
|
||||||
this.thisItem.latestStatus == null &&
|
this.thisItem.latestStatus == null &&
|
||||||
(this.thisItem.toUser == this.currentUserId || isPicOfTargetStation) &&
|
this.thisItem.toUser == this.currentUserId && // Check ToUser, not LastUser/CurrentUserId
|
||||||
this.thisItem.movementComplete == 0) {
|
this.thisItem.movementComplete == 0) {
|
||||||
|
|
||||||
this.displayStatus = "arrived";
|
this.displayStatus = "arrived";
|
||||||
|
|
||||||
// 2. RETURN/OWNED LOGIC
|
// 2. RETURN/OWNED LOGIC: Check if YOU currently hold the item
|
||||||
} else if (this.thisItem.movementId != null &&
|
} else if (this.thisItem.movementId != null &&
|
||||||
this.thisItem.latestStatus != null &&
|
this.thisItem.latestStatus != null &&
|
||||||
(this.thisItem.toUser == this.currentUserId || isPicOfTargetStation) &&
|
this.thisItem.toUser == this.currentUserId &&
|
||||||
this.thisItem.latestStatus != "Ready To Deploy") {
|
this.thisItem.latestStatus != "Ready To Deploy") {
|
||||||
|
|
||||||
this.displayStatus = "return";
|
this.displayStatus = "return";
|
||||||
@ -703,6 +627,7 @@
|
|||||||
this.displayStatus = "requestAgain";
|
this.displayStatus = "requestAgain";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
// FALLBACK: If none of the above matches, it means someone else is the ToUser
|
||||||
this.displayStatus = "differentUser";
|
this.displayStatus = "differentUser";
|
||||||
this.thisItem = null;
|
this.thisItem = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -962,7 +962,6 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
|
|
||||||
CurrentStationId = item.Movement?.ToStation ?? item.Movement?.LastStation,
|
CurrentStationId = item.Movement?.ToStation ?? item.Movement?.LastStation,
|
||||||
ToStationId = item.Movement?.ToStation,
|
ToStationId = item.Movement?.ToStation,
|
||||||
toStation = item.Movement?.ToStation,
|
|
||||||
|
|
||||||
LastUser = item.Movement?.LastUser,
|
LastUser = item.Movement?.LastUser,
|
||||||
ToUserName = item.Movement?.NextUser?.UserName,
|
ToUserName = item.Movement?.NextUser?.UserName,
|
||||||
@ -1061,37 +1060,13 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//itemmovement.sendDate = DateTime.Now; // This ensures hours/minutes/seconds are captured
|
itemmovement.sendDate = DateTime.Now; // This ensures hours/minutes/seconds are captured
|
||||||
//itemmovement.Date = DateTime.Now; // Set the general record date as well
|
itemmovement.Date = DateTime.Now; // Set the general record date as well
|
||||||
|
|
||||||
//var inventoryMaster = await _centralDbContext.InventoryMasters.Include("User").FirstOrDefaultAsync(i => i.UserId == itemmovement.LastUser);
|
var inventoryMaster = await _centralDbContext.InventoryMasters.Include("User").FirstOrDefaultAsync(i => i.UserId == itemmovement.LastUser);
|
||||||
//if (inventoryMaster != null)
|
if (inventoryMaster != null)
|
||||||
//{
|
|
||||||
// itemmovement.LastStore = inventoryMaster.StoreId;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// 1. FIX DATE OVERRULE:
|
|
||||||
// Use the date from the frontend (assigndate) if it exists.
|
|
||||||
// Only set to DateTime.Now if the frontend sent null/empty.
|
|
||||||
if (itemmovement.sendDate == default || itemmovement.sendDate == null)
|
|
||||||
{
|
{
|
||||||
itemmovement.sendDate = DateTime.Now;
|
itemmovement.LastStore = inventoryMaster.StoreId;
|
||||||
}
|
|
||||||
itemmovement.Date = DateTime.Now; // Log the entry creation time
|
|
||||||
|
|
||||||
// 2. FIX STORE/USER OVERRULE:
|
|
||||||
// Only auto-fill LastStore if:
|
|
||||||
// - The frontend didn't send one (null)
|
|
||||||
// - We have a LastUser to look up
|
|
||||||
// - AND it is NOT a "user" assignment (because for 'user', we want it to stay NULL)
|
|
||||||
if (itemmovement.LastStore == null && itemmovement.LastUser != null && itemmovement.ToUser == null)
|
|
||||||
{
|
|
||||||
var inventoryMaster = await _centralDbContext.InventoryMasters
|
|
||||||
.FirstOrDefaultAsync(i => i.UserId == itemmovement.LastUser);
|
|
||||||
if (inventoryMaster != null)
|
|
||||||
{
|
|
||||||
itemmovement.LastStore = inventoryMaster.StoreId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1209,11 +1184,8 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
return NotFound("Item movement record not found.");
|
return NotFound("Item movement record not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedList.ToUser = receiveMovement.ToUser ?? updatedList.ToUser;
|
updatedList.ToUser = receiveMovement.ToUser;
|
||||||
updatedList.ToStore = receiveMovement.ToStore ?? updatedList.ToStore;
|
updatedList.ToStore = receiveMovement.ToStore;
|
||||||
updatedList.ToStation = receiveMovement.ToStation ?? updatedList.ToStation;
|
|
||||||
//updatedList.ToUser = receiveMovement.ToUser;
|
|
||||||
//updatedList.ToStore = receiveMovement.ToStore;
|
|
||||||
updatedList.LatestStatus = receiveMovement.LatestStatus;
|
updatedList.LatestStatus = receiveMovement.LatestStatus;
|
||||||
updatedList.receiveDate = receiveMovement.receiveDate;
|
updatedList.receiveDate = receiveMovement.receiveDate;
|
||||||
updatedList.Remark = receiveMovement.Remark;
|
updatedList.Remark = receiveMovement.Remark;
|
||||||
@ -1962,45 +1934,10 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// --- CORE FIX: ISOLATE THE CURRENT LIFECYCLE ---
|
|
||||||
// 1. Find the last time the item cycle was "reset" (Returned or newly Registered)
|
|
||||||
var lastResetMovement = await _centralDbContext.ItemMovements
|
|
||||||
.Where(m => m.ItemId == returnMovement.ItemId && (m.Action == "StockIn" || m.Action == "Register"))
|
|
||||||
.OrderByDescending(m => m.Id)
|
|
||||||
.FirstOrDefaultAsync();
|
|
||||||
|
|
||||||
// Get the ID where the current cycle started (if 0, it means it has never been returned/registered)
|
|
||||||
int currentCycleStartId = lastResetMovement != null ? lastResetMovement.Id : 0;
|
|
||||||
|
|
||||||
// 2. Find the VERY FIRST movement AFTER the cycle started.
|
|
||||||
// This bypasses the middleman (User/Store who gave it to the station) and
|
|
||||||
// accurately grabs the Inventory Master who originally assigned it at the beginning of the chain.
|
|
||||||
var originalMasterMovement = await _centralDbContext.ItemMovements
|
|
||||||
.Where(m => m.ItemId == returnMovement.ItemId
|
|
||||||
&& m.Id > currentCycleStartId
|
|
||||||
&& (m.LastUser != null || m.LastStore != null))
|
|
||||||
.OrderBy(m => m.Id) // <-- Get the FIRST movement of the current chain
|
|
||||||
.FirstOrDefaultAsync();
|
|
||||||
|
|
||||||
if (originalMasterMovement != null)
|
|
||||||
{
|
|
||||||
// Set the destination back to the original Inventory Master
|
|
||||||
returnMovement.ToUser = originalMasterMovement.LastUser;
|
|
||||||
returnMovement.ToStore = originalMasterMovement.LastStore;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Fallback just in case history isn't found
|
|
||||||
returnMovement.ToUser = null;
|
|
||||||
returnMovement.ToStore = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(returnMovement.ConsignmentNote))
|
if (!string.IsNullOrEmpty(returnMovement.ConsignmentNote))
|
||||||
{
|
{
|
||||||
var findUniqueCode = _centralDbContext.Items.Include(i => i.Product).FirstOrDefault(r => r.ItemID == returnMovement.ItemId);
|
var findUniqueCode = _centralDbContext.Items.Include(i => i.Product).FirstOrDefault(r => r.ItemID == returnMovement.ItemId);
|
||||||
|
var findUniqueUser = _centralDbContext.Users.FirstOrDefault(r => r.Id == returnMovement.LastUser);
|
||||||
// Fetch the user data for the file name based on the destination we just assigned
|
|
||||||
var findUniqueUser = _centralDbContext.Users.FirstOrDefault(r => r.Id == returnMovement.ToUser);
|
|
||||||
|
|
||||||
var bytes = Convert.FromBase64String(returnMovement.ConsignmentNote);
|
var bytes = Convert.FromBase64String(returnMovement.ConsignmentNote);
|
||||||
|
|
||||||
@ -2089,28 +2026,27 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
|
|||||||
var findUniqueUser = _centralDbContext.Users.FirstOrDefault(r => r.Id == stationMovement.LastUser);
|
var findUniqueUser = _centralDbContext.Users.FirstOrDefault(r => r.Id == stationMovement.LastUser);
|
||||||
|
|
||||||
var bytes = Convert.FromBase64String(stationMovement.ConsignmentNote);
|
var bytes = Convert.FromBase64String(stationMovement.ConsignmentNote);
|
||||||
|
string filePath = "";
|
||||||
|
|
||||||
var uniqueAbjad = new string(Enumerable.Range(0, 8).Select(_ => "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[new Random().Next(36)]).ToArray());
|
var uniqueAbjad = new string(Enumerable.Range(0, 8).Select(_ => "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[new Random().Next(36)]).ToArray());
|
||||||
|
|
||||||
// FIX: Safely handle null users and clean invalid file characters (just like your Return API)
|
|
||||||
string safeUserName = string.Join("_", (findUniqueUser?.FullName ?? "Station").Split(Path.GetInvalidFileNameChars()));
|
|
||||||
string safeModelNo = string.Join("_", (findUniqueCode?.Product?.ModelNo ?? "NA").Split(Path.GetInvalidFileNameChars()));
|
|
||||||
|
|
||||||
string extension = IsPdf(bytes) ? ".pdf" : ".jpg";
|
if (IsImage(bytes))
|
||||||
if (!IsImage(bytes) && !IsPdf(bytes)) return BadRequest("Unsupported file format.");
|
|
||||||
|
|
||||||
string relativePath = $"media/inventory/itemmovement/{safeUserName}_{safeModelNo}_{uniqueAbjad}_Station{extension}";
|
|
||||||
string folderPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "media", "inventory", "itemmovement");
|
|
||||||
string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", relativePath);
|
|
||||||
|
|
||||||
if (!Directory.Exists(folderPath))
|
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(folderPath);
|
filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/media/inventory/itemmovement", findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "(" + uniqueAbjad + ") Station.jpg");
|
||||||
|
stationMovement.ConsignmentNote = "/media/inventory/itemmovement/" + findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "(" + uniqueAbjad + ") Station.jpg";
|
||||||
|
}
|
||||||
|
else if (IsPdf(bytes))
|
||||||
|
{
|
||||||
|
filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/media/inventory/itemmovement", findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "Return.pdf");
|
||||||
|
stationMovement.ConsignmentNote = "/media/inventory/itemmovement/" + findUniqueUser.FullName + " " + findUniqueCode.Product?.ModelNo + "(" + uniqueAbjad + ") Station.pdf";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return BadRequest("Unsupported file format.");
|
||||||
}
|
}
|
||||||
|
|
||||||
await System.IO.File.WriteAllBytesAsync(filePath, bytes);
|
await System.IO.File.WriteAllBytesAsync(filePath, bytes);
|
||||||
|
|
||||||
// Save the safe relative path to the database
|
|
||||||
stationMovement.ConsignmentNote = "/" + relativePath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_centralDbContext.ItemMovements.Add(stationMovement);
|
_centralDbContext.ItemMovements.Add(stationMovement);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user