From 049899dc644dafb293d9855daf83a6b40c24f274 Mon Sep 17 00:00:00 2001 From: Maciej Maciejewski Date: Tue, 26 Nov 2024 22:12:02 +0100 Subject: [PATCH] =?UTF-8?q?dodanie=20usuwania=20produktu=20w=20transakcji,?= =?UTF-8?q?=20zmiana=20ilo=C5=9Bci=20w=20klasie=20testowej?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Controllers/PdfController.cs | 3 + Controllers/TransactionController.cs | 36 ++++++- Controllers/WorkDayController.cs | 41 ++++++- Models/Workday.cs | 2 +- TestClass.cs | 4 +- nHIbernate/PdfData.cs | 10 +- nHIbernate/Workday.cs | 14 ++- nHIbernate/WorkdayRepository.cs | 119 ++++++++++++++++----- nHibernate/Transactions/TransactionCRUD.cs | 61 +++++++++++ 9 files changed, 250 insertions(+), 40 deletions(-) diff --git a/Controllers/PdfController.cs b/Controllers/PdfController.cs index 7232d94..bfb24fa 100644 --- a/Controllers/PdfController.cs +++ b/Controllers/PdfController.cs @@ -5,6 +5,7 @@ using System.Linq; using FirmTracker_Server.nHibernate; using FirmTracker_Server.nHibernate.Expenses; using FirmTracker_Server.nHibernate.Transactions; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using QuestPDF.Fluent; using QuestPDF.Helpers; @@ -14,6 +15,7 @@ namespace FirmTracker_Server.Controllers { [Route("api/[controller]")] [ApiController] + [Authorize] public class PdfController : ControllerBase { private readonly IExpenseRepository _expenseRepository; @@ -26,6 +28,7 @@ namespace FirmTracker_Server.Controllers } [HttpGet("download")] + [Authorize(Roles = Roles.Admin)] public IActionResult DownloadReport( [FromQuery] string reportType, // "expenses" or "transactions" [FromQuery] DateTime? startDate, diff --git a/Controllers/TransactionController.cs b/Controllers/TransactionController.cs index 276a50a..fbe2110 100644 --- a/Controllers/TransactionController.cs +++ b/Controllers/TransactionController.cs @@ -55,14 +55,21 @@ namespace FirmTracker_Server.Controllers { try { - + foreach (var product in transaction.TransactionProducts) { + // Validate if the product quantity is positive + if (product.Quantity <= 0) + { + return BadRequest($"Ilość na produktu {product.ProductName} musi być dodatnia."); + } var productByName = _productCRUD.GetProductByName(product.ProductName); if (productByName == null) { throw new InvalidOperationException($"Produkt o nazwie {product.ProductName} nie istnieje."); } + + product.ProductID = productByName.Id; product.TransactionId = transaction.Id; @@ -132,6 +139,11 @@ namespace FirmTracker_Server.Controllers { foreach (var product in transaction.TransactionProducts) { + // Validate if the product quantity is positive + if (product.Quantity <= 0) + { + return BadRequest($"Sprzedawana ilość produktu {product.ProductName} musi być ilością dodatnią."); + } var productByName = _productCRUD.GetProductByName(product.ProductName); if (productByName == null) { @@ -207,5 +219,27 @@ namespace FirmTracker_Server.Controllers return Ok(transactions); } + // DELETE: api/Transaction/5/product/10 + [HttpDelete("{transactionId}/product/{productId}")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [Authorize(Roles = Roles.Admin + "," + Roles.User)] + public IActionResult DeleteTransactionProduct(int transactionId, int productId) + { + try + { + _transactionCRUD.DeleteTransactionProduct(transactionId, productId); + return NoContent(); // Successfully removed the product + } + catch (InvalidOperationException ioe) + { + return BadRequest(ioe.Message); // If the transaction or product isn't found + } + catch (Exception ex) + { + return NotFound(ex.Message); // Other general errors + } + } } } diff --git a/Controllers/WorkDayController.cs b/Controllers/WorkDayController.cs index 4c4cc6e..844d115 100644 --- a/Controllers/WorkDayController.cs +++ b/Controllers/WorkDayController.cs @@ -32,7 +32,7 @@ namespace FirmTracker_Server.Controllers public WorkdayController() { - _workdayCRUD = new WorkdayRepository(); // Instantiate directly (no DI in this example) + _workdayCRUD = new WorkdayRepository(); } // Endpoint to start a workday @@ -44,15 +44,52 @@ namespace FirmTracker_Server.Controllers { var userIdString = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value; int userId = int.Parse(userIdString); + + // Attempt to start a new workday _workdayCRUD.StartWorkday(userId); return Ok(new { status = "started", userId }); } catch (Exception ex) { + // If there's an error (like previous workday not stopped), handle it return BadRequest(new { message = "An error occurred while starting the workday.", error = ex.Message }); } } + // Endpoint to stop a workday + [HttpPost("stop")] + [Authorize(Roles = Roles.Admin + "," + Roles.User)] + public IActionResult StopWorkday() + { + try + { + var userIdString = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value; + int userId = int.Parse(userIdString); + + var result = _workdayCRUD.StopWorkday(userId); + return Ok(new { status = result ? "stopped" : "already stopped", userId }); + } + catch (Exception ex) + { + return BadRequest(new { message = "An error occurred while stopping the workday.", error = ex.Message }); + } + } + + // Endpoint to get all workdays for a user + [HttpGet("user/{userMail}/workdays")] + [Authorize(Roles = Roles.Admin + "," + Roles.User)] + public IActionResult GetWorkdays(string userMail) + { + try + { + var workdays = _workdayCRUD.GetWorkdaysByUser(userMail); + return Ok(workdays); + } + catch (Exception ex) + { + return BadRequest(new { message = "An error occurred while fetching workdays.", error = ex.Message }); + } + } + - } } diff --git a/Models/Workday.cs b/Models/Workday.cs index a93638d..31313b8 100644 --- a/Models/Workday.cs +++ b/Models/Workday.cs @@ -8,7 +8,7 @@ namespace YourNamespace.Models public virtual int Id { get; set; } public virtual DateTime? StartTime { get; set; } public virtual DateTime? EndTime { get; set; } - + public TimeSpan WorkedHours { get; set; } // Many-to-One relationship to the User entity public virtual User User { get; set; } } diff --git a/TestClass.cs b/TestClass.cs index 5cb4440..9797a9d 100644 --- a/TestClass.cs +++ b/TestClass.cs @@ -239,9 +239,9 @@ namespace FirmTracker_Server expenseCrud.AddExpense(expense3); List testTransactionProducts = new List { - new TransactionProduct { ProductID =17, Quantity = 10 }, + new TransactionProduct { ProductID =17, Quantity = 3 }, new TransactionProduct { ProductID = 14, Quantity = 1 }, - new TransactionProduct { ProductID = 1, Quantity = 0 }, + new TransactionProduct { ProductID = 1, Quantity = 1 }, }; foreach (var transactionProduct in testTransactionProducts) { diff --git a/nHIbernate/PdfData.cs b/nHIbernate/PdfData.cs index d18d025..5792f4b 100644 --- a/nHIbernate/PdfData.cs +++ b/nHIbernate/PdfData.cs @@ -44,7 +44,7 @@ namespace FirmTracker_Server.nHibernate .ToList(); } } - // Retrieve a specific transaction by ID + public Transaction GetTransaction(int transactionId) { using (var session = SessionFactory.OpenSession()) @@ -53,7 +53,7 @@ namespace FirmTracker_Server.nHibernate } } - // Retrieve transactions within a specific date range + public List GetTransactionsByDateRange(DateTime startDate, DateTime endDate) { using (var session = SessionFactory.OpenSession()) @@ -64,7 +64,7 @@ namespace FirmTracker_Server.nHibernate } } - // Retrieve all products for a specific transaction + public List GetTransactionProducts(int transactionId) { using (var session = SessionFactory.OpenSession()) @@ -75,7 +75,7 @@ namespace FirmTracker_Server.nHibernate } } - // Add a new transaction + public void AddTransaction(Transaction transaction) { using (var session = SessionFactory.OpenSession()) @@ -113,7 +113,7 @@ namespace FirmTracker_Server.nHibernate } } - // Delete a transaction by ID + public void DeleteTransaction(int transactionId) { using (var session = SessionFactory.OpenSession()) diff --git a/nHIbernate/Workday.cs b/nHIbernate/Workday.cs index 7f819cc..ac85b39 100644 --- a/nHIbernate/Workday.cs +++ b/nHIbernate/Workday.cs @@ -7,6 +7,18 @@ namespace FirmTracker_Server.nHibernate public virtual int Id { get; set; } public virtual DateTime StartTime { get; set; } public virtual DateTime? EndTime { get; set; } // Nullable EndTime, if not finished - public virtual User User { get; set; } // Assuming a relationship to a User entity + public virtual TimeSpan WorkedHours + { + get + { + // Calculate the worked hours, using 5 PM as the fallback for the EndTime + return (EndTime ?? DateTime.Today.AddHours(24)) - StartTime; + } + set + { + + } + } + public virtual User User { get; set; } } } diff --git a/nHIbernate/WorkdayRepository.cs b/nHIbernate/WorkdayRepository.cs index 6c2e992..eff5486 100644 --- a/nHIbernate/WorkdayRepository.cs +++ b/nHIbernate/WorkdayRepository.cs @@ -1,40 +1,103 @@ using FirmTracker_Server.Entities; -using NHibernate; -using System; +using FirmTracker_Server.nHibernate; -namespace FirmTracker_Server.nHibernate +public class WorkdayRepository { - public class WorkdayRepository + public void StartWorkday(int userId) { - public void StartWorkday(int userId) + using (var session = SessionFactory.OpenSession()) + using (var transaction = session.BeginTransaction()) { - using (var session = SessionFactory.OpenSession()) - using (var transaction = session.BeginTransaction()) + try { - try - { - // Fetch the user entity by its ID - var user = session.Get(userId); // Assuming User is a mapped entity - if (user == null) - { - throw new Exception("User not found"); - } + // Check if there is an existing workday that hasn't been stopped yet + var ongoingWorkday = session.Query() + .Where(w => w.User.UserId == userId && w.EndTime == null) + .OrderByDescending(w => w.StartTime) + .FirstOrDefault(); - // Create a new Workday and assign the User reference - var workday = new Workday - { - StartTime = DateTime.Now, - User = user // Set the User reference here - }; - - session.Save(workday); - transaction.Commit(); - } - catch (Exception ex) + if (ongoingWorkday != null) { - transaction.Rollback(); - throw new Exception("An error occurred while starting the workday", ex); + // If there is an ongoing workday, throw an exception or return a specific message + throw new Exception("Previous workday wasn't stopped yet."); } + + // Fetch the user entity + var user = session.Get(userId); + if (user == null) throw new Exception("User not found"); + + // Create a new workday if there is no ongoing one + var workday = new Workday + { + StartTime = DateTime.Now, + User = user + }; + + session.Save(workday); + transaction.Commit(); + } + catch (Exception ex) + { + transaction.Rollback(); + throw new Exception("An error occurred while starting the workday", ex); + } + } + } + + public bool StopWorkday(int userId) + { + using (var session = SessionFactory.OpenSession()) + using (var transaction = session.BeginTransaction()) + { + try + { + var workday = session.Query() + .Where(w => w.User.UserId == userId && w.EndTime == null) + .OrderByDescending(w => w.StartTime) + .FirstOrDefault(); + + if (workday == null) + { + return false; // No ongoing workday found + } + + workday.EndTime = DateTime.Now; + + session.Update(workday); + transaction.Commit(); + + return true; + } + catch (Exception ex) + { + transaction.Rollback(); + throw new Exception("An error occurred while stopping the workday", ex); + } + } + } + + public List GetWorkdaysByUser(string email) + { + using (var session = SessionFactory.OpenSession()) + { + try + { + var workdays = session.Query() + .Where(w => w.User.Email == email) + .Select(w => new Workday + { + Id = w.Id, + StartTime = w.StartTime, + EndTime = w.EndTime ?? DateTime.Today.AddHours(17), + WorkedHours = (w.EndTime ?? DateTime.Today.AddHours(17)) - w.StartTime, + }) + .ToList(); + + return workdays; + } + catch (Exception ex) + { + throw new Exception("An error occurred while fetching workdays", ex); } } } diff --git a/nHibernate/Transactions/TransactionCRUD.cs b/nHibernate/Transactions/TransactionCRUD.cs index c16d574..9be2044 100644 --- a/nHibernate/Transactions/TransactionCRUD.cs +++ b/nHibernate/Transactions/TransactionCRUD.cs @@ -94,6 +94,10 @@ namespace FirmTracker_Server.nHibernate.Transactions { var product = session.Get(tp.ProductID); + if(tp.Quantity < 0) + { + + } if (product.Type != 0) { product.Availability += tp.Quantity; @@ -253,6 +257,63 @@ namespace FirmTracker_Server.nHibernate.Transactions } } } + public void DeleteTransactionProduct(int transactionId, int productId) + { + using (var session = SessionFactory.OpenSession()) + using (var t = session.BeginTransaction()) + { + try + { + // Get the transaction to update + var transaction = session.Get(transactionId); + if (transaction == null) + { + throw new InvalidOperationException($"Transaction with ID {transactionId} not found."); + } + + // Find the transaction product to remove + var transactionProduct = transaction.TransactionProducts.FirstOrDefault(tp => tp.ProductID == productId); + if (transactionProduct == null) + { + throw new InvalidOperationException($"Product with ID {productId} not found in the transaction."); + } + + // Get the product to update availability + var product = session.Get(productId); + if (product == null) + { + throw new InvalidOperationException($"Product with ID {productId} not found."); + } + + // Revert the product availability + if (product.Type != 0) + { + product.Availability += transactionProduct.Quantity; + session.Update(product); + } + + // Remove the product from the transaction + transaction.TotalPrice -= (transactionProduct.Quantity * product.Price * (1 - (transaction.Discount / 100))); + transaction.TotalPrice = Math.Round(transaction.TotalPrice, 2, MidpointRounding.AwayFromZero); + + // Remove the product from the Transaction's Product list + transaction.TransactionProducts.Remove(transactionProduct); + + // Now delete the transaction product + session.Delete(transactionProduct); + + // Update the transaction total price + session.Update(transaction); + + t.Commit(); + } + catch (Exception ex) + { + t.Rollback(); + throw new InvalidOperationException($"Error while deleting product from transaction: {ex.Message}"); + } + } + } public IList GetAllTransactions()