@using Indotalent.Features.Payroll.Payrolls @using Indotalent.Features.Payroll.PayrollDetails.Cqrs @using Microsoft.AspNetCore.Components.Web @using Microsoft.JSInterop @using MudBlazor @using ClosedXML.Excel @using System.IO @inject PayrollsService PayrollsService @inject IDialogService DialogService @inject ISnackbar Snackbar @inject IJSRuntime JSRuntime
Employee Payroll List Reviewing distribution for period: @PeriodName
Search
@if (_isExporting) { } else { Excel } @if (_loading) { } else { Refresh } @if (_selectedRow != null) { Detail }
NIK Employee Name Basic Salary Incomes Deductions Take Home Pay @context.EmployeeCode @context.EmployeeName @context.BasicSalary.ToString("N0") @context.TotalIncome.ToString("N0") (@context.TotalDeduction.ToString("N0")) @context.TakeHomePay.ToString("N0")
Rows per page: Showing @(GetFilteredData().Count() == 0 ? 0 : _skip + 1)-@Math.Min(_skip + _top, GetFilteredData().Count()) of @GetFilteredData().Count()
Prev Page @_currentPage of @(_totalPage == 0 ? 1 : _totalPage) Next
@code { [Parameter] public string ProcessId { get; set; } = string.Empty; [Parameter] public string PeriodName { get; set; } = string.Empty; [Parameter] public EventCallback OnBack { get; set; } private List _details = new(); private GetPayrollDetailListByProcessIdResponse? _selectedRow; private string _searchString = ""; private int _skip = 0; private int _top = 5; private int _totalPage => GetFilteredData().Count() == 0 ? 0 : (int)Math.Ceiling((double)GetFilteredData().Count() / (_top == 0 ? 1 : _top)); private int _currentPage => (_top >= GetFilteredData().Count() || _top == 0) ? 1 : (_skip / _top) + 1; private bool _loading = false; private bool _isExporting = false; protected override async Task OnParametersSetAsync() { if (!string.IsNullOrEmpty(ProcessId)) await LoadDetails(); } private async Task LoadDetails() { _loading = true; _selectedRow = null; StateHasChanged(); var response = await PayrollsService.GetPayrollDetailListByProcessIdAsync(ProcessId); if (response != null && response.IsSuccess) { _details = response.Value ?? new(); } _loading = false; StateHasChanged(); } private IEnumerable GetFilteredData() { if (string.IsNullOrWhiteSpace(_searchString)) return _details; return _details.Where(x => (x.EmployeeCode?.Contains(_searchString, StringComparison.OrdinalIgnoreCase) ?? false) || (x.EmployeeName?.Contains(_searchString, StringComparison.OrdinalIgnoreCase) ?? false) ); } private IEnumerable GetPagedData() => GetFilteredData().Skip(_skip).Take(_top); private void OnSearchClick() { _skip = 0; StateHasChanged(); } private void HandleSearchKeyDown(KeyboardEventArgs e) { if (e.Key == "Enter") OnSearchClick(); } private void OnPageChanged(int page) { _skip = (page - 1) * _top; _selectedRow = null; StateHasChanged(); } private void OnPageSizeChanged(int size) { _top = size; _skip = 0; _selectedRow = null; StateHasChanged(); } private async Task OpenSlipPopup() { if (_selectedRow == null) return; var response = await PayrollsService.GetPayrollSlipByIdAsync(_selectedRow.Id!); if (response != null && response.IsSuccess) { var parameters = new DialogParameters<_PayrollSlipDialog> { { x => x.Data, response.Value }, { x => x.PeriodName, PeriodName } }; var options = new DialogOptions { MaxWidth = MaxWidth.Medium, FullWidth = true, CloseButton = true }; await DialogService.ShowAsync<_PayrollSlipDialog>("", parameters, options); } } private async Task ExportToExcel() { _isExporting = true; StateHasChanged(); try { await Task.Delay(500); using var workbook = new XLWorkbook(); var worksheet = workbook.Worksheets.Add("EmployeePayroll"); worksheet.Cell(1, 1).Value = "NIK"; worksheet.Cell(1, 2).Value = "Employee Name"; worksheet.Cell(1, 3).Value = "Basic Salary"; worksheet.Cell(1, 4).Value = "Total Income"; worksheet.Cell(1, 5).Value = "Total Deduction"; worksheet.Cell(1, 6).Value = "Take Home Pay"; var headerRange = worksheet.Range(1, 1, 1, 6); headerRange.Style.Font.Bold = true; headerRange.Style.Fill.BackgroundColor = XLColor.FromHtml("#0D47A1"); headerRange.Style.Font.FontColor = XLColor.White; int row = 2; foreach (var item in GetFilteredData()) { worksheet.Cell(row, 1).Value = item.EmployeeCode; worksheet.Cell(row, 2).Value = item.EmployeeName; worksheet.Cell(row, 3).Value = item.BasicSalary; worksheet.Cell(row, 4).Value = item.TotalIncome; worksheet.Cell(row, 5).Value = item.TotalDeduction; worksheet.Cell(row, 6).Value = item.TakeHomePay; row++; } worksheet.Columns().AdjustToContents(); using var stream = new MemoryStream(); workbook.SaveAs(stream); await JSRuntime.InvokeVoidAsync("downloadFile", $"Payroll_Detail_{PeriodName}.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", Convert.ToBase64String(stream.ToArray())); Snackbar.Add("Excel exported successfully", Severity.Success); } catch (Exception ex) { Snackbar.Add($"Export failed: {ex.Message}", Severity.Error); } finally { _isExporting = false; StateHasChanged(); } } }