LAST 13/06/2025

This commit is contained in:
Naz 2025-06-13 09:38:16 +08:00
parent efd69601ec
commit 4e7c5757e0
6 changed files with 318 additions and 247 deletions

View File

@ -28,11 +28,6 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Controllers
return View(); return View();
} }
public IActionResult OtApproval()
{
return View();
}
public IActionResult Settings() public IActionResult Settings()
{ {
return View(); return View();

View File

@ -31,6 +31,8 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
decimal userRate, decimal userRate,
DateTime? selectedMonth = null, DateTime? selectedMonth = null,
bool isHoU = false, bool isHoU = false,
bool isHoD = false,
bool isManager = false,
string? flexiHour = null, string? flexiHour = null,
byte[]? logoImage = null, byte[]? logoImage = null,
bool isSimplifiedExport = false, bool isSimplifiedExport = false,
@ -98,19 +100,18 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
} }
else else
{ {
if (isHoU || isHoD || isManager) // If HoU, HoD, or Manager, hide salary details
if (isHoU)
{ {
if (showStationColumn) if (showStationColumn)
{ {
AddHoUPSTWAirHeaders(worksheet, ref currentRow); AddHoUPSTWAirHeaders(worksheet, ref currentRow); // This already excludes salary info
} }
else else
{ {
AddHoUNonPSTWAirHeaders(worksheet, ref currentRow); AddHoUNonPSTWAirHeaders(worksheet, ref currentRow); // This already excludes salary info
} }
} }
else else // For other users (who are not HoU, HoD, or Manager)
{ {
if (showStationColumn) if (showStationColumn)
{ {
@ -236,7 +237,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
descriptionCell.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Left; descriptionCell.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Left;
} }
else else // Not simplified export
{ {
var dayType = GetDayType(date, userSetting?.State?.WeekendId, publicHolidayDates); var dayType = GetDayType(date, userSetting?.State?.WeekendId, publicHolidayDates);
var classified = ClassifyOt(record, hrp, publicHolidayDates, userSetting?.State?.WeekendId); var classified = ClassifyOt(record, hrp, publicHolidayDates, userSetting?.State?.WeekendId);
@ -259,7 +260,15 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
decimal currentRowTotalRd = currentRdUnder4 + currentRd4to8 + currentRdAfter; decimal currentRowTotalRd = currentRdUnder4 + currentRd4to8 + currentRdAfter;
decimal currentRowTotalPh = currentPhUnder8 + currentPhAfter; decimal currentRowTotalPh = currentPhUnder8 + currentPhAfter;
var otAmt = CalculateOtAmount(record, hrp, publicHolidayDates, userSetting?.State?.WeekendId); decimal otAmtValParsed = 0;
string otAmt = "";
if (!isHoU && !isHoD && !isManager) // 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;
}
totalOfficeBreak += (decimal)record.OfficeBreak.GetValueOrDefault(0); totalOfficeBreak += (decimal)record.OfficeBreak.GetValueOrDefault(0);
totalAfterBreak += (decimal)record.AfterBreak.GetValueOrDefault(0); totalAfterBreak += (decimal)record.AfterBreak.GetValueOrDefault(0);
@ -280,9 +289,9 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
grandTotalNdOd += currentRowTotalNdOd; grandTotalNdOd += currentRowTotalNdOd;
grandTotalRd += currentRowTotalRd; grandTotalRd += currentRowTotalRd;
grandTotalPh += currentRowTotalPh; grandTotalPh += currentRowTotalPh;
grandTotalOtAmount += decimal.TryParse(otAmt, out decimal otAmtVal) ? otAmtVal : 0; grandTotalOtAmount += otAmtValParsed; // Only add if it was calculated
if (!isHoU) if (!isHoU && !isHoD && !isManager) // Only show if not HoU, HoD, or Manager
{ {
// Basic Salary // Basic Salary
worksheet.Cell(currentRow, col).Value = !hasPrintedSalaryDetails ? basicSalary.ToString("N2") : ""; worksheet.Cell(currentRow, col).Value = !hasPrintedSalaryDetails ? basicSalary.ToString("N2") : "";
@ -294,7 +303,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
worksheet.Cell(currentRow, col).Value = !hasPrintedSalaryDetails ? hrp.ToString("N2") : ""; worksheet.Cell(currentRow, col).Value = !hasPrintedSalaryDetails ? hrp.ToString("N2") : "";
worksheet.Cell(currentRow, col++).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; worksheet.Cell(currentRow, col++).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
} }
hasPrintedSalaryDetails = true; hasPrintedSalaryDetails = true; // Ensure these are printed only once if visible
var dayCell = worksheet.Cell(currentRow, col); var dayCell = worksheet.Cell(currentRow, col);
var dateCell = worksheet.Cell(currentRow, col + 1); var dateCell = worksheet.Cell(currentRow, col + 1);
@ -339,7 +348,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
worksheet.Cell(currentRow, col++).Value = currentRowTotalRd > 0 ? currentRowTotalRd.ToString("N2") : ""; worksheet.Cell(currentRow, col++).Value = currentRowTotalRd > 0 ? currentRowTotalRd.ToString("N2") : "";
worksheet.Cell(currentRow, col++).Value = currentRowTotalPh > 0 ? currentRowTotalPh.ToString("N2") : ""; worksheet.Cell(currentRow, col++).Value = currentRowTotalPh > 0 ? currentRowTotalPh.ToString("N2") : "";
if (!isHoU) if (!isHoU && !isHoD && !isManager) // Only show if not HoU, HoD, or Manager
{ {
worksheet.Cell(currentRow, col++).Value = otAmt == "0.00" ? "" : otAmt; worksheet.Cell(currentRow, col++).Value = otAmt == "0.00" ? "" : otAmt;
} }
@ -406,7 +415,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
int totalLabelStartColumnIndex = 1; int totalLabelStartColumnIndex = 1;
int totalLabelEndColumnIndex; int totalLabelEndColumnIndex;
if (!isHoU) if (!isHoU && !isHoD && !isManager) // If not HoU, HoD, or Manager, include salary columns in merge
{ {
totalLabelEndColumnIndex = 3; totalLabelEndColumnIndex = 3;
} }
@ -436,7 +445,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
int colTotalPhIndex = 0; int colTotalPhIndex = 0;
int colOtAmtIndex = 0; int colOtAmtIndex = 0;
if (!isHoU) if (!isHoU && !isHoD && !isManager)
{ {
colOfficeBreakIndex = 8; colOfficeBreakIndex = 8;
colAfterBreakIndex = 11; colAfterBreakIndex = 11;
@ -491,7 +500,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
worksheet.Cell(currentRow, colTotalRdIndex).Value = grandTotalRd.ToString("N2"); worksheet.Cell(currentRow, colTotalRdIndex).Value = grandTotalRd.ToString("N2");
worksheet.Cell(currentRow, colTotalPhIndex).Value = grandTotalPh.ToString("N2"); worksheet.Cell(currentRow, colTotalPhIndex).Value = grandTotalPh.ToString("N2");
if (!isHoU) if (!isHoU && !isHoD && !isManager)
{ {
worksheet.Cell(currentRow, colOtAmtIndex).Value = Math.Round(grandTotalOtAmount, MidpointRounding.AwayFromZero).ToString("F2"); worksheet.Cell(currentRow, colOtAmtIndex).Value = Math.Round(grandTotalOtAmount, MidpointRounding.AwayFromZero).ToString("F2");
} }
@ -688,7 +697,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
} }
else else
{ {
if (!isHoU) if (!isHoU && !isHoD && !isManager) // If not HoU, HoD, or Manager, include salary columns in width adjustment
{ {
worksheet.Column(1).Width = 15; // Basic Salary worksheet.Column(1).Width = 15; // Basic Salary
worksheet.Column(2).Width = 10; // ORP worksheet.Column(2).Width = 10; // ORP
@ -714,7 +723,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
int descColIndex = showStationColumn ? 29 : 28; int descColIndex = showStationColumn ? 29 : 28;
worksheet.Column(descColIndex).Width = 60; worksheet.Column(descColIndex).Width = 60;
} }
else else // If HoU, HoD, or Manager, adjust columns without salary info
{ {
worksheet.Column(1).Width = 10; worksheet.Column(1).Width = 10;
worksheet.Column(2).Width = 12; worksheet.Column(2).Width = 12;
@ -729,12 +738,12 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
worksheet.Column(9).Width = 15; worksheet.Column(9).Width = 15;
worksheet.Column(10).Width = 18; worksheet.Column(10).Width = 18;
for (int i = 11; i <= 23; i++) for (int i = 11; i <= 23; i++) // Adjust based on new column count
{ {
worksheet.Column(i).Width = 12; worksheet.Column(i).Width = 12;
} }
int descColIndex = showStationColumn ? 25 : 24; int descColIndex = showStationColumn ? 25 : 24; // Adjust based on new column count
worksheet.Column(descColIndex).Width = 60; worksheet.Column(descColIndex).Width = 60;
} }
} }
@ -1726,7 +1735,6 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
rowIndex++; rowIndex++;
} }
private uint GetDayCellColorStyleIndex(DateTime date, int? weekendId, List<DateTime> publicHolidays) private uint GetDayCellColorStyleIndex(DateTime date, int? weekendId, List<DateTime> publicHolidays)
{ {
if (publicHolidays.Contains(date.Date)) if (publicHolidays.Contains(date.Date))

View File

@ -27,7 +27,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
decimal userRate, decimal userRate,
DateTime? selectedMonth = null, DateTime? selectedMonth = null,
byte[]? logoImage = null, byte[]? logoImage = null,
bool isHoU = false, bool isRestrictedUser = false,
string? flexiHour = null, string? flexiHour = null,
List<ApprovalSignatureData>? approvedSignatures = null) List<ApprovalSignatureData>? approvedSignatures = null)
{ {
@ -117,7 +117,8 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
column.Item().PaddingVertical(10).LineHorizontal(0.5f).LineColor(Colors.Grey.Lighten2); column.Item().PaddingVertical(10).LineHorizontal(0.5f).LineColor(Colors.Grey.Lighten2);
column.Item().Element(container => ComposeTable(container, records, user, userRate, showStationColumn, allDatesInMonth, isHoU, publicHolidaysForUser.Select(h => h.HolidayDate.Date).ToList())); // Pass the new isRestrictedUser flag to ComposeTable
column.Item().Element(container => ComposeTable(container, records, user, userRate, showStationColumn, allDatesInMonth, isRestrictedUser, publicHolidaysForUser.Select(h => h.HolidayDate.Date).ToList()));
column.Item().PaddingTop(20).Element(container => column.Item().PaddingTop(20).Element(container =>
{ {
@ -216,7 +217,8 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
return stream; return stream;
} }
private void ComposeTable(IContainer container, List<OtRegisterModel> records, UserModel user, decimal userRate, bool showStationColumn, List<DateTime> allDatesInMonth, bool isHoU, List<DateTime> publicHolidays) // Update the signature of ComposeTable to accept the new flag
private void ComposeTable(IContainer container, List<OtRegisterModel> records, UserModel user, decimal userRate, bool showStationColumn, List<DateTime> allDatesInMonth, bool hideSalaryDetails, List<DateTime> publicHolidays)
{ {
var recordsGroupedByDate = records var recordsGroupedByDate = records
.GroupBy(r => r.OtDate.Date) .GroupBy(r => r.OtDate.Date)
@ -230,7 +232,8 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
{ {
table.ColumnsDefinition(columns => table.ColumnsDefinition(columns =>
{ {
if (!isHoU) // Conditionally add salary columns based on hideSalaryDetails
if (!hideSalaryDetails)
{ {
columns.RelativeColumn(0.25f); // Basic Salary columns.RelativeColumn(0.25f); // Basic Salary
columns.RelativeColumn(0.2f); // ORP columns.RelativeColumn(0.2f); // ORP
@ -259,7 +262,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
columns.RelativeColumn(0.3f); columns.RelativeColumn(0.3f);
columns.RelativeColumn(0.2f); columns.RelativeColumn(0.2f);
columns.RelativeColumn(0.2f); columns.RelativeColumn(0.2f);
if (!isHoU) if (!hideSalaryDetails) // Conditionally add Total Amt column
{ {
columns.RelativeColumn(0.25f); columns.RelativeColumn(0.25f);
} }
@ -274,7 +277,8 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
table.Header(header => table.Header(header =>
{ {
if (!isHoU) // Conditionally add salary headers based on hideSalaryDetails
if (!hideSalaryDetails)
{ {
header.Cell().RowSpan(2).Background("#fce5cd").Border(0.25f).Padding(3).Text("Basic Salary\n(RM)").FontSize(6).Bold().AlignCenter(); header.Cell().RowSpan(2).Background("#fce5cd").Border(0.25f).Padding(3).Text("Basic Salary\n(RM)").FontSize(6).Bold().AlignCenter();
header.Cell().RowSpan(2).Background("#fce5cd").Border(0.25f).Padding(3).Text("ORP").FontSize(6).Bold().AlignCenter(); header.Cell().RowSpan(2).Background("#fce5cd").Border(0.25f).Padding(3).Text("ORP").FontSize(6).Bold().AlignCenter();
@ -299,7 +303,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
header.Cell().RowSpan(2).Background("#fdebd0").Border(0.25f).Padding(3).Text("Total\nRD").FontSize(6).Bold().AlignCenter(); header.Cell().RowSpan(2).Background("#fdebd0").Border(0.25f).Padding(3).Text("Total\nRD").FontSize(6).Bold().AlignCenter();
header.Cell().RowSpan(2).Background("#fdebd0").Border(0.25f).Padding(3).Text("Total\nPH").FontSize(6).Bold().AlignCenter(); header.Cell().RowSpan(2).Background("#fdebd0").Border(0.25f).Padding(3).Text("Total\nPH").FontSize(6).Bold().AlignCenter();
if (!isHoU) if (!hideSalaryDetails) // Conditionally add Total Amt header
{ {
header.Cell().RowSpan(2).Background("#fce5cd").Border(0.25f).Padding(3).Text("OT Amt\n(RM)").FontSize(6).Bold().AlignCenter(); header.Cell().RowSpan(2).Background("#fce5cd").Border(0.25f).Padding(3).Text("OT Amt\n(RM)").FontSize(6).Bold().AlignCenter();
} }
@ -413,7 +417,8 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
if (center) text.AlignCenter(); if (center) text.AlignCenter();
} }
if (!isHoU) // Conditionally render salary details
if (!hideSalaryDetails)
{ {
// Display the calculated values here // Display the calculated values here
AddCell(!hasPrintedSalaryDetails ? $"{basicSalary:F2}" : ""); AddCell(!hasPrintedSalaryDetails ? $"{basicSalary:F2}" : "");
@ -455,7 +460,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
AddCell(totalNdOd); AddCell(totalNdOd);
AddCell(totalRd); AddCell(totalRd);
AddCell(totalPh); AddCell(totalPh);
if (!isHoU) if (!hideSalaryDetails) // Conditionally render Total Amt column
{ {
AddCell(otAmt == "0.00" ? "" : otAmt); AddCell(otAmt == "0.00" ? "" : otAmt);
} }
@ -473,7 +478,8 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
} }
} }
if (!isHoU) // Adjust column span for the TOTAL row based on visibility
if (!hideSalaryDetails)
{ {
table.Cell().ColumnSpan(5).Background("#d8d1f5").Border(0.80f).Padding(3) table.Cell().ColumnSpan(5).Background("#d8d1f5").Border(0.80f).Padding(3)
.Text("TOTAL").Bold().FontSize(6).AlignCenter(); .Text("TOTAL").Bold().FontSize(6).AlignCenter();
@ -540,7 +546,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
table.Cell().Background("#d8d1f5").Border(0.80f).Padding(3) table.Cell().Background("#d8d1f5").Border(0.80f).Padding(3)
.Text($"{grandTotalPh:N2}").Bold().FontSize(6).AlignCenter(); .Text($"{grandTotalPh:N2}").Bold().FontSize(6).AlignCenter();
if (!isHoU) if (!hideSalaryDetails) // Conditionally render Total Amt in footer
{ {
table.Cell().Background("#d8d1f5").Border(0.80f).Padding(3) table.Cell().Background("#d8d1f5").Border(0.80f).Padding(3)
.Text($"{Math.Round(grandTotalOtAmount, MidpointRounding.AwayFromZero):F2}").Bold().FontSize(6).AlignCenter(); .Text($"{Math.Round(grandTotalOtAmount, MidpointRounding.AwayFromZero):F2}").Bold().FontSize(6).AlignCenter();
@ -687,7 +693,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
else else
{ {
table.Cell().ColumnSpan(2).Border(0.25f).Padding(2) table.Cell().ColumnSpan(2).Border(0.25f).Padding(2)
.Text($"No public holidays found for {userSetting?.State?.StateName ?? "this state"} in {displayMonth:MMMM yyyy}.") // Changed format .Text($"No public holidays found for {userSetting?.State?.StateName ?? "this state"} in {displayMonth:MMMM yyyy}.")
.FontSize(7).Italic().AlignCenter(); .FontSize(7).Italic().AlignCenter();
} }
}); });
@ -1105,7 +1111,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
{ {
result["phUnder8"] = toFixedOrEmpty(officeHrs); // Assign all to 'under 8' result["phUnder8"] = toFixedOrEmpty(officeHrs); // Assign all to 'under 8'
} }
else // If total office hours are more than 8 else
{ {
result["phAfter"] = toFixedOrEmpty(officeHrs); // Assign all to 'PH After' (for office hours beyond 8) result["phAfter"] = toFixedOrEmpty(officeHrs); // Assign all to 'PH After' (for office hours beyond 8)
} }

View File

@ -86,9 +86,9 @@
<table class="table table-bordered table-sm table-striped"> <table class="table table-bordered table-sm table-striped">
<thead> <thead>
<tr> <tr>
<th class="header-orange" rowspan="2" v-if="!isHoU">Basic Salary<br>(RM)</th> <th class="header-orange" rowspan="2" v-if="!isApproverRole(['HoU', 'HoD', 'Manager'])">Basic Salary<br>(RM)</th>
<th class="header-orange" rowspan="2" v-if="!isHoU">ORP</th> <th class="header-orange" rowspan="2" v-if="!isApproverRole(['HoU', 'HoD', 'Manager'])">ORP</th>
<th class="header-orange" rowspan="2" v-if="!isHoU">HRP</th> <th class="header-orange" rowspan="2" v-if="!isApproverRole(['HoU', 'HoD', 'Manager'])">HRP</th>
<th class="header-green text-nowrap" rowspan="2">Date</th> <th class="header-green text-nowrap" rowspan="2">Date</th>
<th class="header-blue" colspan="3">Office Hour</th> <th class="header-blue" colspan="3">Office Hour</th>
<th class="header-blue" colspan="3">After Office Hour</th> <th class="header-blue" colspan="3">After Office Hour</th>
@ -102,7 +102,7 @@
<th class="header-green" rowspan="2">Total OT Hrs<br>ND & OD</th> <th class="header-green" rowspan="2">Total OT Hrs<br>ND & OD</th>
<th class="header-green" rowspan="2">Total OT Hrs<br>RD</th> <th class="header-green" rowspan="2">Total OT Hrs<br>RD</th>
<th class="header-green" rowspan="2">Total OT Hrs<br>PH</th> <th class="header-green" rowspan="2">Total OT Hrs<br>PH</th>
<th class="header-green" rowspan="2" v-if="!isHoU">OT Amt (RM)</th> <th class="header-green" rowspan="2" v-if="!isApproverRole(['HoU', 'HoD', 'Manager'])">OT Amt (RM)</th>
<th class="header-orange" rowspan="2" v-if="showStationColumn">Station</th> <th class="header-orange" rowspan="2" v-if="showStationColumn">Station</th>
<th class="header-blue" rowspan="2">Description</th> <th class="header-blue" rowspan="2">Description</th>
<th class="header-green" rowspan="2">Action</th> <th class="header-green" rowspan="2">Action</th>
@ -127,7 +127,7 @@
</thead> </thead>
<tbody> <tbody>
<tr v-for="(record, index) in sortedOtRecords" :key="record.overtimeId"> <tr v-for="(record, index) in sortedOtRecords" :key="record.overtimeId">
<template v-if="index === 0 && !isHoU"> <template v-if="index === 0 && !isApproverRole(['HoU', 'HoD', 'Manager'])">
<td :rowspan="sortedOtRecords.length" class="text-nowrap">{{ calculateBasicSalary() }}</td> <td :rowspan="sortedOtRecords.length" class="text-nowrap">{{ calculateBasicSalary() }}</td>
<td :rowspan="sortedOtRecords.length" class="text-nowrap">{{ calculateOrp() }}</td> <td :rowspan="sortedOtRecords.length" class="text-nowrap">{{ calculateOrp() }}</td>
<td :rowspan="sortedOtRecords.length" class="text-nowrap">{{ calculateHrp() }}</td> <td :rowspan="sortedOtRecords.length" class="text-nowrap">{{ calculateHrp() }}</td>
@ -162,7 +162,7 @@
<td>{{ calculateRdTotal(record) }}</td> <td>{{ calculateRdTotal(record) }}</td>
<td>{{ calculatePhTotal(record) }}</td> <td>{{ calculatePhTotal(record) }}</td>
<td v-if="!isHoU">{{ calculateOtAmount(record) }}</td> <td v-if="!isApproverRole(['HoU', 'HoD', 'Manager'])">{{ calculateOtAmount(record) }}</td>
<td v-if="showStationColumn">{{ record.stationName || 'N/A' }}</td> <td v-if="showStationColumn">{{ record.stationName || 'N/A' }}</td>
<td class="wrap-text"> <td class="wrap-text">
@ -184,23 +184,23 @@
</td> </td>
</tr> </tr>
<tr v-if="otRecords.length === 0"> <tr v-if="otRecords.length === 0">
<td :colspan="showStationColumn ? (isHoU ? 27 : 31) : (isHoU ? 26 : 30)">No overtime details found for this submission.</td> <td :colspan="showStationColumn ? (isApproverRole(['HoU', 'HoD', 'Manager']) ? 27 : 31) : (isApproverRole(['HoU', 'HoD', 'Manager']) ? 26 : 30)">No overtime details found for this submission.</td>
</tr> </tr>
</tbody> </tbody>
<tfoot> <tfoot>
<tr class="fw-bold bg-light"> <tr class="fw-bold bg-light">
<td v-if="!isHoU" colspan="3">TOTAL</td> <td v-if="!isApproverRole(['HoU', 'HoD', 'Manager'])" colspan="3">TOTAL</td>
<td v-else colspan="1">TOTAL</td> <td v-else colspan="1">TOTAL</td>
<td v-if="!isHoU" colspan="3"></td> <td v-if="!isApproverRole(['HoU', 'HoD', 'Manager'])" colspan="3"></td>
<td v-else colspan="2"></td> <td v-else colspan="2"></td>
<td><strong>{{ formatBreakToHourMinute(totals.officeBreak) }}</strong></td> <td><strong>{{ formatBreakToHourMinute(totals.officeBreak) }}</strong></td>
<td v-if="!isHoU" colspan="2"></td> <td v-if="!isApproverRole(['HoU', 'HoD', 'Manager'])" colspan="2"></td>
<td v-else colspan="2"></td> <td v-else colspan="2"></td>
<td><strong>{{ formatBreakToHourMinute(totals.afterBreak) }}</strong></td> <td><strong>{{ formatBreakToHourMinute(totals.afterBreak) }}</strong></td>
<td v-if="!isHoU" colspan="2"></td> <td v-if="!isApproverRole(['HoU', 'HoD', 'Manager'])" colspan="2"></td>
<td v-else colspan="2"></td> <td v-else colspan="2"></td>
<td>{{ totals.ndAfter }}</td> <td>{{ totals.ndAfter }}</td>
@ -220,7 +220,7 @@
<td>{{ totals.totalRd }}</td> <td>{{ totals.totalRd }}</td>
<td>{{ totals.totalPh }}</td> <td>{{ totals.totalPh }}</td>
<td v-if="!isHoU">{{ totals.otAmt }}</td> <td v-if="!isApproverRole(['HoU', 'HoD', 'Manager'])">{{ totals.otAmt }}</td>
<td v-if="showStationColumn"></td> <td v-if="showStationColumn"></td>
@ -387,7 +387,7 @@
weekendId: null, weekendId: null,
basicSalary: null basicSalary: null
}, },
isHoU: false, isHoU: false, // Keep this for existing logic, but use isApproverRole for salary visibility
expandedDescriptions: [], expandedDescriptions: [],
currentEditRecord: { currentEditRecord: {
overtimeId: null, overtimeId: null,
@ -545,6 +545,10 @@
} }
}, },
methods: { methods: {
// New method to check if the current approver role is in the list of roles to hide salary info
isApproverRole(rolesToHide) {
return rolesToHide.includes(this.approverRole);
},
toggleDescription(index) { toggleDescription(index) {
this.expandedDescriptions[index] = !this.expandedDescriptions[index]; this.expandedDescriptions[index] = !this.expandedDescriptions[index];
}, },
@ -562,6 +566,7 @@
...data.userInfo, ...data.userInfo,
basicSalary: data.userInfo.rate basicSalary: data.userInfo.rate
}; };
// No change here for isHoU, as it's used for other logic (like edit/delete buttons)
this.isHoU = data.isHoU; this.isHoU = data.isHoU;
this.currentEditRecord.statusId = parseInt(statusId); this.currentEditRecord.statusId = parseInt(statusId);
@ -1189,7 +1194,7 @@
const end = this.parseTime(toTime); const end = this.parseTime(toTime);
const minAllowedFromMinutesForMidnightTo = 16 * 60 + 30; const minAllowedFromMinutesForMidnightTo = 16 * 60 + 30;
const maxAllowedFromMinutesForMidnightTo = 23 * 60 + 30; const maxAllowedFromMidnightTo = 23 * 60 + 30;
const startMinutes = start.hours * 60 + start.minutes; const startMinutes = start.hours * 60 + start.minutes;
if (end.hours === 0 && end.minutes === 0) { if (end.hours === 0 && end.minutes === 0) {
@ -1197,7 +1202,7 @@
alert(`Invalid ${label} Time: 'From' and 'To' cannot both be 00:00 (midnight).`); alert(`Invalid ${label} Time: 'From' and 'To' cannot both be 00:00 (midnight).`);
return false; return false;
} }
if (startMinutes < minAllowedFromMinutesForMidnightTo || startMinutes > maxAllowedFromMinutesForMidnightTo) { if (startMinutes < minAllowedFromMidnightTo || startMinutes > maxAllowedFromMidnightTo) {
alert(`Invalid ${label} Time: If 'To' is 12:00 am (00:00), 'From' must start between 4:30 pm and 11:30 pm on the same day to be saved.`); alert(`Invalid ${label} Time: If 'To' is 12:00 am (00:00), 'From' must start between 4:30 pm and 11:30 pm on the same day to be saved.`);
return false; return false;
} }

View File

@ -2286,11 +2286,18 @@ namespace PSTW_CentralSystem.Controllers.API
.Include(us => us.FlexiHour) .Include(us => us.FlexiHour)
.FirstOrDefault(us => us.UserId == user.Id); .FirstOrDefault(us => us.UserId == user.Id);
bool isHoU = false; // Determine if the current logged-in user is HoU, HoD, or Manager for the OT user
if (userSetting?.Approvalflow != null && userSetting.Approvalflow.HoU == currentLoggedInUserId) bool hideSalaryDetails = false;
if (userSetting?.Approvalflow != null)
{ {
isHoU = true; if (userSetting.Approvalflow.HoU == currentLoggedInUserId ||
userSetting.Approvalflow.HoD == currentLoggedInUserId ||
userSetting.Approvalflow.Manager == currentLoggedInUserId)
{
hideSalaryDetails = true;
} }
}
string? flexiHour = userSetting?.FlexiHour?.FlexiHour; string? flexiHour = userSetting?.FlexiHour?.FlexiHour;
@ -2328,7 +2335,8 @@ namespace PSTW_CentralSystem.Controllers.API
} }
var pdfGenerator = new OvertimePDF(_centralDbContext); var pdfGenerator = new OvertimePDF(_centralDbContext);
var stream = pdfGenerator.GenerateOvertimeTablePdf(otRecords, user, userRate, selectedMonth, logoImage, isHoU, flexiHour, approvedSignatures); // Pass the new hideSalaryDetails flag to the PDF generator
var stream = pdfGenerator.GenerateOvertimeTablePdf(otRecords, user, userRate, selectedMonth, logoImage, hideSalaryDetails, flexiHour, approvedSignatures);
string fileName = $"OvertimeReport_{user.FullName}_{DateTime.Now:yyyyMMdd}.pdf"; string fileName = $"OvertimeReport_{user.FullName}_{DateTime.Now:yyyyMMdd}.pdf";
return File(stream.ToArray(), "application/pdf", fileName); return File(stream.ToArray(), "application/pdf", fileName);
@ -2423,10 +2431,24 @@ namespace PSTW_CentralSystem.Controllers.API
.FirstOrDefault(us => us.UserId == user.Id); .FirstOrDefault(us => us.UserId == user.Id);
bool isHoU = false; bool isHoU = false;
if (userSetting?.Approvalflow != null && userSetting.Approvalflow.HoU == currentLoggedInUserId) bool isHoD = false; // Initialize isHoD
bool isManager = false; // Initialize isManager
if (userSetting?.Approvalflow != null)
{
if (userSetting.Approvalflow.HoU == currentLoggedInUserId)
{ {
isHoU = true; isHoU = true;
} }
if (userSetting.Approvalflow.HoD == currentLoggedInUserId) // Check if current user is HoD
{
isHoD = true;
}
if (userSetting.Approvalflow.Manager == currentLoggedInUserId) // Check if current user is Manager
{
isManager = true;
}
}
string? flexiHour = userSetting?.FlexiHour?.FlexiHour; string? flexiHour = userSetting?.FlexiHour?.FlexiHour;
@ -2435,7 +2457,19 @@ namespace PSTW_CentralSystem.Controllers.API
var logoPath = Path.Combine(_env.WebRootPath, "images", "logo.jpg"); var logoPath = Path.Combine(_env.WebRootPath, "images", "logo.jpg");
byte[]? logoImage = System.IO.File.Exists(logoPath) ? System.IO.File.ReadAllBytes(logoPath) : null; byte[]? logoImage = System.IO.File.Exists(logoPath) ? System.IO.File.ReadAllBytes(logoPath) : null;
var stream = excelGenerator.GenerateOvertimeExcel(otRecords, user, userRate, selectedMonth, isHoU, flexiHour, logoImage, isSimplifiedExport: false, otStatus); var stream = excelGenerator.GenerateOvertimeExcel(
otRecords,
user,
userRate,
selectedMonth,
isHoU,
isHoD, // Pass isHoD
isManager, // Pass isManager
flexiHour,
logoImage,
isSimplifiedExport: false,
otStatus
);
string fileName = $"OvertimeReport_{user.FullName}_{DateTime.Now:yyyyMMdd}.xlsx"; string fileName = $"OvertimeReport_{user.FullName}_{DateTime.Now:yyyyMMdd}.xlsx";
return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName); return File(stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
@ -2460,6 +2494,7 @@ namespace PSTW_CentralSystem.Controllers.API
var userSetting = _centralDbContext.Hrusersetting var userSetting = _centralDbContext.Hrusersetting
.Include(us => us.FlexiHour) .Include(us => us.FlexiHour)
.Include(us => us.Approvalflow) // Include Approvalflow to check roles
.FirstOrDefault(us => us.UserId == userId); .FirstOrDefault(us => us.UserId == userId);
string flexiHour = userSetting?.FlexiHour?.FlexiHour; string flexiHour = userSetting?.FlexiHour?.FlexiHour;
@ -2472,7 +2507,27 @@ namespace PSTW_CentralSystem.Controllers.API
.Where(o => o.UserId == userId && o.OtDate >= startDate && o.OtDate < endDate) .Where(o => o.UserId == userId && o.OtDate >= startDate && o.OtDate < endDate)
.ToList(); .ToList();
bool isAdminUser = IsAdmin(user.Id); var currentLoggedInUserId = GetCurrentLoggedInUserId();
bool isHoU = false;
bool isHoD = false; // Initialize isHoD
bool isManager = false; // Initialize isManager
if (userSetting?.Approvalflow != null)
{
if (userSetting.Approvalflow.HoU == currentLoggedInUserId)
{
isHoU = true;
}
if (userSetting.Approvalflow.HoD == currentLoggedInUserId) // Check if current user is HoD
{
isHoD = true;
}
if (userSetting.Approvalflow.Manager == currentLoggedInUserId) // Check if current user is Manager
{
isManager = true;
}
}
var excelGenerator = new OvertimeExcel(_centralDbContext, _env); var excelGenerator = new OvertimeExcel(_centralDbContext, _env);
@ -2484,7 +2539,9 @@ namespace PSTW_CentralSystem.Controllers.API
user, user,
userRate, userRate,
startDate, startDate,
isHoU: false, isHoU,
isHoD, // Pass isHoD
isManager, // Pass isManager
flexiHour: flexiHour, flexiHour: flexiHour,
logoImage: logoImage, logoImage: logoImage,
isSimplifiedExport: true isSimplifiedExport: true