Compare commits
2 Commits
f531bf54af
...
8da7888933
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8da7888933 | ||
|
|
9e34e45748 |
@@ -1,6 +1,8 @@
|
|||||||
using Aberwyn.Models;
|
using Aberwyn.Data;
|
||||||
|
using Aberwyn.Models;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace Aberwyn.Controllers
|
namespace Aberwyn.Controllers
|
||||||
{
|
{
|
||||||
@@ -12,6 +14,9 @@ namespace Aberwyn.Controllers
|
|||||||
{
|
{
|
||||||
ViewBag.Year = year;
|
ViewBag.Year = year;
|
||||||
ViewBag.Month = month;
|
ViewBag.Month = month;
|
||||||
|
DateTime payDate = SalaryDateService.GetSalaryPayDate(year, month -1);
|
||||||
|
ViewBag.Paydate = payDate.ToString("d MMMM", new CultureInfo("sv-SE"));
|
||||||
|
|
||||||
return View();
|
return View();
|
||||||
}
|
}
|
||||||
[Route("budget/list")]
|
[Route("budget/list")]
|
||||||
@@ -39,9 +44,19 @@ namespace Aberwyn.Controllers
|
|||||||
public IActionResult Index()
|
public IActionResult Index()
|
||||||
{
|
{
|
||||||
var now = DateTime.Now;
|
var now = DateTime.Now;
|
||||||
return RedirectToAction("Index", new { year = now.Year, month = now.Month });
|
return RedirectToAction("Index", new { year = now.Year, month = now.Month + 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("api/budget/{year:int}/{month:int}/salary-date")]
|
||||||
|
public IActionResult SalaryDate(int year, int month)
|
||||||
|
{
|
||||||
|
var date = SalaryDateService.GetSalaryPayDate(year, month);
|
||||||
|
|
||||||
|
return Ok(new
|
||||||
|
{
|
||||||
|
iso = date.ToString("yyyy-MM-dd"),
|
||||||
|
display = date.ToString("d MMMM yyyy", new CultureInfo("sv-SE"))
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
96
Aberwyn/Data/PayoutService.cs
Normal file
96
Aberwyn/Data/PayoutService.cs
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
using Aberwyn.Data;
|
||||||
|
|
||||||
|
namespace Aberwyn.Data
|
||||||
|
{
|
||||||
|
public class PayoutService
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class SwedishHolidays
|
||||||
|
{
|
||||||
|
public static bool IsRedDay(DateTime date)
|
||||||
|
{
|
||||||
|
var year = date.Year;
|
||||||
|
|
||||||
|
var fixedHolidays = new[]
|
||||||
|
{
|
||||||
|
new DateTime(year, 1, 1), // Nyårsdagen
|
||||||
|
new DateTime(year, 1, 6), // Trettondedag jul
|
||||||
|
new DateTime(year, 5, 1), // Första maj
|
||||||
|
new DateTime(year, 6, 6), // Nationaldagen
|
||||||
|
new DateTime(year, 12, 25), // Juldagen
|
||||||
|
new DateTime(year, 12, 26), // Annandag jul
|
||||||
|
};
|
||||||
|
|
||||||
|
if (fixedHolidays.Contains(date.Date))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Rörliga helgdagar
|
||||||
|
var easter = GetEasterSunday(year);
|
||||||
|
|
||||||
|
var movable = new[]
|
||||||
|
{
|
||||||
|
easter.AddDays(-2), // Långfredagen
|
||||||
|
easter, // Påskdagen
|
||||||
|
easter.AddDays(1), // Annandag påsk
|
||||||
|
easter.AddDays(39), // Kristi himmelsfärd
|
||||||
|
easter.AddDays(49), // Pingstdagen
|
||||||
|
GetMidsummerDay(year),
|
||||||
|
};
|
||||||
|
|
||||||
|
return movable.Contains(date.Date);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DateTime GetMidsummerDay(int year)
|
||||||
|
{
|
||||||
|
// Lördag mellan 20–26 juni
|
||||||
|
for (int day = 20; day <= 26; day++)
|
||||||
|
{
|
||||||
|
var d = new DateTime(year, 6, day);
|
||||||
|
if (d.DayOfWeek == DayOfWeek.Saturday)
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
throw new Exception("Midsummer not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DateTime GetEasterSunday(int year)
|
||||||
|
{
|
||||||
|
// Meeus/Jones/Butcher
|
||||||
|
int a = year % 19;
|
||||||
|
int b = year / 100;
|
||||||
|
int c = year % 100;
|
||||||
|
int d = b / 4;
|
||||||
|
int e = b % 4;
|
||||||
|
int f = (b + 8) / 25;
|
||||||
|
int g = (b - f + 1) / 3;
|
||||||
|
int h = (19 * a + b - d - g + 15) % 30;
|
||||||
|
int i = c / 4;
|
||||||
|
int k = c % 4;
|
||||||
|
int l = (32 + 2 * e + 2 * i - h - k) % 7;
|
||||||
|
int m = (a + 11 * h + 22 * l) / 451;
|
||||||
|
int month = (h + l - 7 * m + 114) / 31;
|
||||||
|
int day = ((h + l - 7 * m + 114) % 31) + 1;
|
||||||
|
|
||||||
|
return new DateTime(year, month, day);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public static class SalaryDateService
|
||||||
|
{
|
||||||
|
public static DateTime GetSalaryPayDate(int year, int month)
|
||||||
|
{
|
||||||
|
var payDate = new DateTime(year, month, 25);
|
||||||
|
|
||||||
|
while (payDate.DayOfWeek == DayOfWeek.Saturday ||
|
||||||
|
payDate.DayOfWeek == DayOfWeek.Sunday ||
|
||||||
|
SwedishHolidays.IsRedDay(payDate))
|
||||||
|
{
|
||||||
|
payDate = payDate.AddDays(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return payDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -127,4 +127,6 @@ namespace Aberwyn.Models
|
|||||||
public string Color { get; set; } // standardfärg, kan modifieras per period
|
public string Color { get; set; } // standardfärg, kan modifieras per period
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
<div class="budget-summary-box compact">
|
<div class="budget-summary-box compact">
|
||||||
<h3>Sammanställning</h3>
|
<h3>Sammanställning</h3>
|
||||||
<ul class="summary-list">
|
<ul class="summary-list">
|
||||||
|
<li><span>Utbetalning:</span>{{ salaryPayDate || '–' }}</li>
|
||||||
<li><span>💰 Inkomst:</span> {{ getTotalIncome() | number:0 }} kr</li>
|
<li><span>💰 Inkomst:</span> {{ getTotalIncome() | number:0 }} kr</li>
|
||||||
<li><span>💸 Utgift:</span> {{ getTotalExpense() | number:0 }} kr</li>
|
<li><span>💸 Utgift:</span> {{ getTotalExpense() | number:0 }} kr</li>
|
||||||
<li><span>🏦 Sparande:</span> {{ getTotalSaving() | number:0 }} kr</li>
|
<li><span>🏦 Sparande:</span> {{ getTotalSaving() | number:0 }} kr</li>
|
||||||
|
|||||||
@@ -60,6 +60,15 @@ app.controller('BudgetController', function ($scope, $http) {
|
|||||||
$scope.loadBudget();
|
$scope.loadBudget();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.loadSalaryDate = function () {
|
||||||
|
const year = $scope.selectedYear;
|
||||||
|
const month = $scope.selectedMonth -1;
|
||||||
|
|
||||||
|
$http.get(`/api/budget/${year}/${month}/salary-date`)
|
||||||
|
.then(function (res) {
|
||||||
|
$scope.salaryPayDate = res.data.display;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
$scope.setItemType = function (item, type) {
|
$scope.setItemType = function (item, type) {
|
||||||
if (type === 'expense') {
|
if (type === 'expense') {
|
||||||
@@ -216,6 +225,7 @@ app.controller('BudgetController', function ($scope, $http) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.finally(function () {
|
.finally(function () {
|
||||||
|
$scope.loadSalaryDate();
|
||||||
$scope.loading = false;
|
$scope.loading = false;
|
||||||
setTimeout($scope.drawCategoryChart, 0);
|
setTimeout($scope.drawCategoryChart, 0);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user