Update Inv & OT

This commit is contained in:
Naz 2025-07-23 17:17:23 +08:00
parent bde383ced7
commit 98ba700ef2
6 changed files with 82 additions and 67 deletions

View File

@ -36,6 +36,9 @@ namespace PSTW_CentralSystem.Areas.Inventory.Models
public string PartNumber { get; set; } = string.Empty;
public int CreatedByUserId { get; set; }
[ForeignKey("CreatedByUserId")]
public DateTime CreateDate { get; set; } = DateTime.Now;
public virtual UserModel? CreatedBy { get; set; }
[ForeignKey("CompanyId")]
public virtual CompanyModel? Company { get; set; }

View File

@ -952,41 +952,43 @@
async fetchItem(itemid) {
try {
const response = await fetch('/InvMainAPI/GetItem/' + itemid, {
method: 'POST',}
);
if (response.ok) {
// this.thisItem = await response.json();
method: 'POST',
});
if (response.ok) {
this.thisItem = await response.json();
// If the item is disposable, set the quantity to 1 by default, or to its current quantity if available
if (this.thisItem.category === 'Disposable') {
this.quantity = 1; // Reset to 1 or default quantity when a disposable item is scanned
this.maxQuantity = this.thisItem.quantity; // Set maxQuantity for disposable items
this.quantity = 1;
this.maxQuantity = this.thisItem.quantity;
} else {
this.quantity = 1; // For non-disposable items, quantity is always 1
this.maxQuantity = null; // Clear maxQuantity for non-disposable items
this.quantity = 1;
this.maxQuantity = null;
}
console.log('last store'+this.thisItem.lastStore);
console.log('last store' + this.thisItem.lastStore);
this.itemlateststatus = this.thisItem.latestStatus ? this.thisItem.latestStatus : this.thisItem.toOther;
this.itemassignedtouser = (this.thisItem.toUser === this.currentUser.id || this.thisItem.lastUser === this.currentUser.id ) && this.thisItem.lastStore === this.currentUser.store ? true : false;
// console.log(this.thisItem);
// console.log(this.itemassignedtouser);
console.log(this.thisItem.lastStore);
console.log( this.thisItem.lastStore == this.currentUser.store? true : false);
console.log(this.thisItem.toUser == this.currentUser.id? true : false);
console.log( this.thisItem.lastUser == this.currentUser.id ? true : false);
console.log(((this.thisItem.toUser == this.currentUser.id) || ( this.thisItem.lastUser == this.currentUser.id)) ? true : false);
console.log('currentuser store'+this.currentUser.store);
this.itemassignedtouser = (this.thisItem.toUser === this.currentUser.id || this.thisItem.lastUser === this.currentUser.id) && this.thisItem.lastStore === this.currentUser.store ? true : false;
console.log(this.thisItem.lastStore);
console.log(this.thisItem.lastStore == this.currentUser.store ? true : false);
console.log(this.thisItem.toUser == this.currentUser.id ? true : false);
console.log(this.thisItem.lastUser == this.currentUser.id ? true : false);
console.log(((this.thisItem.toUser == this.currentUser.id) || (this.thisItem.lastUser == this.currentUser.id)) ? true : false);
console.log('currentuser store' + this.currentUser.store);
} else {
console.error('Failed to fetch item information');
this.responseMessage = await response.text();
// If the response is not OK (e.g., 404 Not Found)
const errorData = await response.json(); // Assuming your API sends a JSON error object
// Show an alert message to the user
alert('QR Scan Error: ' + errorData.message);
this.resetScanner(); // Optionally reset the scanner on error
}
} catch (error) {
console.error('Error fetching item information:', error);
// Show an alert message for network or other unhandled errors
alert('An unexpected error occurred: ' + error.message);
this.resetScanner(); // Optionally reset the scanner on unexpected error
}
},
async fetchSuppliers() {
@ -1032,25 +1034,17 @@
const now = new Date();
try {
// First Movement: Cancellation Record (EXACTLY AS YOU HAVE IT)
const cancellationMovementData = {
ItemId: this.thisItem.itemID,
ToStore: this.currentUser.store,
ToUser: this.currentUser.id,
ToOther: null,
sendDate: new Date(now.getTime() + 8 * 60 * 60 * 1000).toISOString(),
Action: 'Stock Out',
Quantity: this.thisItem.quantity,
Remark: `Item has been cancelled: ${this.cancelRemark}`,
ConsignmentNote: this.thisItem.consignmentNote,
LastUser: this.currentUser.id,
LastStore: this.currentUser.store,
LatestStatus: 'Ready To Deploy',
receiveDate: null,
MovementComplete: true,
};
// --- REMOVED: First Movement: Cancellation Record (cancellationMovementData) ---
// Second Movement: Re-registration/Re-stock Record (EXACTLY AS YOU HAVE IT)
// Fetch the current item movement details to get the existing Remark
const originalMovementDetailsResponse = await fetch(`/InvMainAPI/GetItemMovementById?id=${this.thisItem.movementId}`); // Assuming you have an API endpoint to get a single item movement by ID
if (!originalMovementDetailsResponse.ok) {
throw new Error('Failed to retrieve original item movement details.');
}
const originalMovementDetails = await originalMovementDetailsResponse.json();
const currentRemark = originalMovementDetails.remark || ''; // Get existing remark, default to empty string if null
// Second Movement: Re-registration/Re-stock Record
const registrationMovementData = {
ItemId: this.thisItem.itemID,
ToStore: this.currentUser.store,
@ -1058,7 +1052,7 @@
ToOther: null,
sendDate: null,
Action: 'Register',
Quantity: this.thisItem.quantity,
Quantity: this.thisItem.movementQuantity, // Use the movement quantity, not item quantity
Remark: null,
ConsignmentNote: null,
LastUser: this.currentUser.id,
@ -1076,7 +1070,8 @@
Id: this.thisItem.movementId,
MovementComplete: true,
LatestStatus: 'Cancelled',
Remark: `Movement cancelled: ${this.cancelRemark}`
// Append the cancellation remark to the current remark
Remark: `${currentRemark.trim()}${currentRemark.trim() ? ' / ' : ''}Movement cancelled: ${this.cancelRemark}`
}),
});
@ -1084,16 +1079,8 @@
throw new Error('Failed to update original movement as cancelled.');
}
// Send the first movement (cancellation)
const response1 = await fetch('/InvMainAPI/AddItemMovement', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(cancellationMovementData),
});
if (!response1.ok) {
throw new Error('Failed to record cancellation movement.');
}
// --- REMOVED: Send the first movement (cancellation) ---
// const response1 = await fetch('/InvMainAPI/AddItemMovement', { ... });
// Send the second movement (registration/re-stock)
const response2 = await fetch('/InvMainAPI/AddItemMovement', {
@ -1112,8 +1099,8 @@
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
ItemId: this.thisItem.itemID,
Quantity: this.thisItem.quantity, // The quantity to add back
MovementId: this.thisItem.movementId // Add the movement ID
MovementId: this.thisItem.movementId // Pass the movement ID to find the exact quantity
// Don't pass Quantity here - API will get it from the movement record
}),
});

View File

@ -464,13 +464,12 @@
formData.append('File', this.selectedFile);
try {
const res = await axios.post('/OvertimeAPI/SubmitOvertime', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
const response = await fetch('/OvertimeAPI/SubmitOvertime', {
method: 'POST',
body: formData
});
if (res.status === 200) {
if (response.ok) { // Check if the response status is 2xx
alert('Overtime submitted successfully!');
const modalEl = document.getElementById('submitModal');
@ -480,10 +479,12 @@
await this.getSubmissionStatus();
} else {
alert('Submission failed.');
const errorText = await response.text(); // Get error message from response body
alert(`Submission failed: ${errorText}`);
console.error('Submission failed:', response.status, errorText);
}
} catch (error) {
console.error(error);
console.error("Error during submission:", error);
alert('An error occurred during submission.');
}
}

View File

@ -497,7 +497,9 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
try
{
var product = await _centralDbContext.Products.FirstOrDefaultAsync(p => p.ProductId == item.ProductId) ?? throw new Exception("Product not found");
var inventoryMaster = await _centralDbContext.InventoryMasters.Include("User").FirstOrDefaultAsync(i => i.UserId == item.CreatedByUserId) ?? new InventoryMasterModel { UserId = item.CreatedByUserId };
var inventoryMaster = await _centralDbContext.InventoryMasters
.Include("User")
.FirstOrDefaultAsync(i => i.UserId == item.CreatedByUserId) ?? new InventoryMasterModel { UserId = item.CreatedByUserId };
if (product.Category == "Disposable")
{
@ -514,6 +516,8 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
item.Quantity = 1; // Force quantity to 1 for Assets/Parts if it's not already
}
item.CreateDate = DateTime.Now;
_centralDbContext.Items.Add(item);
_centralDbContext.Products.Update(product); // Update the product quantity
@ -580,6 +584,7 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
savedItem.EndWDate,
savedItem.InvoiceDate,
savedItem.PartNumber,
CreateDate = savedItem.CreateDate.ToString("dd/MM/yyyy HH:mm:ss")
};
return Json(updatedItem);
}
@ -1144,6 +1149,25 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory
}
}
[HttpGet("GetItemMovementById")]
public async Task<IActionResult> GetItemMovementById(int id)
{
try
{
var itemMovement = await _centralDbContext.ItemMovements.FindAsync(id);
if (itemMovement == null)
{
return NotFound("Item movement record not found.");
}
return Ok(itemMovement);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
#endregion ItemMovement
#region ItemMovementUser