update user list / update Excel & PDF

This commit is contained in:
Naz 2026-04-09 16:27:49 +08:00
parent 9cd3c473cf
commit ed30316685
5 changed files with 258 additions and 226 deletions

View File

@ -36,10 +36,12 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
string? flexiHour = null,
byte[]? logoImage = null,
bool isSimplifiedExport = false,
OtStatusModel? otStatus = null)
OtStatusModel? otStatus = null,
bool hideSalaryDetails = false)
{
bool isAdminUser = IsAdmin(user.Id);
bool showStationColumn = user.Department?.DepartmentId == 3 || user.Department?.DepartmentId == 2 || isAdminUser;
bool hideSalary = hideSalaryDetails || isHoU || isHoD || isManager;
var stream = new MemoryStream();
@ -100,7 +102,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
}
else
{
if (isHoU || isHoD || isManager) // If HoU, HoD, or Manager, hide salary details
if (hideSalary) // If HoU, HoD, or Manager, hide salary details
{
if (showStationColumn)
{
@ -263,7 +265,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
decimal otAmtValParsed = 0;
string otAmt = "";
if (!isHoU && !isHoD && !isManager) // Only calculate and show OT amount if not HoU, HoD, or Manager
if (!hideSalary) // Only calculate and show OT amount if not HoU, HoD, or Manager
{
otAmt = CalculateOtAmount(record, hrp, publicHolidayDates, userSetting?.State?.WeekendId);
otAmtValParsed = decimal.TryParse(otAmt, out decimal val) ? val : 0;
@ -291,7 +293,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
grandTotalPh += currentRowTotalPh;
grandTotalOtAmount += otAmtValParsed; // Only add if it was calculated
if (!isHoU && !isHoD && !isManager) // Only show if not HoU, HoD, or Manager
if (!hideSalary) // Only show if not HoU, HoD, or Manager
{
// Basic Salary
worksheet.Cell(currentRow, col).Value = !hasPrintedSalaryDetails ? basicSalary.ToString("N2") : "";
@ -348,7 +350,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
worksheet.Cell(currentRow, col++).Value = currentRowTotalRd > 0 ? currentRowTotalRd.ToString("N2") : "";
worksheet.Cell(currentRow, col++).Value = currentRowTotalPh > 0 ? currentRowTotalPh.ToString("N2") : "";
if (!isHoU && !isHoD && !isManager) // Only show if not HoU, HoD, or Manager
if (!hideSalary) // Only show if not HoU, HoD, or Manager
{
worksheet.Cell(currentRow, col++).Value = otAmt == "0.00" ? "" : otAmt;
}
@ -415,7 +417,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
int totalLabelStartColumnIndex = 1;
int totalLabelEndColumnIndex;
if (!isHoU && !isHoD && !isManager) // If not HoU, HoD, or Manager, include salary columns in merge
if (!hideSalary) // If not HoU, HoD, or Manager, include salary columns in merge
{
totalLabelEndColumnIndex = 3;
}
@ -445,7 +447,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
int colTotalPhIndex = 0;
int colOtAmtIndex = 0;
if (!isHoU && !isHoD && !isManager)
if (!hideSalary)
{
colOfficeBreakIndex = 8;
colAfterBreakIndex = 11;
@ -500,7 +502,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
worksheet.Cell(currentRow, colTotalRdIndex).Value = grandTotalRd.ToString("N2");
worksheet.Cell(currentRow, colTotalPhIndex).Value = grandTotalPh.ToString("N2");
if (!isHoU && !isHoD && !isManager)
if (!hideSalary)
{
worksheet.Cell(currentRow, colOtAmtIndex).Value = Math.Round(grandTotalOtAmount, MidpointRounding.AwayFromZero).ToString("F2");
}
@ -697,7 +699,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
}
else
{
if (!isHoU && !isHoD && !isManager) // If not HoU, HoD, or Manager, include salary columns in width adjustment
if (!hideSalary) // If not HoU, HoD, or Manager, include salary columns in width adjustment
{
worksheet.Column(1).Width = 15; // Basic Salary
worksheet.Column(2).Width = 10; // ORP

View File

@ -68,8 +68,10 @@
</style>
<div id="reviewApp" style="max-width: 1300px; margin: auto; font-size: 13px;">
<div class="table-container table-responsive">
<div id="reviewApp" style="width: 100%; padding: 0 20px; font-size: 13px;">
<div class="table-container">
<div style="margin-bottom: 15px;">
<strong>Employee Name:</strong> {{ userInfo.fullName }}<br />
<strong>Department:</strong> {{ userInfo.departmentName || 'N/A' }}<br />
@ -83,7 +85,9 @@
</div>
</template>
</div>
<table class="table table-bordered table-sm table-striped">
<div class="table-responsive custom-scrollbar">
<table class="table table-bordered table-sm table-striped" style="min-width: 1500px;">
<thead>
<tr>
<th class="header-orange" rowspan="2" v-if="!isApproverRole(['HoU', 'HoD', 'Manager'])">Basic Salary<br>(RM)</th>
@ -229,12 +233,17 @@
</tfoot>
</table>
</div>
<div class="mt-3 d-flex flex-wrap gap-2">
<button class="btn btn-primary btn-sm" v-on:click="printPdf"><i class="bi bi-printer"></i> Print</button>
<button class="btn btn-dark btn-sm" v-on:click="saveAsPdf"><i class="bi bi-file-pdf"></i> Save</button>
<button class="btn btn-success btn-sm" v-on:click="exportToExcel"><i class="bi bi-file-earmark-excel"></i> Excel</button>
</div>
<div class="mt-3 d-flex flex-wrap gap-2">
<button class="btn btn-primary btn-sm" v-on:click="printPdf(false)"><i class="bi bi-printer"></i> Print</button>
<button class="btn btn-dark btn-sm" v-on:click="saveAsPdf(false)"><i class="bi bi-file-pdf"></i> Save</button>
<button class="btn btn-success btn-sm" v-on:click="exportToExcel(false)"><i class="bi bi-file-earmark-excel"></i> Excel</button>
</div>
<div class="mt-3 d-flex flex-wrap gap-2">
<button class="btn btn-primary btn-sm" v-on:click="printPdf(true)"><i class="bi bi-printer"></i> Print No Salary</button>
<button class="btn btn-dark btn-sm" v-on:click="saveAsPdf(true)"><i class="bi bi-file-pdf"></i> Save No Salary</button>
<button class="btn btn-success btn-sm" v-on:click="exportToExcel(true)"><i class="bi bi-file-earmark-excel"></i> Excel No Salary</button>
</div>
<div class="modal fade" id="editOtModal" tabindex="-1" aria-labelledby="editOtModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
@ -1212,11 +1221,11 @@
alert("Error deleting record: " + err.message);
});
},
saveAsPdf() {
saveAsPdf(hideSalary = false) {
const params = new URLSearchParams(window.location.search);
const statusId = params.get("statusId");
fetch(`/OvertimeAPI/GetOvertimePdfByStatusId/${statusId}`)
fetch(`/OvertimeAPI/GetOvertimePdfByStatusId/${statusId}?hideSalary=${hideSalary}`)
.then(response => {
if (!response.ok) throw new Error("Failed to generate PDF");
const disposition = response.headers.get("Content-Disposition");
@ -1245,11 +1254,11 @@
alert("Failed to generate PDF. Please try again later.");
});
},
printPdf() {
printPdf(hideSalary = false) {
const params = new URLSearchParams(window.location.search);
const statusId = params.get("statusId");
fetch(`/OvertimeAPI/GetOvertimePdfByStatusId/${statusId}`)
fetch(`/OvertimeAPI/GetOvertimePdfByStatusId/${statusId}?hideSalary=${hideSalary}`)
.then(response => {
if (!response.ok) throw new Error("Failed to fetch PDF for printing.");
return response.blob();
@ -1273,11 +1282,11 @@
alert("Failed to prepare PDF for printing. Please try again later.");
});
},
exportToExcel() {
exportToExcel(hideSalary = false) {
const params = new URLSearchParams(window.location.search);
const statusId = params.get("statusId");
fetch(`/OvertimeAPI/GetOvertimeExcelByStatusId/${statusId}`)
fetch(`/OvertimeAPI/GetOvertimeExcelByStatusId/${statusId}?hideSalary=${hideSalary}`)
.then(response => {
if (!response.ok) throw new Error("Failed to generate Excel");
const disposition = response.headers.get("Content-Disposition");

View File

@ -154,7 +154,7 @@
},
async fetchUser() {
try {
const response = await fetch(`/InvMainAPI/UserList/`, { method: 'POST' });
const response = await fetch(`/OvertimeAPI/UserList/`, { method: 'POST' });
if (response.ok) {
const data = await response.json();
this.userList = data.filter(e => e.fullName !== "MAAdmin" && e.fullName !== "SysAdmin");

View File

@ -66,7 +66,7 @@
}
</style>
<div id="app" style="max-width: 1300px; margin: auto; font-size: 13px;">
<div id="app" style="width: 100%; padding: 0 20px; font-size: 13px;">
<div class="mb-3 d-flex flex-wrap">
<div class="me-2 mb-2">
<label>Month</label>
@ -82,8 +82,11 @@
</div>
</div>
<div id="print-section" class="table-container table-responsive">
<table class="table table-bordered table-sm table-striped">
<div id="print-section" class="table-container">
<div class="table-responsive custom-scrollbar">
<table class="table table-bordered table-sm table-striped" style="min-width: 1200px;">
<thead>
<tr>
<th class="header-green" rowspan="2">Date</th>
@ -156,6 +159,7 @@
</tbody>
</table>
</div>
</div>
<div class="mt-3 d-flex flex-wrap gap-2">
<button class="btn btn-primary btn-sm" v-on:click="printPdf" :disabled="noRecordsFound"><i class="bi bi-printer"></i> Print</button>

View File

@ -51,6 +51,22 @@ namespace PSTW_CentralSystem.Controllers.API
_env = env;
}
[HttpPost("UserList")]
public async Task<IActionResult> UserList()
{
var userList = await _centralDbContext.Users
.Include(i => i.Department)
.ToListAsync();
return Json(userList.Select(i => new
{
i.Id,
i.FullName,
i.Department,
i.Department?.DepartmentName,
}));
}
#region Settings
[HttpGet("GetUpdateDates")]
@ -2478,7 +2494,7 @@ namespace PSTW_CentralSystem.Controllers.API
#region OT Review/ OT Record PDF Excel
[HttpGet("GetOvertimePdfByStatusId/{statusId}")]
public IActionResult GetOvertimePdfByStatusId(int statusId)
public IActionResult GetOvertimePdfByStatusId(int statusId, [FromQuery] bool hideSalary = false)
{
var otStatus = _centralDbContext.Otstatus.FirstOrDefault(s => s.StatusId == statusId);
if (otStatus == null)
@ -2519,14 +2535,14 @@ namespace PSTW_CentralSystem.Controllers.API
.FirstOrDefault(us => us.UserId == user.Id);
// Determine if the current logged-in user is HoU, HoD, or Manager for the OT user
bool hideSalaryDetails = false;
bool hideSalaryDetails = hideSalary; // Start with the button's request
if (userSetting?.Approvalflow != null)
{
if (userSetting.Approvalflow.HoU == currentLoggedInUserId ||
userSetting.Approvalflow.HoD == currentLoggedInUserId ||
userSetting.Approvalflow.Manager == currentLoggedInUserId)
{
hideSalaryDetails = true;
hideSalaryDetails = true; // Override to true if they are a manager
}
}
@ -2629,7 +2645,7 @@ namespace PSTW_CentralSystem.Controllers.API
}
[HttpGet("GetOvertimeExcelByStatusId/{statusId}")]
public IActionResult GetOvertimeExcelByStatusId(int statusId)
public IActionResult GetOvertimeExcelByStatusId(int statusId, [FromQuery] bool hideSalary = false)
{
var otStatus = _centralDbContext.Otstatus.FirstOrDefault(s => s.StatusId == statusId);
if (otStatus == null)
@ -2700,7 +2716,8 @@ namespace PSTW_CentralSystem.Controllers.API
flexiHour,
logoImage,
isSimplifiedExport: false,
otStatus
otStatus,
hideSalaryDetails: hideSalary
);
string fileName = $"OvertimeReport_{user.FullName}_{DateTime.Now:yyyyMMdd}.xlsx";