PI2024-30 #6
113
Controllers/PdfController.cs
Normal file
113
Controllers/PdfController.cs
Normal file
@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FirmTracker_Server.nHibernate;
|
||||
using FirmTracker_Server.nHibernate.Expenses;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
|
||||
namespace FirmTracker_Server.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class PdfController : ControllerBase
|
||||
{
|
||||
private readonly IExpenseRepository _expenseRepository;
|
||||
|
||||
public PdfController(IExpenseRepository expenseRepository)
|
||||
{
|
||||
_expenseRepository = expenseRepository;
|
||||
}
|
||||
|
||||
[HttpGet("download")]
|
||||
public IActionResult DownloadExpenseReport()
|
||||
{
|
||||
// Fetch expense data from the repository
|
||||
List<Expense> expenses = _expenseRepository.GetAllExpenses();
|
||||
|
||||
// Generate the PDF file
|
||||
byte[] pdfBytes = GeneratePdf(expenses);
|
||||
string date = DateTime.Now.ToString("yyyy-MM-dd");
|
||||
string fileName = $"ExpenseReport_{date}.pdf";
|
||||
|
||||
// Return the PDF as a downloadable file
|
||||
return File(pdfBytes, "application/pdf", fileName);
|
||||
}
|
||||
|
||||
private byte[] GeneratePdf(List<Expense> expenses)
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
// Calculate total and average expenses
|
||||
decimal totalExpenses = expenses.Sum(e => e.Value);
|
||||
decimal averageExpense = expenses.Count > 0 ? totalExpenses / expenses.Count : 0;
|
||||
|
||||
// Define the document using QuestPDF
|
||||
Document.Create(container =>
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Size(PageSizes.A4);
|
||||
page.Margin(2, Unit.Centimetre);
|
||||
page.PageColor(Colors.White);
|
||||
page.DefaultTextStyle(x => x.FontSize(12));
|
||||
|
||||
// Main header
|
||||
page.Header()
|
||||
.Text("Expense Report")
|
||||
.FontSize(20)
|
||||
.SemiBold()
|
||||
.AlignCenter();
|
||||
|
||||
// Summary section
|
||||
page.Content().PaddingVertical(1, Unit.Centimetre).Column(column =>
|
||||
{
|
||||
column.Spacing(10);
|
||||
|
||||
column.Item().Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text($"Total Expenses: {totalExpenses:C}").FontSize(14).Bold();
|
||||
row.RelativeItem().Text($"Average Expense: {averageExpense:C}").FontSize(14).Bold();
|
||||
});
|
||||
|
||||
column.Item().Text("Expense Details").FontSize(16).Underline();
|
||||
|
||||
// Add a table header
|
||||
column.Item().Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text("Date").SemiBold();
|
||||
row.RelativeItem().Text("Value").SemiBold();
|
||||
row.RelativeItem().Text("Description").SemiBold();
|
||||
});
|
||||
|
||||
// Populate table rows with expense data
|
||||
foreach (var expense in expenses)
|
||||
{
|
||||
column.Item().Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text(expense.Date.ToString("yyyy-MM-dd"));
|
||||
row.RelativeItem().Text(expense.Value.ToString("C"));
|
||||
row.RelativeItem().Text(expense.Description);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Footer with generation date
|
||||
page.Footer()
|
||||
.AlignCenter()
|
||||
.Text(text =>
|
||||
{
|
||||
text.Span("Generated on ");
|
||||
text.Span(DateTime.Now.ToString("yyyy-MM-dd")).SemiBold();
|
||||
});
|
||||
});
|
||||
}).GeneratePdf(ms);
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
55
Controllers/WorkDayController.cs
Normal file
55
Controllers/WorkDayController.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
|
||||
namespace YourNamespace.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class WorkdayController : ControllerBase
|
||||
{
|
||||
// In-memory storage for simplicity, where the key is the userId.
|
||||
private static readonly ConcurrentDictionary<string, DateTime?> WorkStartTimes = new ConcurrentDictionary<string, DateTime?>();
|
||||
|
||||
// Get the current status of the user's workday (started or not)
|
||||
[HttpGet("status/{userId}")]
|
||||
public IActionResult GetWorkdayStatus(string userId)
|
||||
{
|
||||
if (WorkStartTimes.TryGetValue(userId, out DateTime? startTime))
|
||||
{
|
||||
if (startTime.HasValue)
|
||||
{
|
||||
return Ok(new { status = "started", startTime = startTime });
|
||||
}
|
||||
else
|
||||
{
|
||||
return Ok(new { status = "stopped" });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound(new { message = "User not found" });
|
||||
}
|
||||
}
|
||||
|
||||
// Start or stop the user's workday by toggling the start/stop state
|
||||
[HttpPost("toggle/{userId}")]
|
||||
public IActionResult ToggleWorkday(string userId)
|
||||
{
|
||||
// If the workday has already started, stop it, otherwise start it
|
||||
if (WorkStartTimes.ContainsKey(userId) && WorkStartTimes[userId].HasValue)
|
||||
{
|
||||
// Stop the workday
|
||||
WorkStartTimes[userId] = null;
|
||||
return Ok(new { status = "stopped" });
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start the workday
|
||||
WorkStartTimes[userId] = DateTime.Now;
|
||||
return Ok(new { status = "started", startTime = WorkStartTimes[userId] });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -29,6 +29,7 @@
|
||||
<PackageReference Include="NLog" Version="5.3.4" />
|
||||
<PackageReference Include="NLog.Database" Version="5.3.4" />
|
||||
<PackageReference Include="NSwag.Annotations" Version="14.0.7" />
|
||||
<PackageReference Include="QuestPDF" Version="2024.10.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.1.2" />
|
||||
|
@ -37,6 +37,7 @@ using FirmTracker_Server.Middleware;
|
||||
using FirmTracker_Server.Services;
|
||||
using System.Reflection;
|
||||
using FirmTracker_Server.Mappings;
|
||||
using NuGet.Packaging;
|
||||
|
||||
|
||||
namespace FirmTracker_Server
|
||||
@ -69,6 +70,7 @@ namespace FirmTracker_Server
|
||||
|
||||
TestClass test = new TestClass();
|
||||
test.AddTestProduct();
|
||||
QuestPDF.Settings.License = QuestPDF.Infrastructure.LicenseType.Community;
|
||||
|
||||
builder.Services.AddCors(options =>
|
||||
{
|
||||
@ -173,6 +175,7 @@ namespace FirmTracker_Server
|
||||
services.AddScoped<IUserService, UserService>();
|
||||
services.AddScoped<ErrorHandling>();
|
||||
services.AddScoped<IPasswordHasher<User>, PasswordHasher<User>>();
|
||||
services.AddScoped<IExpenseRepository, ExpenseRepository>();
|
||||
services.AddMvc();
|
||||
}
|
||||
|
||||
|
98
nHIbernate/PdfData.cs
Normal file
98
nHIbernate/PdfData.cs
Normal file
@ -0,0 +1,98 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FirmTracker_Server.nHibernate.Expenses;
|
||||
using NHibernate;
|
||||
|
||||
namespace FirmTracker_Server.nHibernate
|
||||
{
|
||||
public interface IExpenseRepository
|
||||
{
|
||||
List<Expense> GetAllExpenses();
|
||||
Expense GetExpense(int expenseId);
|
||||
void AddExpense(Expense expense);
|
||||
void UpdateExpense(Expense expense);
|
||||
void DeleteExpense(int expenseId);
|
||||
}
|
||||
|
||||
public class ExpenseRepository : IExpenseRepository
|
||||
{
|
||||
// Retrieve all expenses
|
||||
public List<Expense> GetAllExpenses()
|
||||
{
|
||||
using (var session = SessionFactory.OpenSession())
|
||||
{
|
||||
return session.Query<Expense>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve a specific expense by ID
|
||||
public Expense GetExpense(int expenseId)
|
||||
{
|
||||
using (var session = SessionFactory.OpenSession())
|
||||
{
|
||||
return session.Get<Expense>(expenseId);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a new expense
|
||||
public void AddExpense(Expense expense)
|
||||
{
|
||||
using (var session = SessionFactory.OpenSession())
|
||||
using (var transaction = session.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
session.Save(expense);
|
||||
transaction.Commit();
|
||||
}
|
||||
catch
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update an existing expense
|
||||
public void UpdateExpense(Expense expense)
|
||||
{
|
||||
using (var session = SessionFactory.OpenSession())
|
||||
using (var transaction = session.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
session.Update(expense);
|
||||
transaction.Commit();
|
||||
}
|
||||
catch
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete an expense by ID
|
||||
public void DeleteExpense(int expenseId)
|
||||
{
|
||||
using (var session = SessionFactory.OpenSession())
|
||||
using (var transaction = session.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
var expense = session.Get<Expense>(expenseId);
|
||||
if (expense != null)
|
||||
{
|
||||
session.Delete(expense);
|
||||
}
|
||||
transaction.Commit();
|
||||
}
|
||||
catch
|
||||
{
|
||||
transaction.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user