From c44fbfdca9cb56c40fd9549182f6b202d44f9917 Mon Sep 17 00:00:00 2001 From: Elias Jansson Date: Wed, 4 Jun 2025 18:01:05 +0200 Subject: [PATCH] Woohoo working version gooo --- Aberwyn/Controllers/AdminController.cs | 169 ++++++++++++++++--------- Aberwyn/Controllers/MealController.cs | 5 +- Aberwyn/Data/ApplicationDbContext.cs | 3 + Aberwyn/Data/MenuService.cs | 50 +++----- Aberwyn/Infrastructure/setup.json | 10 +- Aberwyn/Models/MenuViewModel.cs | 1 + Aberwyn/Views/Admin/Index.cshtml | 90 +++++++++++-- 7 files changed, 214 insertions(+), 114 deletions(-) diff --git a/Aberwyn/Controllers/AdminController.cs b/Aberwyn/Controllers/AdminController.cs index 95f92da..f07b575 100644 --- a/Aberwyn/Controllers/AdminController.cs +++ b/Aberwyn/Controllers/AdminController.cs @@ -102,54 +102,20 @@ namespace Aberwyn.Controllers } [HttpPost] [Authorize(Roles = "Admin")] - public IActionResult ImportMealsFromProd() + public IActionResult ImportMenusFromCustom(string dbHost, int dbPort, string dbName, string dbUser, string dbPassword) { - var prodService = MenuService.CreateWithSetup(_env); - var devService = new MenuService(_context); // injicerad context används + var connStr = $"Server={dbHost};Port={dbPort};Database={dbName};Uid={dbUser};Pwd={dbPassword};"; + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseMySql(connStr, ServerVersion.AutoDetect(connStr)); - var prodMeals = prodService.GetMealsDetailed(); - - foreach (var meal in prodMeals) - { - // Kopiera utan ID (för att undvika konflikt) och spara - var newMeal = new Meal - { - Name = meal.Name, - Description = meal.Description, - ProteinType = meal.ProteinType, - Category = meal.Category, - CarbType = meal.CarbType, - RecipeUrl = meal.RecipeUrl, - ImageUrl = meal.ImageUrl, - IsAvailable = meal.IsAvailable, - CreatedAt = meal.CreatedAt, - Instructions = meal.Instructions, - ImageData = meal.ImageData, - ImageMimeType = meal.ImageMimeType, - Ingredients = meal.Ingredients.Select(i => new Ingredient - { - Quantity = i.Quantity, - Item = i.Item - }).ToList() - }; - - devService.SaveOrUpdateMealWithIngredients(newMeal); - } - - return Content("Import klar!"); - } - - [HttpPost] - [Authorize(Roles = "Admin")] - public IActionResult ImportMenusFromProd() - { - var prodService = MenuService.CreateWithConfig(_configuration, _env, useProdDb: true); + using var customContext = new ApplicationDbContext(optionsBuilder.Options); + var sourceService = new MenuService(customContext); var devService = new MenuService(_context); - var allProdMenus = prodService.GetAllWeeklyMenus(); - var allMeals = devService.GetMeals(); + var sourceMenus = sourceService.GetAllWeeklyMenus(); + var devMeals = devService.GetMeals(); - foreach (var menu in allProdMenus) + foreach (var menu in sourceMenus) { var newMenu = new WeeklyMenu { @@ -163,34 +129,92 @@ namespace Aberwyn.Controllers }; if (!string.IsNullOrEmpty(menu.BreakfastMealName)) - newMenu.BreakfastMealId = allMeals.FirstOrDefault(m => m.Name == menu.BreakfastMealName)?.Id; + newMenu.BreakfastMealId = devMeals.FirstOrDefault(m => m.Name == menu.BreakfastMealName)?.Id; if (!string.IsNullOrEmpty(menu.LunchMealName)) - newMenu.LunchMealId = allMeals.FirstOrDefault(m => m.Name == menu.LunchMealName)?.Id; + newMenu.LunchMealId = devMeals.FirstOrDefault(m => m.Name == menu.LunchMealName)?.Id; if (!string.IsNullOrEmpty(menu.DinnerMealName)) - newMenu.DinnerMealId = allMeals.FirstOrDefault(m => m.Name == menu.DinnerMealName)?.Id; + newMenu.DinnerMealId = devMeals.FirstOrDefault(m => m.Name == menu.DinnerMealName)?.Id; _context.WeeklyMenus.Add(newMenu); } _context.SaveChanges(); - TempData["Message"] = "Import av veckomenyer klar."; + TempData["Message"] = $"✅ Import av veckomenyer från extern databas klar ({sourceMenus.Count})."; return RedirectToAction("Index"); } + [HttpPost] [Authorize(Roles = "Admin")] - public IActionResult ImportBudgetFromProd() + public IActionResult ImportMealsFromCustom(string dbHost, int dbPort, string dbName, string dbUser, string dbPassword) { - // Hämta connection till produktion - using var prodContext = ApplicationDbContextFactory.CreateWithConfig(_env, true); + var connStr = $"Server={dbHost};Port={dbPort};Database={dbName};Uid={dbUser};Pwd={dbPassword};"; + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseMySql(connStr, ServerVersion.AutoDetect(connStr), mySqlOptions => mySqlOptions.CommandTimeout(180)); + using var customContext = new ApplicationDbContext(optionsBuilder.Options); - // Importera definitioner först - var prodCategoryDefs = prodContext.BudgetCategoryDefinitions.ToList(); - var prodItemDefs = prodContext.BudgetItemDefinitions.ToList(); + var customService = new MenuService(customContext); + var devService = new MenuService(_context); - foreach (var def in prodCategoryDefs) + try + { + var importedMeals = customService.GetMealsDetailed(); // Ska inkludera Ingredients + foreach (var meal in importedMeals) + { + var newMeal = new Meal + { + Id = meal.Id, // 👈 Viktigt! + Name = meal.Name, + Description = meal.Description, + ProteinType = meal.ProteinType, + Category = meal.Category, + CarbType = meal.CarbType, + RecipeUrl = meal.RecipeUrl, + ImageUrl = meal.ImageUrl, + IsAvailable = meal.IsAvailable, + CreatedAt = meal.CreatedAt, + Instructions = meal.Instructions, + ImageData = meal.ImageData, + ImageMimeType = meal.ImageMimeType, + Ingredients = meal.Ingredients.Select(i => new Ingredient + { + MealId = meal.Id, // 👈 Koppla till rätt måltid + Quantity = i.Quantity, + Item = i.Item + }).ToList() + }; + + devService.SaveOrUpdateMealWithIngredients(newMeal); + } + + TempData["Message"] = $"✅ {importedMeals.Count} måltider importerade från extern databas."; + } + catch (Exception ex) + { + TempData["Message"] = $"❌ Fel vid import: {ex.Message}"; + } + + return RedirectToAction("Index"); + } + + + + [HttpPost] + [Authorize(Roles = "Admin")] + public IActionResult ImportBudgetFromCustom(string dbHost, int dbPort, string dbName, string dbUser, string dbPassword) + { + var connStr = $"Server={dbHost};Port={dbPort};Database={dbName};Uid={dbUser};Pwd={dbPassword};"; + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseMySql(connStr, ServerVersion.AutoDetect(connStr)); + + using var sourceContext = new ApplicationDbContext(optionsBuilder.Options); + + var categoryDefs = sourceContext.BudgetCategoryDefinitions.ToList(); + var itemDefs = sourceContext.BudgetItemDefinitions.ToList(); + + foreach (var def in categoryDefs) { if (!_context.BudgetCategoryDefinitions.Any(d => d.Name == def.Name)) { @@ -199,11 +223,10 @@ namespace Aberwyn.Controllers Name = def.Name, Color = def.Color ?? "#cccccc" }); - } } - foreach (var def in prodItemDefs) + foreach (var def in itemDefs) { if (!_context.BudgetItemDefinitions.Any(d => d.Name == def.Name)) { @@ -211,19 +234,17 @@ namespace Aberwyn.Controllers } } - _context.SaveChanges(); // Se till att ID:n finns för FK:n nedan + _context.SaveChanges(); - // Ladda definitioner i minnet för snabb lookup var devCategoryDefs = _context.BudgetCategoryDefinitions.ToList(); var devItemDefs = _context.BudgetItemDefinitions.ToList(); - // Importera budgetperioder med kategorier och items - var prodPeriods = prodContext.BudgetPeriods + var periods = sourceContext.BudgetPeriods .Include(p => p.Categories) .ThenInclude(c => c.Items) .ToList(); - foreach (var period in prodPeriods) + foreach (var period in periods) { var exists = _context.BudgetPeriods .Any(p => p.Year == period.Year && p.Month == period.Month); @@ -259,11 +280,13 @@ namespace Aberwyn.Controllers } _context.SaveChanges(); - TempData["Message"] = "✅ Import av budgetdata från produktion är klar."; + TempData["Message"] = $"✅ Import av budgetdata från extern databas klar ({periods.Count} månader)."; return RedirectToAction("Index"); } + + //Todo [HttpGet] @@ -314,9 +337,31 @@ namespace Aberwyn.Controllers return Ok(); } + [HttpPost] + [Authorize(Roles = "Admin")] + public IActionResult TestDbConnection(string dbHost, int dbPort, string dbName, string dbUser, string dbPassword) + { + var connStr = $"Server={dbHost};Port={dbPort};Database={dbName};Uid={dbUser};Pwd={dbPassword};"; + try + { + var builder = new DbContextOptionsBuilder(); + builder.UseMySql(connStr, ServerVersion.AutoDetect(connStr)); + + using var context = new ApplicationDbContext(builder.Options); + context.Database.OpenConnection(); + context.Database.CloseConnection(); + + return Json(new { success = true, message = "✅ Anslutning lyckades!" }); + } + catch (Exception ex) + { + return Json(new { success = false, message = $"❌ Anslutning misslyckades: {ex.Message}" }); + } + } } + public class AdminUserViewModel { public string UserId { get; set; } diff --git a/Aberwyn/Controllers/MealController.cs b/Aberwyn/Controllers/MealController.cs index 5e7b194..fb0970b 100644 --- a/Aberwyn/Controllers/MealController.cs +++ b/Aberwyn/Controllers/MealController.cs @@ -10,12 +10,13 @@ namespace Aberwyn.Controllers private readonly IConfiguration _configuration; private readonly IHostEnvironment _env; private readonly MenuService _menuService; - - public MealController(IConfiguration configuration, IHostEnvironment env) + public MealController(MenuService menuService, IConfiguration configuration, IHostEnvironment env) { + _menuService = menuService; _configuration = configuration; _env = env; } + [HttpGet] public IActionResult View(int id, bool edit = false) { diff --git a/Aberwyn/Data/ApplicationDbContext.cs b/Aberwyn/Data/ApplicationDbContext.cs index e5ece4e..d6dd3b9 100644 --- a/Aberwyn/Data/ApplicationDbContext.cs +++ b/Aberwyn/Data/ApplicationDbContext.cs @@ -16,6 +16,9 @@ namespace Aberwyn.Data base.OnModelCreating(builder); builder.Entity().ToTable("WeeklyMenu"); + builder.Entity() + .Property(m => m.Id) + .ValueGeneratedNever(); } diff --git a/Aberwyn/Data/MenuService.cs b/Aberwyn/Data/MenuService.cs index dbecfd2..b95ef19 100644 --- a/Aberwyn/Data/MenuService.cs +++ b/Aberwyn/Data/MenuService.cs @@ -16,37 +16,6 @@ public class MenuService _context = context; } - // Detta är en alternativ konstruktör – används manuellt vid t.ex. import - public static MenuService CreateWithConfig(IConfiguration config, IHostEnvironment env, bool useProdDb = false) - { - var basePath = env.ContentRootPath ?? Directory.GetCurrentDirectory(); - var setupPath = Path.Combine(basePath, "infrastructure", "setup.json"); - - if (!File.Exists(setupPath)) - throw new FileNotFoundException("setup.json saknas i infrastructure/"); - - var setupJson = File.ReadAllText(setupPath); - var setup = System.Text.Json.JsonSerializer.Deserialize(setupJson)!; - - if (!setup.IsConfigured || string.IsNullOrWhiteSpace(setup.DbPassword)) - throw new InvalidOperationException("setup.json är ofullständig."); - - var csBuilder = new MySqlConnector.MySqlConnectionStringBuilder - { - Server = setup.DbHost, - Port = (uint)setup.DbPort, - Database = setup.DbName, - UserID = setup.DbUser, - Password = setup.DbPassword, - AllowUserVariables = true - }; - - var builder = new DbContextOptionsBuilder(); - builder.UseMySql(csBuilder.ConnectionString, ServerVersion.AutoDetect(csBuilder.ConnectionString)); - - var context = new ApplicationDbContext(builder.Options); - return new MenuService(context); - } public static MenuService CreateWithSetup(IHostEnvironment env) { var setup = SetupLoader.Load(env); @@ -83,15 +52,26 @@ public class MenuService meal.Name = meal.Name.Trim(); meal.CreatedAt = meal.CreatedAt == default ? DateTime.Now : meal.CreatedAt; - if (meal.Id == 0) - _context.Meals.Add(meal); + var existing = _context.Meals + .AsNoTracking() + .FirstOrDefault(m => m.Id == meal.Id); + + if (existing == null) + { + // Nytt objekt – försök behålla ID:t från prod + _context.Entry(meal).State = EntityState.Added; + } else + { + // Befintlig – uppdatera _context.Meals.Update(meal); + } _context.SaveChanges(); } -public List GetAllWeeklyMenus() + + public List GetAllWeeklyMenus() { var menus = _context.WeeklyMenus.ToList(); @@ -139,10 +119,12 @@ public List GetAllWeeklyMenus() public List GetMealsDetailed() { return _context.Meals + .Include(m => m.Ingredients) // 🧠 detta behövs! .OrderByDescending(m => m.CreatedAt) .ToList(); } + public Meal GetMealById(int id) { var meal = _context.Meals diff --git a/Aberwyn/Infrastructure/setup.json b/Aberwyn/Infrastructure/setup.json index 48eaad4..eba5681 100644 --- a/Aberwyn/Infrastructure/setup.json +++ b/Aberwyn/Infrastructure/setup.json @@ -2,10 +2,10 @@ "AdminUsername": "admin", "AdminEmail": "admin@localhost", "AdminPassword": "Admin123!", - "IsConfigured": false, - "DbHost": null, + "IsConfigured": true, + "DbHost": "192.168.1.108", "DbPort": 3306, - "DbName": null, - "DbUser": null, - "DbPassword": null + "DbName": "lewel_prod", + "DbUser": "lewel", + "DbPassword": "W542.Hl;)%ta" } \ No newline at end of file diff --git a/Aberwyn/Models/MenuViewModel.cs b/Aberwyn/Models/MenuViewModel.cs index 57ee9d0..7958f49 100644 --- a/Aberwyn/Models/MenuViewModel.cs +++ b/Aberwyn/Models/MenuViewModel.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Aberwyn.Data; using Aberwyn.Models; diff --git a/Aberwyn/Views/Admin/Index.cshtml b/Aberwyn/Views/Admin/Index.cshtml index c370eed..f30d4af 100644 --- a/Aberwyn/Views/Admin/Index.cshtml +++ b/Aberwyn/Views/Admin/Index.cshtml @@ -84,20 +84,88 @@ -
-

Importera måltider från produktion

-
- -
-
- -
-
- -
+
+
+ Importera från annan databas +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + + +
+
+ +