-
This commit is contained in:
parent
ffdc93a4b7
commit
872eb2363a
@ -18,6 +18,10 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
|
|||||||
byte[]? logoImage = null // Optional logo image
|
byte[]? logoImage = null // Optional logo image
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
records = records
|
||||||
|
.OrderBy(r => r.OtDate)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
var stream = new MemoryStream();
|
var stream = new MemoryStream();
|
||||||
|
|
||||||
Document.Create(container =>
|
Document.Create(container =>
|
||||||
@ -44,6 +48,7 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
|
|||||||
|
|
||||||
col.Item().Text($"Name: {userFullName}").FontSize(9).SemiBold();
|
col.Item().Text($"Name: {userFullName}").FontSize(9).SemiBold();
|
||||||
col.Item().Text($"Department: {departmentName}").FontSize(9).Italic();
|
col.Item().Text($"Department: {departmentName}").FontSize(9).Italic();
|
||||||
|
col.Item().Text($"Overtime Record: { GetMonthYearString(records)}").FontSize(9).Italic();
|
||||||
});
|
});
|
||||||
|
|
||||||
row.RelativeItem(1).AlignRight().Text($"Generated: {DateTime.Now:dd MMM yyyy HH:mm}")
|
row.RelativeItem(1).AlignRight().Text($"Generated: {DateTime.Now:dd MMM yyyy HH:mm}")
|
||||||
@ -58,46 +63,70 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
|
|||||||
{
|
{
|
||||||
table.ColumnsDefinition(columns =>
|
table.ColumnsDefinition(columns =>
|
||||||
{
|
{
|
||||||
columns.RelativeColumn(); // Date
|
columns.RelativeColumn(1.1f); // Date
|
||||||
columns.RelativeColumn(1); // Office From
|
columns.RelativeColumn(0.8f); // Office From
|
||||||
columns.RelativeColumn(1); // Office To
|
columns.RelativeColumn(0.8f); // Office To
|
||||||
columns.RelativeColumn(); // Office Break
|
columns.RelativeColumn(0.8f); // Office Break
|
||||||
columns.RelativeColumn(1); // Outside From
|
columns.RelativeColumn(0.9f); // Outside From
|
||||||
columns.RelativeColumn(1); // Outside To
|
columns.RelativeColumn(0.9f); // Outside To
|
||||||
columns.RelativeColumn(); // Outside Break
|
columns.RelativeColumn(0.9f); // Outside Break
|
||||||
columns.RelativeColumn(); // Total OT
|
columns.RelativeColumn(); // Total OT
|
||||||
columns.RelativeColumn(1); // Break Hours
|
columns.RelativeColumn(); // Break Hours
|
||||||
columns.RelativeColumn(); // Net OT
|
columns.RelativeColumn(); // Net OT
|
||||||
if (departmentId == 2)
|
if (departmentId == 2)
|
||||||
columns.RelativeColumn(); // Station
|
columns.RelativeColumn(); // Station
|
||||||
columns.RelativeColumn(1); // Day Type
|
columns.RelativeColumn(0.9f); // Day Type
|
||||||
columns.RelativeColumn(3); // Description
|
columns.RelativeColumn(2.7f); // Description
|
||||||
});
|
});
|
||||||
|
|
||||||
// Header Row
|
// Header Row
|
||||||
table.Header(header =>
|
table.Header(header =>
|
||||||
{
|
{
|
||||||
header.Cell().Background("#d0ead2").Padding(5).Text("Date").FontSize(9).Bold().AlignCenter();
|
void AddHeaderCell(string text, string bgColor)
|
||||||
header.Cell().Background("#dceefb").Padding(5).Text("From\n(Office)").FontSize(9).Bold().AlignCenter();
|
{
|
||||||
header.Cell().Background("#dceefb").Padding(5).Text("To\n(Office)").FontSize(9).Bold().AlignCenter();
|
header.Cell().Background(bgColor).Border(0.25f).Padding(5).Text(text).FontSize(9).Bold().AlignCenter();
|
||||||
header.Cell().Background("#dceefb").Padding(5).Text("Break\n(Office)").FontSize(9).Bold().AlignCenter();
|
}
|
||||||
header.Cell().Background("#edf2f7").Padding(5).Text("From\n(Outside)").FontSize(9).Bold().AlignCenter();
|
|
||||||
header.Cell().Background("#edf2f7").Padding(5).Text("To\n(Outside)").FontSize(9).Bold().AlignCenter();
|
AddHeaderCell("Date", "#d0ead2");
|
||||||
header.Cell().Background("#edf2f7").Padding(5).Text("Break\n(Outside)").FontSize(9).Bold().AlignCenter();
|
AddHeaderCell("From\n(Office)", "#dceefb");
|
||||||
header.Cell().Background("#fdebd0").Padding(5).Text("Total OT\nHours").FontSize(9).Bold().AlignCenter();
|
AddHeaderCell("To\n(Office)", "#dceefb");
|
||||||
header.Cell().Background("#fdebd0").Padding(5).Text("Break Hours\n(min)").FontSize(9).Bold().AlignCenter();
|
AddHeaderCell("Break\n(Office)", "#dceefb");
|
||||||
header.Cell().Background("#fdebd0").Padding(5).Text("Net OT").FontSize(9).Bold().AlignCenter();
|
AddHeaderCell("From\n(Outside)", "#edf2f7");
|
||||||
|
AddHeaderCell("To\n(Outside)", "#edf2f7");
|
||||||
|
AddHeaderCell("Break\n(Outside)", "#edf2f7");
|
||||||
|
AddHeaderCell("Total OT\nHours", "#fdebd0");
|
||||||
|
AddHeaderCell("Break Hours\n(min)", "#fdebd0");
|
||||||
|
AddHeaderCell("Net OT", "#fdebd0");
|
||||||
if (departmentId == 2)
|
if (departmentId == 2)
|
||||||
header.Cell().Background("#d0f0ef").Padding(5).Text("Station").FontSize(9).Bold().AlignCenter();
|
AddHeaderCell("Station", "#d0f0ef");
|
||||||
header.Cell().Background("#e0f7da").Padding(5).Text("Days").FontSize(9).Bold().AlignCenter();
|
AddHeaderCell("Days", "#e0f7da");
|
||||||
header.Cell().Background("#e3f2fd").Padding(5).Text("Description").FontSize(9).Bold().AlignCenter();
|
AddHeaderCell("Description", "#e3f2fd");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Data Rows
|
||||||
// Data Rows
|
// Data Rows
|
||||||
double totalOTSum = 0;
|
double totalOTSum = 0;
|
||||||
int totalBreakSum = 0;
|
int totalBreakSum = 0;
|
||||||
TimeSpan totalNetOt = TimeSpan.Zero;
|
TimeSpan totalNetOt = TimeSpan.Zero;
|
||||||
|
bool alternate = false;
|
||||||
|
|
||||||
|
if (!records.Any())
|
||||||
|
{
|
||||||
|
// Show message row if no records
|
||||||
|
uint colspan = (uint)(departmentId == 2 ? 13 : 12);
|
||||||
|
|
||||||
|
table.Cell().ColumnSpan(colspan)
|
||||||
|
.Border(0.5f)
|
||||||
|
.Padding(10)
|
||||||
|
.AlignCenter()
|
||||||
|
.Text("No records found for selected month and year.")
|
||||||
|
.FontSize(10)
|
||||||
|
.FontColor(Colors.Grey.Darken2)
|
||||||
|
.Italic();
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
foreach (var r in records)
|
foreach (var r in records)
|
||||||
{
|
{
|
||||||
var totalOT = CalculateTotalOT(r);
|
var totalOT = CalculateTotalOT(r);
|
||||||
@ -108,32 +137,57 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
|
|||||||
totalBreakSum += totalBreak;
|
totalBreakSum += totalBreak;
|
||||||
totalNetOt += netOT;
|
totalNetOt += netOT;
|
||||||
|
|
||||||
table.Cell().Padding(5).Text(r.OtDate.ToString("dd/MM/yyyy")).FontSize(9);
|
string rowBg = alternate ? "#f9f9f9" : "#ffffff";
|
||||||
table.Cell().Padding(5).Text(FormatTime(r.OfficeFrom)).FontSize(9);
|
alternate = !alternate;
|
||||||
table.Cell().Padding(5).Text(FormatTime(r.OfficeTo)).FontSize(9);
|
|
||||||
table.Cell().Padding(5).Text($"{r.OfficeBreak ?? 0} min").FontSize(9);
|
void AddCell(string value, bool alignLeft = false)
|
||||||
table.Cell().Padding(5).Text(FormatTime(r.OutsideFrom)).FontSize(9);
|
{
|
||||||
table.Cell().Padding(5).Text(FormatTime(r.OutsideTo)).FontSize(9);
|
var text = table.Cell().Background(rowBg).Border(0.25f).Padding(5).Text(value).FontSize(9);
|
||||||
table.Cell().Padding(5).Text($"{r.OutsideBreak ?? 0} min").FontSize(9);
|
if (alignLeft)
|
||||||
table.Cell().Padding(5).Text($"{totalOT.TotalHours:F2}").FontSize(9);
|
text.AlignLeft();
|
||||||
table.Cell().Padding(5).Text($"{totalBreak}").FontSize(9);
|
else
|
||||||
table.Cell().Padding(5).Text($"{netOT.Hours} hr {netOT.Minutes} min").FontSize(9);
|
text.AlignCenter();
|
||||||
|
}
|
||||||
|
|
||||||
|
AddCell(r.OtDate.ToString("dd/MM/yyyy"));
|
||||||
|
AddCell(FormatTime(r.OfficeFrom));
|
||||||
|
AddCell(FormatTime(r.OfficeTo));
|
||||||
|
AddCell($"{r.OfficeBreak ?? 0} min");
|
||||||
|
AddCell(FormatTime(r.OutsideFrom));
|
||||||
|
AddCell(FormatTime(r.OutsideTo));
|
||||||
|
AddCell($"{r.OutsideBreak ?? 0} min");
|
||||||
|
AddCell($"{(int)totalOT.TotalHours} hr {totalOT.Minutes} min");
|
||||||
|
AddCell($"{totalBreak}");
|
||||||
|
AddCell($"{netOT.Hours} hr {netOT.Minutes} min");
|
||||||
if (departmentId == 2)
|
if (departmentId == 2)
|
||||||
table.Cell().Padding(5).Text(r.Stations?.StationName ?? "N/A").FontSize(9);
|
AddCell(r.Stations?.StationName ?? "N/A");
|
||||||
table.Cell().Padding(5).Text(r.OtDays).FontSize(9);
|
AddCell(r.OtDays);
|
||||||
table.Cell().Padding(5).Text(r.OtDescription ?? "-").FontSize(9).WrapAnywhere().LineHeight(1.2f);
|
table.Cell().Background(rowBg).Border(0.25f).Padding(5).Text(r.OtDescription ?? "-").FontSize(9).WrapAnywhere().LineHeight(1.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Totals Row
|
// Totals Row
|
||||||
table.Cell().ColumnSpan((uint)(departmentId == 2 ? 7 : 6)).Background("#d8d1f5").Padding(5).Text("TOTAL").Bold().FontSize(9);
|
var totalOTTimeSpan = TimeSpan.FromHours(totalOTSum);
|
||||||
table.Cell().Background("#d8d1f5").Padding(5).Text($"{totalOTSum:F2}").Bold().FontSize(9);
|
var totalBreakTimeSpan = TimeSpan.FromMinutes(totalBreakSum);
|
||||||
table.Cell().Background("#d8d1f5").Padding(5).Text($"{totalBreakSum}").Bold().FontSize(9);
|
|
||||||
table.Cell().Background("#d8d1f5").Padding(5).Text($"{(int)totalNetOt.TotalHours} hr {totalNetOt.Minutes} min").Bold().FontSize(9);
|
int totalCols = departmentId == 2 ? 13 : 12;
|
||||||
|
int spanCols = departmentId == 2 ? 7 : 6;
|
||||||
|
|
||||||
|
for (int i = 0; i < spanCols; i++)
|
||||||
|
table.Cell().Background("#d8d1f5").Border(0.80f).Padding(5).Text(i == 0 ? "TOTAL" : "").Bold().FontSize(9).AlignCenter();
|
||||||
|
|
||||||
|
table.Cell().Background("#d8d1f5").Border(0.80f).Padding(5).Text($"{(int)totalOTTimeSpan.TotalHours} hr {totalOTTimeSpan.Minutes} min").Bold().FontSize(9).AlignCenter();
|
||||||
|
table.Cell().Background("#d8d1f5").Border(0.80f).Padding(5).Text($"{(int)totalBreakTimeSpan.TotalHours} hr {totalBreakTimeSpan.Minutes} min").Bold().FontSize(9).AlignCenter();
|
||||||
|
table.Cell().Background("#d8d1f5").Border(0.80f).Padding(5).Text($"{(int)totalNetOt.TotalHours} hr {totalNetOt.Minutes} min").Bold().FontSize(9).AlignCenter();
|
||||||
if (departmentId == 2)
|
if (departmentId == 2)
|
||||||
table.Cell().Background("#d8d1f5");
|
table.Cell().Background("#d8d1f5").Border(0.80f);
|
||||||
table.Cell().Background("#d8d1f5");
|
else
|
||||||
table.Cell().Background("#d8d1f5");
|
table.Cell().Background("#d8d1f5").Border(0.80f);
|
||||||
|
table.Cell().Background("#d8d1f5").Border(0.80f);
|
||||||
|
table.Cell().Background("#d8d1f5").Border(0.80f);
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).GeneratePdf(stream);
|
}).GeneratePdf(stream);
|
||||||
@ -158,6 +212,15 @@ namespace PSTW_CentralSystem.Areas.OTcalculate.Services
|
|||||||
{
|
{
|
||||||
return time?.ToString(@"hh\:mm") ?? "-";
|
return time?.ToString(@"hh\:mm") ?? "-";
|
||||||
}
|
}
|
||||||
|
private string GetMonthYearString(List<OtRegisterModel> records)
|
||||||
|
{
|
||||||
|
if (records == null || !records.Any())
|
||||||
|
return "No Data";
|
||||||
|
|
||||||
|
var firstDate = records.First().OtDate;
|
||||||
|
return $"{firstDate:MMMM yyyy}";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,6 +58,19 @@
|
|||||||
text-align: left; /* Optional: left-align description */
|
text-align: left; /* Optional: left-align description */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.description-preview {
|
||||||
|
max-height: 3.6em; /* approx. 2 lines */
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
cursor: pointer;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
transition: max-height 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description-preview.expanded {
|
||||||
|
max-height: none;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@ -112,12 +125,16 @@
|
|||||||
<td>{{ formatTime(record.outsideFrom) }}</td>
|
<td>{{ formatTime(record.outsideFrom) }}</td>
|
||||||
<td>{{ formatTime(record.outsideTo) }}</td>
|
<td>{{ formatTime(record.outsideTo) }}</td>
|
||||||
<td>{{ record.outsideBreak }} min</td>
|
<td>{{ record.outsideBreak }} min</td>
|
||||||
<td>{{ calcTotalHours(record).toFixed(2) }}</td>
|
<td>{{ formatHourMinute(calcTotalTime(record)) }}</td>
|
||||||
<td>{{ calcBreakTotal(record) }}</td>
|
<td>{{ calcBreakTotal(record) }}</td>
|
||||||
<td>{{ formatHourMinute(calcNetHours(record)) }}</td>
|
<td>{{ formatHourMinute(calcNetHours(record)) }}</td>
|
||||||
<td v-if="isPSTWAIR">{{ record.stationName || 'N/A' }}</td>
|
<td v-if="isPSTWAIR">{{ record.stationName || 'N/A' }}</td>
|
||||||
<td>{{ record.otDays}}</td>
|
<td>{{ record.otDays}}</td>
|
||||||
<td class="wrap-text">{{ record.otDescription }}</td>
|
<td class="wrap-text">
|
||||||
|
<div class="description-preview" v-on:click ="toggleDescription(index)" :class="{ expanded: expandedDescriptions[index] }">
|
||||||
|
{{ record.otDescription }}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span v-if="record.pdfBase64">
|
<span v-if="record.pdfBase64">
|
||||||
<button class="btn btn-light border rounded-circle" title="View PDF" v-on:click="viewPdf(record.pdfBase64)">
|
<button class="btn btn-light border rounded-circle" title="View PDF" v-on:click="viewPdf(record.pdfBase64)">
|
||||||
@ -142,8 +159,8 @@
|
|||||||
<tr class="table-primary fw-bold">
|
<tr class="table-primary fw-bold">
|
||||||
<td>TOTAL</td>
|
<td>TOTAL</td>
|
||||||
<td colspan="6"></td>
|
<td colspan="6"></td>
|
||||||
<td>{{ totalHours.toFixed(2) }}</td>
|
<td>{{ formatHourMinute(totalHours) }}</td>
|
||||||
<td>{{ totalBreak }}</td>
|
<td>{{ formatHourMinute(totalBreak) }}</td>
|
||||||
<td>{{ formatHourMinute(totalNetTime) }}</td>
|
<td>{{ formatHourMinute(totalNetTime) }}</td>
|
||||||
<td v-if="isPSTWAIR"></td>
|
<td v-if="isPSTWAIR"></td>
|
||||||
<td colspan="4"></td>
|
<td colspan="4"></td>
|
||||||
@ -153,7 +170,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-3 d-flex flex-wrap gap-2">
|
<div class="mt-3 d-flex flex-wrap gap-2">
|
||||||
<button class="btn btn-primary btn-sm" v-on:click="printTable">
|
<button class="btn btn-primary btn-sm" v-on:click="printPdf">
|
||||||
<i class="bi bi-printer"></i> Print
|
<i class="bi bi-printer"></i> Print
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-dark btn-sm" v-on:click="downloadPdf">
|
<button class="btn btn-dark btn-sm" v-on:click="downloadPdf">
|
||||||
@ -180,7 +197,8 @@
|
|||||||
selectedMonth: new Date().getMonth() + 1,
|
selectedMonth: new Date().getMonth() + 1,
|
||||||
selectedYear: currentYear,
|
selectedYear: currentYear,
|
||||||
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
|
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
|
||||||
years: Array.from({ length: 10 }, (_, i) => currentYear - 5 + i)
|
years: Array.from({ length: 10 }, (_, i) => currentYear - 5 + i),
|
||||||
|
expandedDescriptions: {}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -190,13 +208,20 @@
|
|||||||
.sort((a, b) => new Date(a.otDate) - new Date(b.otDate));
|
.sort((a, b) => new Date(a.otDate) - new Date(b.otDate));
|
||||||
},
|
},
|
||||||
totalHours() {
|
totalHours() {
|
||||||
return this.filteredRecords.reduce((sum, r) => sum + this.calcTotalHours(r), 0);
|
const total = this.filteredRecords.reduce((sum, r) => sum + this.calcTotalHours(r), 0);
|
||||||
|
const hours = Math.floor(total);
|
||||||
|
const minutes = Math.round((total - hours) * 60);
|
||||||
|
return { hours, minutes };
|
||||||
},
|
},
|
||||||
totalBreak() {
|
totalBreak() {
|
||||||
return this.filteredRecords.reduce((sum, r) => sum + this.calcBreakTotal(r), 0);
|
const totalMin = this.filteredRecords.reduce((sum, r) => sum + this.calcBreakTotal(r), 0);
|
||||||
|
const hours = Math.floor(totalMin / 60);
|
||||||
|
const minutes = totalMin % 60;
|
||||||
|
return { hours, minutes };
|
||||||
},
|
},
|
||||||
totalNetTime() {
|
totalNetTime() {
|
||||||
const totalMinutes = (this.totalHours * 60) - this.totalBreak;
|
const totalMinutes = (this.totalHours.hours * 60 + this.totalHours.minutes) -
|
||||||
|
(this.totalBreak.hours * 60 + this.totalBreak.minutes);
|
||||||
return {
|
return {
|
||||||
hours: Math.floor(totalMinutes / 60),
|
hours: Math.floor(totalMinutes / 60),
|
||||||
minutes: Math.round(totalMinutes % 60)
|
minutes: Math.round(totalMinutes % 60)
|
||||||
@ -231,6 +256,10 @@
|
|||||||
console.error("Records fetch error:", err);
|
console.error("Records fetch error:", err);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
toggleDescription(index) {
|
||||||
|
this.expandedDescriptions[index] = !this.expandedDescriptions[index];
|
||||||
|
},
|
||||||
|
|
||||||
formatDate(d) {
|
formatDate(d) {
|
||||||
return new Date(d).toLocaleDateString();
|
return new Date(d).toLocaleDateString();
|
||||||
},
|
},
|
||||||
@ -243,6 +272,13 @@
|
|||||||
const [th, tm] = to.split(":").map(Number);
|
const [th, tm] = to.split(":").map(Number);
|
||||||
return ((th * 60 + tm) - (fh * 60 + fm)) / 60;
|
return ((th * 60 + tm) - (fh * 60 + fm)) / 60;
|
||||||
},
|
},
|
||||||
|
calcTotalTime(r) {
|
||||||
|
const totalMinutes = this.calcTotalHours(r) * 60;
|
||||||
|
return {
|
||||||
|
hours: Math.floor(totalMinutes / 60),
|
||||||
|
minutes: Math.round(totalMinutes % 60)
|
||||||
|
};
|
||||||
|
},
|
||||||
calcTotalHours(r) {
|
calcTotalHours(r) {
|
||||||
return this.getTimeDiff(r.officeFrom, r.officeTo) + this.getTimeDiff(r.outsideFrom, r.outsideTo);
|
return this.getTimeDiff(r.officeFrom, r.officeTo) + this.getTimeDiff(r.outsideFrom, r.outsideTo);
|
||||||
},
|
},
|
||||||
@ -257,7 +293,7 @@
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
formatHourMinute(timeObj) {
|
formatHourMinute(timeObj) {
|
||||||
return timeObj ? `${timeObj.hours} hr ${timeObj.minutes} min` : '-';
|
return timeObj ? `${timeObj.hours} h ${timeObj.minutes} m` : '-';
|
||||||
},
|
},
|
||||||
editRecord(index) {
|
editRecord(index) {
|
||||||
const record = this.filteredRecords[index];
|
const record = this.filteredRecords[index];
|
||||||
@ -275,8 +311,26 @@
|
|||||||
alert("Error deleting record.");
|
alert("Error deleting record.");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
printTable() {
|
printPdf() {
|
||||||
window.print();
|
const today = new Date();
|
||||||
|
const month = today.getMonth() + 1;
|
||||||
|
const year = today.getFullYear();
|
||||||
|
|
||||||
|
fetch(`/OvertimeAPI/GenerateOvertimePdf?month=${month}&year=${year}`)
|
||||||
|
.then(response => response.blob())
|
||||||
|
.then(blob => {
|
||||||
|
const blobUrl = URL.createObjectURL(blob);
|
||||||
|
const printWindow = window.open(blobUrl, '_blank');
|
||||||
|
|
||||||
|
// Automatically trigger print after window loads
|
||||||
|
printWindow.onload = () => {
|
||||||
|
printWindow.focus();
|
||||||
|
printWindow.print();
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error("Error generating PDF:", error);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
async downloadPdf() {
|
async downloadPdf() {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -492,9 +492,6 @@ namespace PSTW_CentralSystem.Controllers.API
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
[HttpPost("SaveOvertimeRecordsWithPdf")]
|
[HttpPost("SaveOvertimeRecordsWithPdf")]
|
||||||
public async Task<IActionResult> SaveOvertimeRecordsWithPdf([FromBody] List<OtRegisterModel> records)
|
public async Task<IActionResult> SaveOvertimeRecordsWithPdf([FromBody] List<OtRegisterModel> records)
|
||||||
{
|
{
|
||||||
@ -577,6 +574,7 @@ namespace PSTW_CentralSystem.Controllers.API
|
|||||||
return File(stream, "application/pdf", $"OvertimeRecords_{year}_{month}.pdf");
|
return File(stream, "application/pdf", $"OvertimeRecords_{year}_{month}.pdf");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user