diff --git a/Areas/OTcalculate/Views/Overtime/OtStatus.cshtml b/Areas/OTcalculate/Views/Overtime/OtStatus.cshtml
index bf86063..aa7ab1a 100644
--- a/Areas/OTcalculate/Views/Overtime/OtStatus.cshtml
+++ b/Areas/OTcalculate/Views/Overtime/OtStatus.cshtml
@@ -341,7 +341,13 @@
{{ entry.approvalRole }}
- {{ entry.changes.some(c => c.field === 'Record Deletion') ? 'deleted the record' : 'updated the record' }}
+
+ deleted the record
+
+
+ updated the record for
+ {{ formatDate(entry.recordDate) }}
+
{{ formatDateTime(entry.date) }}
@@ -702,7 +708,7 @@
getChanges(before, after) {
const changes = [];
- // Safety check: if there is no before/after data, return empty
+ // If there is no before/after data, return empty
if (!before || !after) return changes;
// Loop through ONLY the keys provided by the clean JSON
@@ -721,6 +727,10 @@
formattedBefore = formattedBefore !== "Empty" ? this.formatMinutesToHours(formattedBefore) : "0:00";
formattedAfter = formattedAfter !== "Empty" ? this.formatMinutesToHours(formattedAfter) : "0:00";
}
+ else if (key === 'OtDate') {
+ formattedBefore = formattedBefore !== "Empty" ? this.formatDate(formattedBefore) : "Empty";
+ formattedAfter = formattedAfter !== "Empty" ? this.formatDate(formattedAfter) : "Empty";
+ }
changes.push({
field: key,
@@ -773,6 +783,8 @@
approvedBy: logEntry.ApproverRole || 'N/A',
approvalRole: logEntry.ApproverRole || approvalRoles[field],
date: logEntry.UpdateTimestamp || new Date().toISOString(),
+ recordDate: logEntry.RecordDate,
+ changeType: logEntry.ChangeType,
changes: changesDetail
});
});
diff --git a/Controllers/API/OvertimeAPI.cs b/Controllers/API/OvertimeAPI.cs
index 91aab4c..b517034 100644
--- a/Controllers/API/OvertimeAPI.cs
+++ b/Controllers/API/OvertimeAPI.cs
@@ -930,16 +930,28 @@ namespace PSTW_CentralSystem.Controllers.API
return Unauthorized("User not found.");
}
- // Prevent adding records to a month that is already submitted
+ // Prevent adding records to a month that is already submitted AND NOT rejected
var targetMonth = request.OtDate.Month;
var targetYear = request.OtDate.Year;
- var isMonthAlreadySubmitted = await _centralDbContext.Otstatus
- .AnyAsync(s => s.UserId == request.UserId && s.Month == targetMonth && s.Year == targetYear);
+ // Check the LATEST submission for this month
+ var existingMonthStatus = await _centralDbContext.Otstatus
+ .Where(s => s.UserId == request.UserId && s.Month == targetMonth && s.Year == targetYear)
+ .OrderByDescending(s => s.StatusId)
+ .FirstOrDefaultAsync();
- if (isMonthAlreadySubmitted)
+ if (existingMonthStatus != null)
{
- return BadRequest($"Overtime for {request.OtDate:MMMM yyyy} has already been submitted. You cannot add new records to a locked month.");
+ bool isRejected = existingMonthStatus.HouStatus == "Rejected" ||
+ existingMonthStatus.HodStatus == "Rejected" ||
+ existingMonthStatus.ManagerStatus == "Rejected" ||
+ existingMonthStatus.HrStatus == "Rejected";
+ if (!isRejected)
+ {
+ return BadRequest($"Overtime for {request.OtDate:MMMM yyyy} is currently locked or approved. You can only add new records if the latest submission was rejected.");
+ }
+
+ request.StatusId = existingMonthStatus.StatusId;
}
var userRoles = await _userManager.GetRolesAsync(user);
@@ -2138,11 +2150,9 @@ namespace PSTW_CentralSystem.Controllers.API
public int ApproverUserId { get; set; }
public DateTime UpdateTimestamp { get; set; }
public string ChangeType { get; set; }
-
- // Save the exact fields that changed
+ public string RecordDate { get; set; }
public Dictionary BeforeEdit { get; set; }
public Dictionary AfterEdit { get; set; }
-
public object DeletedRecord { get; set; }
}
@@ -2165,35 +2175,48 @@ namespace PSTW_CentralSystem.Controllers.API
var beforeChanges = new Dictionary();
var afterChanges = new Dictionary();
+ bool IsChanged(string oldVal, string newVal) => (oldVal ?? "") != (newVal ?? "");
+
if (existingRecord.OtDate.Date != updatedRecordDto.OtDate.Date)
{
beforeChanges["OtDate"] = existingRecord.OtDate.ToString("yyyy-MM-dd");
afterChanges["OtDate"] = updatedRecordDto.OtDate.ToString("yyyy-MM-dd");
}
- if (existingRecord.OfficeFrom != newOfficeFrom)
+
+ string oldOfficeFrom = existingRecord.OfficeFrom?.ToString(@"hh\:mm") ?? "Empty";
+ string newOfficeFromStr = newOfficeFrom?.ToString(@"hh\:mm") ?? "Empty";
+ if (IsChanged(oldOfficeFrom, newOfficeFromStr))
{
- beforeChanges["OfficeFrom"] = existingRecord.OfficeFrom?.ToString(@"hh\:mm") ?? "Empty";
- afterChanges["OfficeFrom"] = newOfficeFrom?.ToString(@"hh\:mm") ?? "Empty";
+ beforeChanges["OfficeFrom"] = oldOfficeFrom;
+ afterChanges["OfficeFrom"] = newOfficeFromStr;
}
- if (existingRecord.OfficeTo != newOfficeTo)
+
+ string oldOfficeTo = existingRecord.OfficeTo?.ToString(@"hh\:mm") ?? "Empty";
+ string newOfficeToStr = newOfficeTo?.ToString(@"hh\:mm") ?? "Empty";
+ if (IsChanged(oldOfficeTo, newOfficeToStr))
{
- beforeChanges["OfficeTo"] = existingRecord.OfficeTo?.ToString(@"hh\:mm") ?? "Empty";
- afterChanges["OfficeTo"] = newOfficeTo?.ToString(@"hh\:mm") ?? "Empty";
+ beforeChanges["OfficeTo"] = oldOfficeTo;
+ afterChanges["OfficeTo"] = newOfficeToStr;
}
if ((existingRecord.OfficeBreak ?? 0) != (updatedRecordDto.OfficeBreak ?? 0))
{
beforeChanges["OfficeBreak"] = (existingRecord.OfficeBreak ?? 0).ToString();
afterChanges["OfficeBreak"] = (updatedRecordDto.OfficeBreak ?? 0).ToString();
}
- if (existingRecord.AfterFrom != newAfterFrom)
+ string oldAfterFrom = existingRecord.AfterFrom?.ToString(@"hh\:mm") ?? "Empty";
+ string newAfterFromStr = newAfterFrom?.ToString(@"hh\:mm") ?? "Empty";
+ if (IsChanged(oldAfterFrom, newAfterFromStr))
{
- beforeChanges["AfterFrom"] = existingRecord.AfterFrom?.ToString(@"hh\:mm") ?? "Empty";
- afterChanges["AfterFrom"] = newAfterFrom?.ToString(@"hh\:mm") ?? "Empty";
+ beforeChanges["AfterFrom"] = oldAfterFrom;
+ afterChanges["AfterFrom"] = newAfterFromStr;
}
- if (existingRecord.AfterTo != newAfterTo)
+
+ string oldAfterTo = existingRecord.AfterTo?.ToString(@"hh\:mm") ?? "Empty";
+ string newAfterToStr = newAfterTo?.ToString(@"hh\:mm") ?? "Empty";
+ if (IsChanged(oldAfterTo, newAfterToStr))
{
- beforeChanges["AfterTo"] = existingRecord.AfterTo?.ToString(@"hh\:mm") ?? "Empty";
- afterChanges["AfterTo"] = newAfterTo?.ToString(@"hh\:mm") ?? "Empty";
+ beforeChanges["AfterTo"] = oldAfterTo;
+ afterChanges["AfterTo"] = newAfterToStr;
}
if ((existingRecord.AfterBreak ?? 0) != (updatedRecordDto.AfterBreak ?? 0))
{
@@ -2252,6 +2275,7 @@ namespace PSTW_CentralSystem.Controllers.API
ApproverUserId = currentLoggedInUserId,
UpdateTimestamp = DateTime.Now,
ChangeType = "Edit",
+ RecordDate = existingRecord.OtDate.ToString("yyyy-MM-dd"),
BeforeEdit = beforeChanges,
AfterEdit = afterChanges
};
@@ -2394,6 +2418,7 @@ namespace PSTW_CentralSystem.Controllers.API
ApproverUserId = currentLoggedInUserId,
UpdateTimestamp = DateTime.Now,
ChangeType = "Delete",
+ RecordDate = recordToDelete.OtDate.ToString("yyyy-MM-dd"),
DeletedRecord = cleanDeletedRecord
};