initial commit

This commit is contained in:
2026-07-21 14:22:06 +07:00
commit 2d7959f202
572 changed files with 45295 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
using FluentValidation;
namespace Indotalent.Shared.Utils;
//public static class FluentValidationHelper
//{
// public static Func<object, string, Task<IEnumerable<string>>> ValidateValue<T>(this AbstractValidator<T> validator) => async (model, propertyName) =>
// {
// var result = await validator.ValidateAsync(ValidationContext<T>.CreateWithOptions((T)model, x => x.IncludeProperties(propertyName)));
// if (result.IsValid) return Array.Empty<string>();
// return result.Errors.Select(e => e.ErrorMessage);
// };
//}
public static class FluentValidationHelper
{
public static Func<object, string, Task<IEnumerable<string>>> ValidateValue<T>(this AbstractValidator<T> validator) => async (model, propertyName) =>
{
if (model is not T typedModel)
return Array.Empty<string>();
var context = ValidationContext<T>.CreateWithOptions(typedModel, x => x.IncludeProperties(propertyName));
var result = await validator.ValidateAsync(context);
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}
+125
View File
@@ -0,0 +1,125 @@
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
using Indotalent.Features.Payroll.PayrollDetails.Cqrs;
namespace Indotalent.Features.Payroll.Payrolls;
public class PayrollSlipPdfGenerator
{
public static byte[] Generate(GetPayrollSlipByIdResponse data, string periodName)
{
QuestPDF.Settings.License = LicenseType.Community;
var primaryBlue = "#0D47A1";
var lightGreyBg = "#F8FAFC";
var borderColor = "#E2E8F0";
var textSlate = "#64748b";
return Document.Create(container =>
{
container.Page(page =>
{
page.Size(PageSizes.A5.Landscape());
page.Margin(1, Unit.Centimetre);
page.PageColor(Colors.White);
page.DefaultTextStyle(x => x.FontSize(9).FontFamily(Fonts.Verdana));
page.Header().PaddingBottom(10).Row(row =>
{
row.RelativeItem().Text("PAYROLL SLIP DETAILS")
.FontSize(14)
.ExtraBold()
.FontColor(Colors.Black);
});
page.Content().Column(col =>
{
col.Item().Border(1).BorderColor(borderColor).Background(lightGreyBg).Padding(10).Row(row =>
{
row.RelativeItem().Column(c =>
{
c.Item().Text("Employee Name").FontSize(8).SemiBold().FontColor(textSlate);
c.Item().Text(data.EmployeeName).FontSize(11).ExtraBold().FontColor(primaryBlue);
c.Item().PaddingTop(5).Text("Code").FontSize(8).SemiBold().FontColor(textSlate);
c.Item().Text(data.EmployeeCode).FontSize(10).Bold();
});
row.RelativeItem().AlignRight().Column(c =>
{
c.Item().Text("Payroll Period").FontSize(8).SemiBold().FontColor(textSlate);
c.Item().Text(periodName).FontSize(11).Bold();
c.Item().PaddingTop(5).Text("Basic Salary").FontSize(8).SemiBold().FontColor(textSlate);
c.Item().Text(data.BasicSalary.ToString("N0")).FontSize(11).ExtraBold().FontColor(primaryBlue);
});
});
col.Item().PaddingTop(15).Row(row =>
{
row.RelativeItem().Column(c =>
{
c.Item().Text("Incomes (+)").FontSize(10).ExtraBold().FontColor(Colors.Green.Medium);
c.Item().PaddingVertical(5).LineHorizontal(1).LineColor(borderColor);
foreach (var inc in data.Incomes)
{
c.Item().PaddingBottom(2).Row(r =>
{
r.RelativeItem().Text(inc.ComponentName);
r.RelativeItem().AlignRight().Text(inc.Amount.ToString("N0")).Bold();
});
}
});
row.ConstantItem(20);
row.RelativeItem().BorderLeft(1).BorderColor(borderColor).PaddingLeft(10).Column(c =>
{
c.Item().Text("Deductions (-)").FontSize(10).ExtraBold().FontColor(Colors.Red.Medium);
c.Item().PaddingVertical(5).LineHorizontal(1).LineColor(borderColor);
foreach (var ded in data.Deductions)
{
c.Item().PaddingBottom(2).Row(r =>
{
r.RelativeItem().Text(ded.ComponentName);
r.RelativeItem().AlignRight().Text($"({ded.Amount.ToString("N0")})").Bold().FontColor(Colors.Red.Medium);
});
}
});
});
col.Item().PaddingTop(20).Background(primaryBlue).Padding(10).Row(row =>
{
row.RelativeItem().AlignLeft().AlignMiddle().Text("TAKE HOME PAY")
.FontSize(12)
.ExtraBold()
.FontColor(Colors.White);
row.RelativeItem().AlignRight().AlignMiddle().Text(data.TakeHomePay.ToString("N0"))
.FontSize(14)
.ExtraBold()
.FontColor(Colors.White);
});
});
page.Footer().PaddingTop(10).Row(row =>
{
row.RelativeItem().Text(x =>
{
x.Span("Generated on: ").FontSize(8).FontColor(textSlate);
x.Span(DateTime.Now.ToString("dd MMM yyyy HH:mm")).FontSize(8).FontColor(textSlate);
});
row.RelativeItem().AlignRight().Text(x =>
{
x.Span("Page ").FontSize(8);
x.CurrentPageNumber().FontSize(8);
});
});
});
}).GeneratePdf();
}
}
+25
View File
@@ -0,0 +1,25 @@
namespace Indotalent.Shared.Utils;
public static class SequentialGuidGenerator
{
public static string NewSequentialId()
{
byte[] guidBytes = Guid.NewGuid().ToByteArray();
byte[] timestampBytes = BitConverter.GetBytes(DateTime.UtcNow.Ticks);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(timestampBytes);
}
guidBytes[10] = timestampBytes[2];
guidBytes[11] = timestampBytes[3];
guidBytes[12] = timestampBytes[4];
guidBytes[13] = timestampBytes[5];
guidBytes[14] = timestampBytes[6];
guidBytes[15] = timestampBytes[7];
return new Guid(guidBytes).ToString();
}
}