profileShare

rasmusjy / splitapp-backend-clean-onion

Read-only snapshot

No repository description.

main default branch 429 files Expires Sep 13, 2026, 9:06 AM
ExpensesController.cs 4,992 bytes
1 using App.BLL.DTO;
2 using App.BLL.Services.Admin;
3 using App.Domain;
4 using Microsoft.AspNetCore.Authorization;
5 using Microsoft.AspNetCore.Mvc;
6 using Microsoft.AspNetCore.Mvc.Rendering;
7 using Microsoft.EntityFrameworkCore;
8 using Microsoft.Extensions.Localization;
9 using WebApp.Areas.Admin.Models;
10
11 namespace WebApp.Areas.Admin.Controllers
12 {
13 [Area("Admin")]
14 [Authorize(Roles = "admin")]
15 public class ExpensesController : Controller
16 {
17 private readonly IExpenseAdminService _service;
18 private readonly IStringLocalizer<App.Resources.Views.Shared> _l;
19
20 public ExpensesController(IExpenseAdminService service, IStringLocalizer<App.Resources.Views.Shared> l)
21 {
22 _service = service;
23 _l = l;
24 }
25
26 private async Task PopulateSelectListsAsync(AdminExpenseFormViewModel vm)
27 {
28 vm.TripList = new SelectList(await _service.GetTripsAsync(), "Id", "Name", vm.Expense.TripId);
29 vm.UserList = new SelectList(await _service.GetUsersAsync(), "Id", "Email", vm.Expense.PaidByUserId);
30 vm.CurrencyList = new SelectList(await _service.GetCurrenciesAsync(), "Id", "Code", vm.Expense.CurrencyId);
31 vm.BudgetCategoryList = new SelectList(await _service.GetBudgetCategoriesAsync(), "Id", "Name", vm.Expense.BudgetCategoryId);
32 }
33
34 public async Task<IActionResult> Index(Guid? tripId, string? search)
35 {
36 var expenses = await _service.GetAllAsync(tripId, search);
37 var trips = (await _service.GetTripsAsync()).OrderBy(t => t.Name).ToList();
38
39 return View(new AdminExpenseIndexViewModel
40 {
41 Title = _l["Expenses"].Value,
42 Items = expenses.OrderByDescending(e => e.ExpenseDate).ToList(),
43 Trips = trips,
44 CurrentTripId = tripId,
45 CurrentSearch = search
46 });
47 }
48
49 public async Task<IActionResult> Details(Guid? id)
50 {
51 if (id == null) return NotFound();
52 var expense = await _service.GetByIdAsync(id.Value);
53 if (expense == null) return NotFound();
54
55 return View(new AdminDetailsViewModel<ExpenseBllDto>
56 {
57 Title = _l["Expense details"].Value,
58 Item = expense
59 });
60 }
61
62 public async Task<IActionResult> Create()
63 {
64 var vm = new AdminExpenseFormViewModel { Title = _l["New expense"].Value };
65 await PopulateSelectListsAsync(vm);
66 return View(vm);
67 }
68
69 [HttpPost]
70 [ValidateAntiForgeryToken]
71 public async Task<IActionResult> Create(AdminExpenseFormViewModel vm)
72 {
73 if (ModelState.IsValid)
74 {
75 await _service.CreateAsync(vm.Expense);
76 return RedirectToAction(nameof(Index));
77 }
78
79 vm.Title = _l["New expense"].Value;
80 await PopulateSelectListsAsync(vm);
81 return View(vm);
82 }
83
84 public async Task<IActionResult> Edit(Guid? id)
85 {
86 if (id == null) return NotFound();
87 var expense = await _service.GetByIdAsync(id.Value);
88 if (expense == null) return NotFound();
89
90 var vm = new AdminExpenseFormViewModel
91 {
92 Title = _l["Edit expense"].Value,
93 Expense = expense
94 };
95 await PopulateSelectListsAsync(vm);
96 return View(vm);
97 }
98
99 [HttpPost]
100 [ValidateAntiForgeryToken]
101 public async Task<IActionResult> Edit(Guid id, AdminExpenseFormViewModel vm)
102 {
103 if (id != vm.Expense.Id) return NotFound();
104
105 if (ModelState.IsValid)
106 {
107 try
108 {
109 await _service.UpdateAsync(vm.Expense);
110 }
111 catch (DbUpdateConcurrencyException)
112 {
113 if (!await _service.ExistsAsync(vm.Expense.Id)) return NotFound();
114 throw;
115 }
116 return RedirectToAction(nameof(Index));
117 }
118
119 vm.Title = _l["Edit expense"].Value;
120 await PopulateSelectListsAsync(vm);
121 return View(vm);
122 }
123
124 public async Task<IActionResult> Delete(Guid? id)
125 {
126 if (id == null) return NotFound();
127 var expense = await _service.GetByIdAsync(id.Value);
128 if (expense == null) return NotFound();
129
130 return View(new AdminDeleteViewModel<ExpenseBllDto>
131 {
132 Title = _l["Delete expense"].Value,
133 Item = expense
134 });
135 }
136
137 [HttpPost, ActionName("Delete")]
138 [ValidateAntiForgeryToken]
139 public async Task<IActionResult> DeleteConfirmed(Guid id)
140 {
141 await _service.DeleteAsync(id);
142 return RedirectToAction(nameof(Index));
143 }
144 }
145 }
146