Finished getting integration to barebones with API key authentication

This commit is contained in:
William Lewis 2024-03-19 21:21:27 -05:00
parent d08ee5db5a
commit 22f7a9363d
86 changed files with 358 additions and 10402 deletions

View File

@ -67,18 +67,4 @@ public class AccountsController : ControllerBase
_accountService.Delete(id);
return Ok(new { message = "account deleted" });
}
[HttpGet("RefreshBalance/{id}")]
public IActionResult RefreshBalance(int id)
{
Account account = _accountService.RefreshAccountBalance(id);
return Ok(_mapper.Map<Account, AccountDTO>(account));
}
[HttpGet("Historical/{id}")]
public IActionResult Historical(int id, int lookBack)
{
AccountHistorical hist = _accountService.GetAccountHistorical(id, lookBack);
return Ok(_mapper.Map<AccountHistorical, AccountHistoricalDTO>(hist));
}
}

View File

@ -1,83 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Controllers;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using AAIntegration.SimmonsBank.API.Models.Users;
using AAIntegration.SimmonsBank.API.Services;
using AAIntegration.SimmonsBank.API.Config;
using System;
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
[Authorize]
[ApiController]
[Route("[controller]")]
public class ApiKeyController : ControllerBase
{
private IApiKeyService _apiKeyService;
private IMapper _mapper;
private readonly AppSettings _appSettings;
private readonly ILogger<ApiKeyController> _logger;
private IUserService _userService;
public ApiKeyController(
IApiKeyService apiKeyService,
IMapper mapper,
IOptions<AppSettings> appSettings,
ILogger<ApiKeyController> logger,
IUserService userService)
{
_apiKeyService = apiKeyService;
_mapper = mapper;
_appSettings = appSettings.Value;
_logger = logger;
_userService = userService;
}
[HttpGet]
public IActionResult GetApiKey()
{
string apiKey = _userService.GetUserApiKey(this.GetCurrentUserId());
string[] apiKeys = { apiKey };
Console.WriteLine($"User API Key Got: " + apiKey);
return Ok(new { keys = apiKeys });
}
/*[HttpGet("{id}")]
public IActionResult GetById(int id)
{
var user = _apiKeyService.GetById(id);
return Ok(user);
}*/
[HttpGet("CreateNew")]
public IActionResult CreateNewApiKey()
{
string apiKey = _userService.CreateUserApiKey(this.GetCurrentUserId());
return Ok(new { message = "API Key created", key = apiKey });
}
[HttpDelete("{apiKey}")]
public IActionResult Delete(string apiKey)
{
_userService.InvalidateApiKey(apiKey);
return Ok(new { message = "API Key deleted" });
}
// Helpers
private int GetCurrentUserId()
{
string nameIdentifier = User.FindFirstValue(ClaimTypes.NameIdentifier);
if (nameIdentifier is null)
_logger.LogInformation($"Name Identifier: is null");
_logger.LogInformation($"Name Identifier: {nameIdentifier}");
Console.WriteLine($"User Id: " + nameIdentifier);
return Convert.ToInt32(nameIdentifier);
}
}

View File

@ -1,103 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Controllers;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using AAIntegration.SimmonsBank.API.Models.Autoclass;
using AAIntegration.SimmonsBank.API.Services;
using AAIntegration.SimmonsBank.API.Config;
using System.Collections.Generic;
using AAIntegration.SimmonsBank.API.Entities;
using Microsoft.AspNetCore.Authorization;
[Authorize]
[ApiController]
[Route("[controller]")]
public class AutoclassController : ControllerBase
{
private IAutoclassService _autoclassService;
private IMapper _mapper;
private readonly AppSettings _appSettings;
public AutoclassController(
IAutoclassService autoclassService,
IMapper mapper,
IOptions<AppSettings> appSettings)
{
_autoclassService = autoclassService;
_mapper = mapper;
_appSettings = appSettings.Value;
}
[HttpGet]
public IActionResult GetAll(int? account = null)
{
List<AutoclassRuleDTO> autoclassDtos = new List<AutoclassRuleDTO>();
foreach (AutoclassRule auto in _autoclassService.GetAll(account))
autoclassDtos.Add(_mapper.Map<AutoclassRule, AutoclassRuleDTO>(auto));
return Ok(autoclassDtos);
}
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
AutoclassRule auto = _autoclassService.GetById(id);
return Ok(_mapper.Map<AutoclassRule, AutoclassRuleDTO>(auto));
}
[HttpPost]
public IActionResult Create([FromBody]AutoclassRuleCreateRequest model)
{
_autoclassService.Create(model);
return Ok(new { message = "AutoclassRule created" });
}
[HttpPut("{id}")]
public IActionResult Update(int id, [FromBody]AutoclassRuleUpdateRequest model)
{
_autoclassService.Update(id, model);
return Ok(new { message = "AutoclassRule updated" });
}
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
_autoclassService.Delete(id);
return Ok(new { message = "AutoclassRule deleted" });
}
/*[HttpGet("RefreshBalance/{id}")]
public IActionResult RefreshBalance(int id)
{
Account account = _accountService.RefreshAccountBalance(id);
return Ok(_mapper.Map<Account, AccountDTO>(account));
}*/
// [HttpGet("RefreshBalance/{id}")]
[HttpGet("TypeOperatorInfo")]
public IActionResult GetAllTypeOperatorInfo()
{
return Ok(_autoclassService.GetAllTypeOperatorInfo());
}
[HttpGet("FieldInfo")]
public IActionResult GetAllFieldInfo()
{
return Ok(_autoclassService.GetAllFieldInfo());
}
[HttpGet("TriggerAutoclassRule/{id}")]
public IActionResult TriggerAutoclassRule(int id)
{
int affectedTransactions = _autoclassService.ApplyAutoclassRule(id);
return Ok(new { message = $"AutoclassRule triggered and updated {affectedTransactions} transaction(s)." });
}
[HttpGet("TriggerTransactionRules/{id}")]
public IActionResult TriggerAutoclassRulesForTransaction(int id)
{
int triggeredRules = _autoclassService.ApplyRulesForTransaction(id);
return Ok(new { message = $"Transaction triggered {triggeredRules} autoclass rule(s)." });
}
}

View File

@ -1,64 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Controllers;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using AAIntegration.SimmonsBank.API.Models.CurrencyType;
using AAIntegration.SimmonsBank.API.Services;
using AAIntegration.SimmonsBank.API.Config;
using Microsoft.AspNetCore.Authorization;
[Authorize]
[ApiController]
[Route("[controller]")]
public class CurrencyTypesController : ControllerBase
{
private ICurrencyTypeService _currencyTypeService;
private IMapper _mapper;
private readonly AppSettings _appSettings;
public CurrencyTypesController(
ICurrencyTypeService currencyTypeService,
IMapper mapper,
IOptions<AppSettings> appSettings)
{
_currencyTypeService = currencyTypeService;
_mapper = mapper;
_appSettings = appSettings.Value;
}
[HttpGet]
public IActionResult GetAll()
{
var currencyTypes = _currencyTypeService.GetAll();
return Ok(currencyTypes);
}
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
var currencyType = _currencyTypeService.GetById(id);
return Ok(currencyType);
}
[HttpPost]
public IActionResult Create([FromBody]CurrencyTypeCreateRequest model)
{
_currencyTypeService.Create(model);
return Ok(new { message = "currencyType created" });
}
/*[HttpPut("{id}")]
public IActionResult Update(int id, [FromBody]AccountUpdateRequest model)
{
_accountService.Update(id, model);
return Ok(new { message = "account updated" });
}*/
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
_currencyTypeService.Delete(id);
return Ok(new { message = "currencyType deleted" });
}
}

View File

@ -1,108 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Controllers;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using AAIntegration.SimmonsBank.API.Models.Envelopes;
using AAIntegration.SimmonsBank.API.Services;
using AAIntegration.SimmonsBank.API.Config;
using System.Collections.Generic;
using AAIntegration.SimmonsBank.API.Entities;
using Microsoft.AspNetCore.Authorization;
[Authorize]
[ApiController]
[Route("[controller]")]
public class EnvelopesController : ControllerBase
{
private IEnvelopeService _envelopeService;
private IMapper _mapper;
private readonly AppSettings _appSettings;
public EnvelopesController(
IEnvelopeService envelopeService,
IMapper mapper,
IOptions<AppSettings> appSettings)
{
_envelopeService = envelopeService;
_mapper = mapper;
_appSettings = appSettings.Value;
}
[HttpGet]
public IActionResult GetAll(int? accountId = null)
{
List<EnvelopeDTO> envelopeDtos = new List<EnvelopeDTO>();
foreach (Envelope env in _envelopeService.GetAll(accountId))
{
List<EnvelopeFundingMethodDTO> methodDtos = new List<EnvelopeFundingMethodDTO>();
foreach (EnvelopeFundingMethod method in env.FundingMethods)
{
methodDtos.Add(_mapper.Map<EnvelopeFundingMethod, EnvelopeFundingMethodDTO>(method));
}
EnvelopeDTO dto = new EnvelopeDTO {
Id = env.Id,
Name = env.Name,
AccountId = env.Account == null ? 0 : env.Account.Id,
Enabled = env.Enabled,
Period = env.Period,
IsPersistant = env.IsPersistant,
Priority = env.Priority,
Balance = env.Balance,
InitialBalance = env.InitialBalance,
LastTriggeredOn = env.LastTriggeredOn,
FundingMethods = methodDtos
};
envelopeDtos.Add(dto);
}
//envelopeDtos.Add(_mapper.Map<Envelope, EnvelopeDTO>(env));
return Ok(envelopeDtos);
}
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
Envelope envelope = _envelopeService.GetById(id);
return Ok(_mapper.Map<Envelope, EnvelopeDTO>(envelope));
}
[HttpPost]
public IActionResult Create([FromBody]EnvelopeCreateRequest model)
{
_envelopeService.Create(model);
return Ok(new { message = "envelope created" });
}
[HttpPut("{id}")]
public IActionResult Update(int id, [FromBody]EnvelopeUpdateRequest model)
{
_envelopeService.Update(id, model);
return Ok(new { message = "envelope updated" });
}
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
_envelopeService.Delete(id);
return Ok(new { message = "envelope deleted" });
}
[HttpGet("Historical/{id}")]
public IActionResult Historical(int id, int lookBack)
{
EnvelopeHistorical hist = _envelopeService.GetEnvelopeHistorical(id, lookBack);
return Ok(_mapper.Map<EnvelopeHistorical, EnvelopeHistoricalDTO>(hist));
}
[HttpGet("FundingMethodModes")]
public IActionResult FundingMethodModes()
{
List<EnvelopeFundingMethodModes> modes = _envelopeService.GetEnvelopeFundingMethodModes();
return Ok(modes);
}
}

View File

@ -8,6 +8,7 @@ using AAIntegration.SimmonsBank.API.Services;
using AAIntegration.SimmonsBank.API.Config;
using System;
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;
[ApiController]
[Route("[controller]")]
@ -30,41 +31,18 @@ public class UsersController : ControllerBase
_logger = logger;
}
[HttpPost("authenticate")]
public IActionResult Authenticate(AuthenticateRequest model)
{
var response = _userService.Authenticate(model);
return Ok(response);
}
[HttpPost("register")]
public IActionResult Register(RegisterRequest model)
public IActionResult Register(UserCreateRequest model)
{
_userService.Register(model);
return Ok(new { message = "Registration successful" });
}
[Authorize]
[HttpGet]
public IActionResult GetAll()
{
var users = _userService.GetAll();
return Ok(users);
}
[Authorize]
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
var user = _userService.GetById(id);
return Ok(user);
string apiKey = _userService.Create(model);
return Ok(new { ApiKey = apiKey });
}
[Authorize]
[HttpPut("{id}")]
public IActionResult Update(int id, [FromBody]UserUpdateRequest model)
public IActionResult Update([FromBody]UserUpdateRequest model)
{
_userService.Update(id, model);
_userService.Update(this.GetCurrentUserApiKey(), model);
return Ok(new { message = "User updated" });
}
@ -72,7 +50,22 @@ public class UsersController : ControllerBase
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
_userService.Delete(id);
_userService.Delete(this.GetCurrentUserApiKey());
return Ok(new { message = "User deleted" });
}
// Helpers
private string GetCurrentUserApiKey()
{
string apiKey = User.FindFirstValue(ClaimTypes.NameIdentifier);
if (apiKey is null)
_logger.LogInformation($"ApiKey: is null");
_logger.LogInformation($"apiKey: {apiKey}");
Console.WriteLine($"User Id: " + apiKey);
return apiKey;
}
}

View File

@ -1,32 +0,0 @@
using Microsoft.AspNetCore.Mvc;
namespace AAIntegration.SimmonsBank.API.Controllers;
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}

View File

@ -6,15 +6,6 @@ public class Account
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime LastActivity { get; set; }
public decimal VirtualBalance { get; set; }
public decimal Balance { get; set; }
public DateTime CreatedOn { get; set; }
public decimal InitialBalance { get; set; }
public int CurrencyId { get; set; }
public CurrencyType Currency { get; set; }
public string ExternalAccountNumber { get; set; }
public ICollection<Envelope> Envelopes { get; set; }
//public ICollection<Transaction> Transactions { get; set; }
//public Institution institution { get; set; }
}

View File

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Text.Json.Serialization;
namespace AAIntegration.SimmonsBank.API.Entities;
public class AccountHistorical
{
//public int Id { get; set; }
public Account Account { get; set; }
public int LookBack { get; set; }
public Statistic Income { get; set; } = null;
public Statistic Credit { get; set; } = null;
public Statistic Debit { get; set; } = null;
}

View File

@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Text.Json.Serialization;
namespace AAIntegration.SimmonsBank.API.Entities;
public class AutoclassChange
{
public int Id { get; set; }
public AutoclassTransactionField Field { get; set; }
public string Value { get; set; }
}

View File

@ -1,232 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Text.Json.Serialization;
namespace AAIntegration.SimmonsBank.API.Entities;
public class AutoclassExpression
{
public int Id { get; set; }
public AutoclassTransactionField TransactionField { get; set; }
public AutoclassCompareOperator CompareOperator { get; set; }
public string Value { get; set; }
public bool Evaluate(Transaction transaction)
{
switch (TransactionField)
{
case AutoclassTransactionField.DATE:
return EvaluateDateType(transaction.Date);
case AutoclassTransactionField.EXTERNAL_ID:
return EvaluateStringType(transaction.ExternalId);
case AutoclassTransactionField.DESCRIPTION:
return EvaluateStringType(transaction.Description);
case AutoclassTransactionField.AMOUNT:
return EvaluateDecimalType(transaction.Amount);
case AutoclassTransactionField.IS_PENDING:
return EvaluateBoolType(transaction.IsPending);
case AutoclassTransactionField.DEBIT_ACCOUNT:
return EvaluateAccountType(transaction.DebitAccount);
case AutoclassTransactionField.CREDIT_ACCOUNT:
return EvaluateAccountType(transaction.CreditAccount);
case AutoclassTransactionField.DEBIT_ENVELOPE:
return EvaluateEnvelopeType(transaction.DebitEnvelope);
case AutoclassTransactionField.CREDIT_ENVELOPE:
return EvaluateEnvelopeType(transaction.CreditEnvelope);
case AutoclassTransactionField.CURRENCY_TYPE:
return EvaluateCurrencyType(transaction.CurrencyType);
case AutoclassTransactionField.TAGS:
return EvaluateStringArrayType(transaction.Tags);
default:
throw new Exception($"AutoclassExpression::Evaluate(Transaction) couldn't recognize the field '{TransactionField}'.");
}
}
private bool EvaluateDateType(DateTime currentValue)
{
/*DateTime expValue = Convert.ToDateTime(Value);
var dt = DateTime.ParseExact(Value , "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);*/
DateTime expValue = DateTime.Parse(Value, null, System.Globalization.DateTimeStyles.RoundtripKind);
switch (CompareOperator)
{
case AutoclassCompareOperator.EQUAL:
return currentValue.Date == expValue.Date;
case AutoclassCompareOperator.NOT_EQUAL:
return currentValue.Date != expValue.Date;
case AutoclassCompareOperator.GREATER_THAN:
return currentValue.Date > expValue.Date;
case AutoclassCompareOperator.GREATER_THAN_OR_EQUAL:
return currentValue.Date >= expValue.Date;
case AutoclassCompareOperator.LESS_THAN:
return currentValue.Date < expValue.Date;
case AutoclassCompareOperator.LESS_THAN_OR_EQUAL:
return currentValue.Date <= expValue.Date;
default:
throw new Exception($"Invalid compare operator '{CompareOperator}' for type 'DateTime'");
}
}
private bool EvaluateStringType(string currentValue)
{
switch (CompareOperator)
{
case AutoclassCompareOperator.EQUAL:
return currentValue == Value;
case AutoclassCompareOperator.NOT_EQUAL:
return currentValue != Value;
case AutoclassCompareOperator.CONTAINS:
return currentValue.Contains(Value);
case AutoclassCompareOperator.CONTAINS_INSENSITIVE:
return currentValue.ToUpper().Contains(Value.ToUpper());
default:
throw new Exception($"Invalid compare operator '{CompareOperator}' for type 'string'");
}
}
private bool EvaluateDecimalType(decimal currentValue)
{
decimal expValue = Convert.ToDecimal(Value);
switch (CompareOperator)
{
case AutoclassCompareOperator.EQUAL:
return currentValue == expValue;
case AutoclassCompareOperator.NOT_EQUAL:
return currentValue != expValue;
case AutoclassCompareOperator.GREATER_THAN:
return currentValue > expValue;
case AutoclassCompareOperator.GREATER_THAN_OR_EQUAL:
return currentValue >= expValue;
case AutoclassCompareOperator.LESS_THAN:
return currentValue < expValue;
case AutoclassCompareOperator.LESS_THAN_OR_EQUAL:
return currentValue <= expValue;
default:
throw new Exception($"Invalid compare operator '{CompareOperator}' for type 'decimal'");
}
}
private bool EvaluateBoolType(bool currentValue)
{
bool expValue = Convert.ToBoolean(Value);
switch (CompareOperator)
{
case AutoclassCompareOperator.EQUAL:
return currentValue == expValue;
case AutoclassCompareOperator.NOT_EQUAL:
return currentValue != expValue;
default:
throw new Exception($"Invalid compare operator '{CompareOperator}' for type 'boolean'");
}
}
private bool EvaluateAccountType(Account currentValue)
{
int expValue = Convert.ToInt32(Value);
switch (CompareOperator)
{
case AutoclassCompareOperator.EQUAL:
if (currentValue == null)
return expValue == 0;
else
return currentValue.Id == expValue;
case AutoclassCompareOperator.NOT_EQUAL:
if (currentValue == null)
return expValue != 0;
else
return currentValue.Id != expValue;
default:
throw new Exception($"Invalid compare operator '{CompareOperator}' for type 'Account'");
}
}
//evaluateEnvelopeType
private bool EvaluateEnvelopeType(Envelope currentValue)
{
int expValue = Convert.ToInt32(Value);
switch (CompareOperator)
{
case AutoclassCompareOperator.EQUAL:
if (currentValue == null)
return expValue == 0;
else
return currentValue.Id == expValue;
case AutoclassCompareOperator.NOT_EQUAL:
if (currentValue == null)
return expValue != 0;
else
return currentValue.Id != expValue;
default:
throw new Exception($"Invalid compare operator '{CompareOperator}' for type 'Envelope'");
}
}
private bool EvaluateCurrencyType(CurrencyType currentValue)
{
int expValue = Convert.ToInt32(Value);
switch (CompareOperator)
{
case AutoclassCompareOperator.EQUAL:
if (currentValue == null)
return expValue == 0;
else
return currentValue.Id == expValue;
case AutoclassCompareOperator.NOT_EQUAL:
if (currentValue == null)
return expValue != 0;
else
return currentValue.Id != expValue;
default:
throw new Exception($"Invalid compare operator '{CompareOperator}' for type 'CurrencyType'");
}
}
private bool EvaluateStringArrayType(List<string> currentValue)
{
switch (CompareOperator)
{
case AutoclassCompareOperator.CONTAINS:
if (currentValue == null)
return false;
else
return currentValue.Any(s => s == Value);
case AutoclassCompareOperator.CONTAINS_INSENSITIVE:
if (currentValue == null)
return false;
else
return currentValue.Any(s => s.ToUpper() == Value.ToUpper());
default:
throw new Exception($"Invalid compare operator '{CompareOperator}' for type 'string[]'");
}
}
}
public enum AutoclassCompareOperator
{
EQUAL,
NOT_EQUAL,
GREATER_THAN,
LESS_THAN,
GREATER_THAN_OR_EQUAL,
LESS_THAN_OR_EQUAL,
CONTAINS,
CONTAINS_INSENSITIVE,
}

View File

@ -1,27 +0,0 @@
using System.Collections.Generic;
using System.Data;
using System.Text.Json.Serialization;
namespace AAIntegration.SimmonsBank.API.Entities;
public class AutoclassRule
{
public int Id { get; set; }
public string Name { get; set; }
public Account Account { get; set; }
public IEnumerable<AutoclassExpression> Expressions { get; set; }
public IEnumerable<AutoclassChange> Changes { get; set; }
public bool Enabled { get; set; }
}
public enum AutoclassType
{
STRING,
BOOLEAN,
DECIMAL,
DATETIME,
ACCOUNT,
ENVELOPE,
CURRENCYTYPE,
STRING_ARRAY,
}

View File

@ -1,12 +0,0 @@
using System.Data;
using System.Text.Json.Serialization;
namespace AAIntegration.SimmonsBank.API.Entities;
public class CurrencyType
{
public int Id { get; set; }
public string Code { get; set; } // USD
public string Symbol { get; set; } // $
public int DecimalPlaces { get; set; } // 2
}

View File

@ -1,25 +0,0 @@
using System.Collections.Generic;
using System.Data;
using System.Text.Json.Serialization;
namespace AAIntegration.SimmonsBank.API.Entities;
public class Envelope
{
public int Id { get; set; }
public string Name { get; set; }
public Account Account { get; set; }
public bool Enabled { get; set; }
public TimeSpan Period { get; set; }
public bool IsPersistant { get; set; }
public int Priority { get; set; }
public decimal Balance { get; set; }
public decimal InitialBalance { get; set; }
public DateTime? LastTriggeredOn { get; set; }
public IEnumerable<EnvelopeFundingMethod> FundingMethods { get; set; }
public string GetLogString()
{
return $"'{Name}' (id={Id})";
}
}

View File

@ -1,22 +0,0 @@
using System.Data;
using System.Text.Json.Serialization;
namespace AAIntegration.SimmonsBank.API.Entities;
public class EnvelopeFundingMethod
{
public int Id { get; set; }
public Envelope Envelope { get; set; }
public int Order { get; set; }
public EnvelopeFundingMethodModes Mode { get; set; }
public string Value { get; set; }
public int PeriodsToLookback { get; set; } = 0;
}
public enum EnvelopeFundingMethodModes
{
ABSOLUTE,
PERCENTAGE,
HISTORICAL_MEDIAN,
HISTORICAL_MEAN,
}

View File

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Text.Json.Serialization;
namespace AAIntegration.SimmonsBank.API.Entities;
public class EnvelopeHistorical
{
//public int Id { get; set; }
public Envelope Envelope { get; set; }
public int LookBack { get; set; }
public decimal? EnvelopeFunding { get; set; } = null;
public Statistic Credit { get; set; } = null;
public Statistic Debit { get; set; } = null;
}

View File

@ -1,19 +0,0 @@
using System.Data;
using System.Text.Json.Serialization;
using AAIntegration.SimmonsBank.API.Enums;
namespace AAIntegration.SimmonsBank.API.Entities;
public class Operation
{
public int Id { get; set; }
public int Order { get; set; }
public bool Enabled { get; set; }
public bool Negative { get; set; }
public OperationMode Mode { get; set; }
public TimeSpan HistoricPeriod { get; set; }
public int HistoricLookbackDepth { get; set; }
public HistoricStatistic HistoricStatistic { get; set; }
public decimal AbsoluteValue { get; set; }
public decimal Percentage { get; set; }
}

View File

@ -1,7 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Entities;
public enum Role
{
Admin,
User
}

View File

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Text.Json.Serialization;
namespace AAIntegration.SimmonsBank.API.Entities;
public class Statistic
{
//public int Id { get; set; }
public Dictionary<DateTime, decimal>? Values { get; set; } = null;
public decimal? Median { get; set; } = null;
public decimal? Mean { get; set; } = null;
public decimal? High { get; set; } = null;
public decimal? Low { get; set; } = null;
}

View File

@ -13,60 +13,6 @@ public class Transaction
public string Description { get; set; }
public Account? DebitAccount { get; set; }
public Account? CreditAccount { get; set; }
public Envelope? DebitEnvelope { get; set; }
public Envelope? CreditEnvelope { get; set; }
public bool IsEnvelopeFundingTransaction { get; set; }
public decimal Amount { get; set; }
public CurrencyType CurrencyType { get; set; }
public string Notes { get; set; }
public bool IsPending { get; set; }
public List<string>? Tags { get; set; }
}
public static class TransactionExtensions
{
public static bool HasTag(this Transaction transaction, string tag)
{
return transaction.Tags != null && transaction.Tags.Any(t => t.ToUpper() == tag.ToUpper());
}
public static Transaction AddTag(this Transaction transaction, string tag)
{
if (transaction.Tags == null)
transaction.Tags = new List<string>() { tag };
else if (transaction.Tags.Any(t => t.ToUpper() == tag.ToUpper()) == false)
transaction.Tags.Add(tag);
return transaction;
}
public static Transaction RemoveTag(this Transaction transaction, string tag)
{
if (transaction.Tags != null)
{
string? actualTag = transaction.Tags
.Where(t => t.ToUpper() == tag.ToUpper())
.FirstOrDefault();
if (actualTag != null)
transaction.Tags.Remove(actualTag);
}
return transaction;
}
}
public enum AutoclassTransactionField
{
DATE,
EXTERNAL_ID,
DESCRIPTION,
DEBIT_ACCOUNT,
CREDIT_ACCOUNT,
DEBIT_ENVELOPE,
CREDIT_ENVELOPE,
AMOUNT,
CURRENCY_TYPE,
IS_PENDING,
TAGS
}

View File

@ -5,16 +5,9 @@ namespace AAIntegration.SimmonsBank.API.Entities;
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public Role Role { get; set; }
public ICollection<Account> Accounts { get; set; }
public string ApiKey { get; set; }
public string SimmonsBankUsername { get; set; }
public string SimmonsBankPassword { get; set; }
public string MFAKey { get; set; }
[JsonIgnore]
public string PasswordHash { get; set; }
[JsonIgnore]
public string? ApiKey { get; set; }
}

View File

@ -42,9 +42,8 @@ public class ApiKeyAuthenticationHandler : AuthenticationHandler<ApiKeyAuthentic
}
_logger.BeginScope("{ClientId}", clientId);
_logger.LogInformation($"Client '{clientId}' authenticated with API Key");
var claims = new[] { new Claim(ClaimTypes.Name, clientId.ToString()) };
var claims = new[] { new Claim(ClaimTypes.NameIdentifier, apiKey.ToString()) };
var identity = new ClaimsIdentity(claims, ApiKeyAuthenticationOptions.DefaultScheme);
var identities = new List<ClaimsIdentity> { identity };
var principal = new ClaimsPrincipal(identities);

View File

@ -4,25 +4,15 @@ using AutoMapper;
using AAIntegration.SimmonsBank.API.Entities;
using AAIntegration.SimmonsBank.API.Models.Users;
using AAIntegration.SimmonsBank.API.Models.Accounts;
using AAIntegration.SimmonsBank.API.Models.Envelopes;
using AAIntegration.SimmonsBank.API.Models.CurrencyType;
using AAIntegration.SimmonsBank.API.Services;
using System.Runtime.Serialization;
using AAIntegration.SimmonsBank.API.Models.Transactions;
using AAIntegration.SimmonsBank.API.Models.Autoclass;
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
// User -> AuthenticateResponse
CreateMap<User, AuthenticateResponse>();
// RegisterRequest -> User
CreateMap<RegisterRequest, User>();
// UserUpdateRequest -> User
{ // UserUpdateRequest -> User
CreateMap<UserUpdateRequest, User>()
.ForAllMembers(x => x.Condition(
(src, dest, prop) =>
@ -30,10 +20,6 @@ public class AutoMapperProfile : Profile
// ignore both null & empty string properties
if (prop == null) return false;
if (prop.GetType() == typeof(string) && string.IsNullOrEmpty((string)prop)) return false;
// ignore null role
if (x.DestinationMember.Name == "Role" && src.Role == null) return false;
// ignore null password
if (x.DestinationMember.Name == "Password" && src.Password == null) return false;
@ -74,44 +60,11 @@ public class AutoMapperProfile : Profile
}
));
// AccountHistorical -> AccountHistoricalDTO
CreateMap<AccountHistorical, AccountHistoricalDTO>();
// EnvelopeHistorical -> EnvelopeHistoricalDTO
CreateMap<EnvelopeHistorical, EnvelopeHistoricalDTO>();
// Envelope -> EnvelopeDTO
CreateMap<Envelope, EnvelopeDTO>()
.ForAllMembers(x => x.Condition(
(src, dest, prop) =>
{
// ignore both null & empty string properties
if (prop == null) return false;
if (prop.GetType() == typeof(string) && string.IsNullOrEmpty((string)prop)) return false;
return true;
}
));
// EnvelopeFundingMethod -> EnvelopeFundingMethodDTO
CreateMap<EnvelopeFundingMethod, EnvelopeFundingMethodDTO>()
.ForAllMembers(x => x.Condition(
(src, dest, prop) =>
{
// ignore both null & empty string properties
if (prop == null) return false;
if (prop.GetType() == typeof(string) && string.IsNullOrEmpty((string)prop)) return false;
return true;
}
));
// Transaction -> TransactionDto
CreateMap<Transaction, TransactionDto>()
.ForMember(dest => dest.DebitAccountId, opt => opt.MapFrom(src => src.DebitAccount.Id))
.ForMember(dest => dest.CreditAccountId, opt => opt.MapFrom(src => src.CreditAccount.Id))
.ForMember(dest => dest.DebitEnvelopeId, opt => opt.MapFrom(src => src.DebitEnvelope.Id))
.ForMember(dest => dest.CreditEnvelopeId, opt => opt.MapFrom(src => src.CreditEnvelope.Id))
.ForAllMembers(x => x.Condition(
(src, dest, prop) =>
{
@ -123,89 +76,5 @@ public class AutoMapperProfile : Profile
}
));
// CurrencyTypeCreateRequest -> CurrencyType
CreateMap<CurrencyTypeCreateRequest, CurrencyType>()
.ForAllMembers(x => x.Condition(
(src, dest, prop) =>
{
// ignore both null & empty string properties
if (prop == null) return false;
if (prop.GetType() == typeof(string) && string.IsNullOrEmpty((string)prop)) return false;
return true;
}
));
// AutoclassExpression <-> AutoclassExpressionCreateRequest
CreateMap<AutoclassExpression, AutoclassExpressionCreateRequest>();
CreateMap<AutoclassExpressionCreateRequest, AutoclassExpression>()
.ForAllMembers(x => x.Condition(
(src, dest, prop) =>
{
// ignore both null & empty string properties
if (prop == null) return false;
if (prop.GetType() == typeof(string) && string.IsNullOrEmpty((string)prop)) return false;
return true;
}
));
CreateMap<AutoclassExpression, AutoclassExpressionDTO>();
CreateMap<AutoclassChange, AutoclassChangeDTO>();
// AutoclassChange <-> AutoclassChangeCreateRequest
CreateMap<AutoclassChange, AutoclassChangeCreateRequest>();
CreateMap<AutoclassChangeCreateRequest, AutoclassChange>()
.ForAllMembers(x => x.Condition(
(src, dest, prop) =>
{
// ignore both null & empty string properties
if (prop == null) return false;
if (prop.GetType() == typeof(string) && string.IsNullOrEmpty((string)prop)) return false;
return true;
}
));
// AutoclassRule <-> AutoclassRuleCreateRequest
CreateMap<AutoclassRule, AutoclassRuleUpdateRequest>()
//.ForMember(d => d.Account, opt => opt.MapFrom(src => src.Account.Id))
.ReverseMap();/*
CreateMap<AutoclassRuleCreateRequest, AutoclassRule>()
.ForMember(d => d.Account, opt => opt.MapFrom(src => src))
.ForAllMembers(x => x.Condition(
(src, dest, prop) =>
{
if (dest.GetType() == typeof(Account))
{
}
// ignore both null & empty string properties
if (prop == null) return false;
if (prop.GetType() == typeof(string) && string.IsNullOrEmpty((string)prop)) return false;
return true;
}
));
CreateMap<AutoclassRuleCreateRequest, Account>()
.ForMember(d => d.Id, opt => opt.MapFrom(src => src.Account))
.ForAllMembers(x => x.Condition(
(src, dest, prop) =>
{
src.UseDestinationValue();
// ignore both null & empty string properties
if (prop == null) return false;
if (prop.GetType() == typeof(string) && string.IsNullOrEmpty((string)prop)) return false;
return true;
}
));*/
// AutoclassRule -> AutoclassRuleDTO
CreateMap<AutoclassRule, AutoclassRuleDTO>()
.ForMember(dest => dest.AccountId, opt => opt.MapFrom(src => src.Account.Id));
}
}

View File

@ -30,428 +30,7 @@ public class DataContext : DbContext
options.UseInMemoryDatabase("TestDb");
}*/
public void AddAmountToAccount(int accountId, decimal amount)
{
Account account = this.Accounts.Find(accountId);
if (account != null)
{
_logger.LogInformation($"\t Adding {amount} to account '{account.Name}' (id={accountId}).");
account.Balance += amount;
this.Accounts.Update(account);
this.SaveChanges();
}
}
public void AddAmountToEnvelope(int envelopeId, decimal amount)
{
Envelope envelope = this.Envelopes
.Include(e => e.Account)
.FirstOrDefault(e => e.Id == envelopeId);
if (envelope != null)
{
_logger.LogInformation($"\t Adding {amount} to envelope '{envelope.Name}' (id={envelopeId}).");
envelope.Balance += amount;
this.Envelopes.Update(envelope);
this.SaveChanges();
if (envelope.Account != null)
this.RecalculateAccountVirtualBalance(envelope.Account.Id);
}
}
public void RecalculateAccountBalance(int id)
{
Account account = this.Accounts
.FirstOrDefault(a => a.Id == id);
decimal amount = account.InitialBalance;
// Grab relevant transactions
List<Transaction> transactions = this.Transactions
.Include(t => t.DebitAccount)
.Include(t => t.CreditAccount)
.Where(t =>
(t.DebitAccount != null && t.DebitAccount.Id == id)
|| (t.CreditAccount != null && t.CreditAccount.Id == id))
.ToList();
// Iterate and sum values
foreach (Transaction t in transactions)
{
if (t.DebitAccount?.Id == id) {
amount -= t.Amount;
} else if (t.CreditAccount?.Id == id) {
amount += t.Amount;
}
}
account.Balance = amount;
_logger.LogInformation($"Recalculating Account Balance for '{account.Name}' as '{amount}'.");
this.Accounts.Update(account);
this.SaveChanges();
}
public void RecalculateAccountVirtualBalance(Envelope env, int lookBack = 12)
{
Envelope envelope = this.Envelopes
.Include(e => e.Account)
.FirstOrDefault(e => e.Id == env.Id);
RecalculateAccountVirtualBalance(envelope.Account.Id, lookBack);
}
public void RecalculateAccountVirtualBalance(int accountId, int lookBack = 12)
{
AccountHistorical hist = this.GetAccountHistorical(accountId, lookBack);
Account account = this.Accounts.Find(accountId);
_logger.LogInformation($"Recalculating virtual balance for account '{account.Name}' (id={accountId}).");
decimal virtualBalance = account.Balance;
// Make this configurable?
// // 2nd half of CHECK BELOW IS TEMPORARY
if (hist.Income != null && hist.Income.Median.HasValue)
{
/*if (hist.Income.Median.Value == 0 && hist.Income.Mean.HasValue)
hist.Income.Median = hist.Income.Mean.Value;*/
_logger.LogInformation($"Using Median Income Value of {hist.Income.Median.Value}...");
virtualBalance = hist.Income.Median.Value;
}
// Determine Virtual Balance
List<Envelope> envelopes = this.Envelopes
.Include(e => e.Account)
.Where(e => e.Account.Id == accountId)
.ToList();
foreach (Envelope e in envelopes)
{
decimal? envelopeFunding = GetEnvelopeFunding(e.Id);
if (envelopeFunding.HasValue)
{
_logger.LogInformation($"Envelope {e.Name} had funding of {envelopeFunding.Value}.");
virtualBalance -= envelopeFunding.Value;
}
}
_logger.LogInformation($"VirtualBalance changed from {account.VirtualBalance} to {virtualBalance}.");
account.VirtualBalance = virtualBalance;
this.SaveChanges();
}
public AccountHistorical GetAccountHistorical(int id, int lookBack)
{
DateTime now = DateTime.UtcNow;
AccountHistorical hist = new AccountHistorical() {
Account = this.Accounts.Find(id),
LookBack = lookBack
};
DateTime firstOfThisMonth = new DateTime(now.Year, now.Month, 1);
DateTime lastOfLastMonth = firstOfThisMonth.AddDays(-1);
DateTime lookBackDate = firstOfThisMonth.AddMonths(-lookBack);
List<Transaction> transactions = this.Transactions
.Include(t => t.CreditAccount)
.Include(t => t.DebitAccount)
.Where(t => (t.CreditAccount != null && t.CreditAccount.Id == id) || (t.DebitAccount != null && t.DebitAccount.Id == id))
.Where(t => t.Date >= lookBackDate.ToUniversalTime() && t.Date <= lastOfLastMonth.ToUniversalTime())
.ToList();
// Sum variables
decimal sumDebit = 0;
decimal sumCredit = 0;
decimal sumIncome = 0;
// High variables
decimal highDebit = 0;
decimal highCredit = 0;
decimal highIncome = 0;
// Low variables
decimal lowDebit = 100000000;
decimal lowCredit = 100000000;
decimal lowIncome = 100000000;
// Values variables
Dictionary<DateTime, decimal> valuesDebit = new Dictionary<DateTime, decimal>();
Dictionary<DateTime, decimal> valuesCredit = new Dictionary<DateTime, decimal>();
Dictionary<DateTime, decimal> valuesIncome = new Dictionary<DateTime, decimal>();
bool monthsHaveData = false;
int monthsWithData = 0;
for (int i = 0; i < lookBack; i++)
{
DateTime currentLookBackMonth = lastOfLastMonth.AddMonths(-i);
List<Transaction> monthTransactions = this.GetTransactionsFromMonth(currentLookBackMonth, transactions);
decimal monthlySumDebit = 0;
decimal monthlySumCredit = 0;
decimal monthlySumIncome = 0;
foreach (Transaction tran in monthTransactions)
{
monthsHaveData = true;
if (tran.CreditAccount != null && tran.CreditAccount.Id == id)
{
monthlySumCredit += tran.Amount;
if (tran.Tags != null && tran.Tags.Any(t => t.ToUpper() == "INCOME"))
monthlySumIncome += tran.Amount;
}
else
monthlySumDebit += tran.Amount;
if (tran.Amount != 0)
monthsWithData = i + 1;
}
if (monthsWithData == i + 1)
{
valuesDebit.Add(currentLookBackMonth, monthlySumDebit);
valuesCredit.Add(currentLookBackMonth, monthlySumCredit);
valuesIncome.Add(currentLookBackMonth, monthlySumIncome);
}
sumDebit += monthlySumDebit;
sumCredit += monthlySumCredit;
sumIncome += monthlySumIncome;
highDebit = i == 0 || monthlySumDebit > highDebit ? monthlySumDebit : highDebit;
highCredit = i == 0 || monthlySumCredit > highCredit ? monthlySumCredit : highCredit;
highIncome = i == 0 || monthlySumIncome > highIncome ? monthlySumIncome : highIncome;
lowDebit = i == 0 || monthlySumDebit < lowDebit ? monthlySumDebit : lowDebit;
lowCredit = i == 0 || monthlySumCredit < lowCredit ? monthlySumCredit : lowCredit;
lowIncome = i == 0 || monthlySumIncome < lowIncome ? monthlySumIncome : lowIncome;
}
if (monthsHaveData == false)
return hist;
hist.Debit = new Statistic() {
Median = HistoricalMedian(valuesDebit),
Mean = sumDebit / (decimal)monthsWithData,
High = highDebit,
Low = lowDebit,
Values = valuesDebit,
};
hist.Credit = new Statistic() {
Median = HistoricalMedian(valuesCredit),
Mean = sumCredit / (decimal)monthsWithData,
High = highCredit,
Low = lowCredit,
Values = valuesCredit,
};
hist.Income = new Statistic() {
Median = HistoricalMedian(valuesIncome),
Mean = sumIncome / (decimal)monthsWithData,
High = highIncome,
Low = lowIncome,
Values = valuesIncome,
};
return hist;
}
/*private decimal? SetZeroToNull(decimal value)
{
return value == 0 ? null : (decimal?)value;
}
private decimal? SetZeroToNull(decimal? value)
{
return value.HasValue && value.Value == 0 ? null : value;
}*/
public EnvelopeHistorical GetEnvelopeHistorical(int id, int lookBack)
{
DateTime now = DateTime.UtcNow;
EnvelopeHistorical hist = new EnvelopeHistorical() {
Envelope = this.Envelopes.Find(id),
LookBack = lookBack
};
// EnvelopeFunding this month (period)
hist.EnvelopeFunding = this.GetEnvelopeFunding(id, now);
// Gather remaining statistics
DateTime firstOfThisMonth = new DateTime(now.Year, now.Month, 1);
DateTime lastOfLastMonth = firstOfThisMonth.AddDays(-1);
DateTime lookBackDate = firstOfThisMonth.AddMonths(-lookBack);
List<Transaction> transactions = this.Transactions
.Include(t => t.CreditEnvelope)
.Include(t => t.DebitEnvelope)
.Where(t => t.IsEnvelopeFundingTransaction == false)
.Where(t => (t.CreditEnvelope != null && t.CreditEnvelope.Id == id) || (t.DebitEnvelope != null && t.DebitEnvelope.Id == id))
.Where(t => t.Date >= lookBackDate.ToUniversalTime() && t.Date <= lastOfLastMonth.ToUniversalTime())
.ToList();
// Sum variables
decimal sumDebit = 0;
decimal sumCredit = 0;
// High variables
decimal highDebit = 0;
decimal highCredit = 0;
// Low variables
decimal lowDebit = 100000000;
decimal lowCredit = 100000000;
// Values variables
Dictionary<DateTime, decimal> valuesDebit = new Dictionary<DateTime, decimal>();
Dictionary<DateTime, decimal> valuesCredit = new Dictionary<DateTime, decimal>();
bool monthsHaveData = false;
int monthsWithData = 0;
for (int i = 0; i < lookBack; i++)
{
DateTime currentLookBackMonth = lastOfLastMonth.AddMonths(-i);
List<Transaction> monthTransactions = this.GetTransactionsFromMonth(currentLookBackMonth, transactions);
decimal monthlySumDebit = 0;
decimal monthlySumCredit = 0;
foreach (Transaction tran in monthTransactions)
{
monthsHaveData = true;
if (tran.CreditEnvelope != null && tran.CreditEnvelope.Id == id)
monthlySumCredit += tran.Amount;
else
monthlySumDebit += tran.Amount;
if (tran.Amount != 0)
monthsWithData = i + 1;
}
if (monthsWithData == i + 1)
{
valuesDebit.Add(currentLookBackMonth, monthlySumDebit);
valuesCredit.Add(currentLookBackMonth, monthlySumCredit);
}
sumDebit += monthlySumDebit;
sumCredit += monthlySumCredit;
highDebit = i == 0 || monthlySumDebit > highDebit ? monthlySumDebit : highDebit;
highCredit = i == 0 || monthlySumCredit > highCredit ? monthlySumCredit : highCredit;
lowDebit = i == 0 || monthlySumDebit < lowDebit ? monthlySumDebit : lowDebit;
lowCredit = i == 0 || monthlySumCredit < lowCredit ? monthlySumCredit : lowCredit;
}
if (monthsHaveData == false)
return hist;
hist.Credit = new Statistic() {
Median = HistoricalMedian(valuesCredit),
Mean = sumCredit / (decimal)monthsWithData,
High = highCredit,
Low = lowCredit,
Values = valuesCredit,
};
hist.Debit = new Statistic() {
Median = HistoricalMedian(valuesDebit),
Mean = sumDebit / (decimal)monthsWithData,
High = highDebit,
Low = lowDebit,
Values = valuesDebit,
};
return hist;
}
private List<Transaction> GetTransactionsFromMonth(DateTime? date = null, List<Transaction> transactions = null)
{
DateTime dt = date.HasValue ? date.Value : DateTime.UtcNow;
if (transactions == null)
return this.Transactions
.Where(t => t.Date.Year == dt.Year && t.Date.Month == dt.Month)
.ToList();
return transactions
.Where(t => t.Date.Year == dt.Year && t.Date.Month == dt.Month)
.ToList();
}
private decimal GetEnvelopeFunding(int id, DateTime? month = null)
{
DateTime dt = month.HasValue ? month.Value : DateTime.UtcNow;
Transaction envelopeFundTransaction = this.Transactions
.Include(t => t.CreditEnvelope)
.Where(t => t.IsEnvelopeFundingTransaction && t.CreditEnvelope != null && t.CreditEnvelope.Id == id)
.FirstOrDefault(t => t.Date.Year == dt.Year && t.Date.Month == dt.Month);
if (envelopeFundTransaction != null)
return envelopeFundTransaction.Amount;
return 0;
}
private decimal HistoricalMedian(Dictionary<DateTime, decimal> data)
{
int count = data.Count();
if (count % 2 == 0)
{
var sortedData = data.OrderBy(s => s.Value).ToArray();
return (sortedData[count / 2 - 1].Value + sortedData[count / 2].Value) / 2;
}
else
{
return data.OrderBy(s => s.Value).ElementAt(count / 2).Value;
}
}
public void RecalculateEnvelopeBalance(int id)
{
Envelope envelope = this.Envelopes.Find(id);
decimal amount = envelope.InitialBalance;
List<Transaction> transactions = this.Transactions
.Include(t => t.DebitEnvelope)
.Include(t => t.CreditEnvelope)
.Where(t =>
(t.DebitEnvelope != null && t.DebitEnvelope.Id == id)
|| (t.CreditEnvelope != null && t.CreditEnvelope.Id == id))
.ToList();
foreach (Transaction t in transactions)
{
if (t.DebitEnvelope?.Id == id) {
amount -= t.Amount;
} else if (t.CreditEnvelope?.Id == id) {
amount += t.Amount;
}
}
envelope.Balance = amount;
this.Envelopes.Update(envelope);
this.SaveChanges();
}
public DbSet<User> Users { get; set; }
public DbSet<Account> Accounts { get; set; }
public DbSet<Envelope> Envelopes { get; set; }
public DbSet<EnvelopeFundingMethod> EnvelopeFundingMethods { get; set; }
public DbSet<CurrencyType> CurrencyTypes { get; set; }
public DbSet<Operation> Operations { get; set; }
public DbSet<Transaction> Transactions { get; set; }
public DbSet<AutoclassRule> AutoclassRules { get; set; }
public DbSet<AutoclassExpression> AutoclassExpressions { get; set; }
public DbSet<AutoclassChange> AutoclassChanges { get; set; }
}

View File

@ -1,65 +0,0 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using AAIntegration.SimmonsBank.API.Config;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20231117033912_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,40 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Username = table.Column<string>(type: "text", nullable: false),
FirstName = table.Column<string>(type: "text", nullable: false),
LastName = table.Column<string>(type: "text", nullable: false),
Email = table.Column<string>(type: "text", nullable: false),
Role = table.Column<int>(type: "integer", nullable: false),
PasswordHash = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Users");
}
}
}

View File

@ -1,270 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using AAIntegration.SimmonsBank.API.Config;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20231201042238_AccountsAllocsOperations")]
partial class AccountsAllocsOperations
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CurrencyId")
.HasColumnType("integer");
b.Property<string>("ExternalAccountNumber")
.IsRequired()
.HasColumnType("text");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<DateTime>("LastActivity")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.HasIndex("OwnerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Alloc", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<decimal>("CurrentBalance")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<decimal>("LastBalanceAdded")
.HasColumnType("numeric");
b.Property<DateTime>("LastTriggeredOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<TimeSpan>("Period")
.HasColumnType("interval");
b.Property<bool>("PersistanceEnabled")
.HasColumnType("boolean");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("Allocs");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.CurrencyType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<int>("DecimalPlaces")
.HasColumnType("integer");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyTypes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("AbsoluteValue")
.HasColumnType("numeric");
b.Property<int?>("AllocId")
.HasColumnType("integer");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<int>("HistoricLookbackDepth")
.HasColumnType("integer");
b.Property<TimeSpan>("HistoricPeriod")
.HasColumnType("interval");
b.Property<int>("HistoricStatistic")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<bool>("Negative")
.HasColumnType("boolean");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<decimal>("Percentage")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("AllocId");
b.ToTable("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany("Accounts")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Alloc", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany("Allocs")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Alloc", null)
.WithMany("Operations")
.HasForeignKey("AllocId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Navigation("Allocs");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Alloc", b =>
{
b.Navigation("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Navigation("Accounts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,152 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
/// <inheritdoc />
public partial class AccountsAllocsOperations : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "CurrencyTypes",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Code = table.Column<string>(type: "text", nullable: false),
Symbol = table.Column<string>(type: "text", nullable: false),
DecimalPlaces = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_CurrencyTypes", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Accounts",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
OwnerId = table.Column<int>(type: "integer", nullable: false),
LastActivity = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
Balance = table.Column<decimal>(type: "numeric", nullable: false),
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
InitialBalance = table.Column<decimal>(type: "numeric", nullable: false),
CurrencyId = table.Column<int>(type: "integer", nullable: false),
ExternalAccountNumber = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Accounts", x => x.Id);
table.ForeignKey(
name: "FK_Accounts_CurrencyTypes_CurrencyId",
column: x => x.CurrencyId,
principalTable: "CurrencyTypes",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Accounts_Users_OwnerId",
column: x => x.OwnerId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Allocs",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
Enabled = table.Column<bool>(type: "boolean", nullable: false),
Period = table.Column<TimeSpan>(type: "interval", nullable: false),
AccountId = table.Column<int>(type: "integer", nullable: false),
PersistanceEnabled = table.Column<bool>(type: "boolean", nullable: false),
CurrentBalance = table.Column<decimal>(type: "numeric", nullable: false),
LastTriggeredOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
LastBalanceAdded = table.Column<decimal>(type: "numeric", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Allocs", x => x.Id);
table.ForeignKey(
name: "FK_Allocs_Accounts_AccountId",
column: x => x.AccountId,
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Operations",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Order = table.Column<int>(type: "integer", nullable: false),
Enabled = table.Column<bool>(type: "boolean", nullable: false),
Negative = table.Column<bool>(type: "boolean", nullable: false),
Mode = table.Column<int>(type: "integer", nullable: false),
HistoricPeriod = table.Column<TimeSpan>(type: "interval", nullable: false),
HistoricLookbackDepth = table.Column<int>(type: "integer", nullable: false),
HistoricStatistic = table.Column<int>(type: "integer", nullable: false),
AbsoluteValue = table.Column<decimal>(type: "numeric", nullable: false),
Percentage = table.Column<decimal>(type: "numeric", nullable: false),
AllocId = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Operations", x => x.Id);
table.ForeignKey(
name: "FK_Operations_Allocs_AllocId",
column: x => x.AllocId,
principalTable: "Allocs",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_Accounts_CurrencyId",
table: "Accounts",
column: "CurrencyId");
migrationBuilder.CreateIndex(
name: "IX_Accounts_OwnerId",
table: "Accounts",
column: "OwnerId");
migrationBuilder.CreateIndex(
name: "IX_Allocs_AccountId",
table: "Allocs",
column: "AccountId");
migrationBuilder.CreateIndex(
name: "IX_Operations_AllocId",
table: "Operations",
column: "AllocId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Operations");
migrationBuilder.DropTable(
name: "Allocs");
migrationBuilder.DropTable(
name: "Accounts");
migrationBuilder.DropTable(
name: "CurrencyTypes");
}
}
}

View File

@ -1,420 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using AAIntegration.SimmonsBank.API.Config;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20231219215509_AddedTransactionEntity")]
partial class AddedTransactionEntity
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CurrencyId")
.HasColumnType("integer");
b.Property<string>("ExternalAccountNumber")
.IsRequired()
.HasColumnType("text");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<DateTime>("LastActivity")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.HasIndex("OwnerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Alloc", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<decimal>("CurrentBalance")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<decimal>("LastBalanceAdded")
.HasColumnType("numeric");
b.Property<DateTime>("LastTriggeredOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<TimeSpan>("Period")
.HasColumnType("interval");
b.Property<bool>("PersistanceEnabled")
.HasColumnType("boolean");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("Allocs");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.CurrencyType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<int>("DecimalPlaces")
.HasColumnType("integer");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyTypes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.InnerTransaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CreditAccountId")
.HasColumnType("integer");
b.Property<int>("CurrencyTypeId")
.HasColumnType("integer");
b.Property<int>("DebitAccountId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("InnerTransactionId")
.HasColumnType("integer");
b.Property<bool>("IsPending")
.HasColumnType("boolean");
b.Property<string>("Notes")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("OuterTransactionId")
.HasColumnType("integer");
b.Property<DateTime>("UpdatedOn")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CreditAccountId");
b.HasIndex("CurrencyTypeId");
b.HasIndex("DebitAccountId");
b.HasIndex("InnerTransactionId");
b.HasIndex("OuterTransactionId");
b.ToTable("InnerTransactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("AbsoluteValue")
.HasColumnType("numeric");
b.Property<int?>("AllocId")
.HasColumnType("integer");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<int>("HistoricLookbackDepth")
.HasColumnType("integer");
b.Property<TimeSpan>("HistoricPeriod")
.HasColumnType("interval");
b.Property<int>("HistoricStatistic")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<bool>("Negative")
.HasColumnType("boolean");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<decimal>("Percentage")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("AllocId");
b.ToTable("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.OuterTransaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.Property<string>("SplitDescription")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("UpdatedOn")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("OuterTransactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany("Accounts")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Alloc", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany("Allocs")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.InnerTransaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
.WithMany()
.HasForeignKey("CreditAccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "CurrencyType")
.WithMany()
.HasForeignKey("CurrencyTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "DebitAccount")
.WithMany()
.HasForeignKey("DebitAccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.InnerTransaction", null)
.WithMany("Transactions")
.HasForeignKey("InnerTransactionId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.OuterTransaction", null)
.WithMany("Transactions")
.HasForeignKey("OuterTransactionId");
b.Navigation("CreditAccount");
b.Navigation("CurrencyType");
b.Navigation("DebitAccount");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Alloc", null)
.WithMany("Operations")
.HasForeignKey("AllocId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.OuterTransaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Navigation("Allocs");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Alloc", b =>
{
b.Navigation("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.InnerTransaction", b =>
{
b.Navigation("Transactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.OuterTransaction", b =>
{
b.Navigation("Transactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Navigation("Accounts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,131 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
/// <inheritdoc />
public partial class AddedTransactionEntity : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "OuterTransactions",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
OwnerId = table.Column<int>(type: "integer", nullable: false),
SplitDescription = table.Column<string>(type: "text", nullable: false),
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
UpdatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
ExternalId = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_OuterTransactions", x => x.Id);
table.ForeignKey(
name: "FK_OuterTransactions_Users_OwnerId",
column: x => x.OwnerId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "InnerTransactions",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Description = table.Column<string>(type: "text", nullable: false),
DebitAccountId = table.Column<int>(type: "integer", nullable: false),
CreditAccountId = table.Column<int>(type: "integer", nullable: false),
Amount = table.Column<decimal>(type: "numeric", nullable: false),
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
UpdatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
ExternalId = table.Column<string>(type: "text", nullable: false),
CurrencyTypeId = table.Column<int>(type: "integer", nullable: false),
Notes = table.Column<string>(type: "text", nullable: false),
IsPending = table.Column<bool>(type: "boolean", nullable: false),
InnerTransactionId = table.Column<int>(type: "integer", nullable: true),
OuterTransactionId = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_InnerTransactions", x => x.Id);
table.ForeignKey(
name: "FK_InnerTransactions_Accounts_CreditAccountId",
column: x => x.CreditAccountId,
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_InnerTransactions_Accounts_DebitAccountId",
column: x => x.DebitAccountId,
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_InnerTransactions_CurrencyTypes_CurrencyTypeId",
column: x => x.CurrencyTypeId,
principalTable: "CurrencyTypes",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_InnerTransactions_InnerTransactions_InnerTransactionId",
column: x => x.InnerTransactionId,
principalTable: "InnerTransactions",
principalColumn: "Id");
table.ForeignKey(
name: "FK_InnerTransactions_OuterTransactions_OuterTransactionId",
column: x => x.OuterTransactionId,
principalTable: "OuterTransactions",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_InnerTransactions_CreditAccountId",
table: "InnerTransactions",
column: "CreditAccountId");
migrationBuilder.CreateIndex(
name: "IX_InnerTransactions_CurrencyTypeId",
table: "InnerTransactions",
column: "CurrencyTypeId");
migrationBuilder.CreateIndex(
name: "IX_InnerTransactions_DebitAccountId",
table: "InnerTransactions",
column: "DebitAccountId");
migrationBuilder.CreateIndex(
name: "IX_InnerTransactions_InnerTransactionId",
table: "InnerTransactions",
column: "InnerTransactionId");
migrationBuilder.CreateIndex(
name: "IX_InnerTransactions_OuterTransactionId",
table: "InnerTransactions",
column: "OuterTransactionId");
migrationBuilder.CreateIndex(
name: "IX_OuterTransactions_OwnerId",
table: "OuterTransactions",
column: "OwnerId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "InnerTransactions");
migrationBuilder.DropTable(
name: "OuterTransactions");
}
}
}

View File

@ -1,399 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using AAIntegration.SimmonsBank.API.Config;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20231221130142_ModifiedTranscationEntity")]
partial class ModifiedTranscationEntity
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CurrencyId")
.HasColumnType("integer");
b.Property<string>("ExternalAccountNumber")
.IsRequired()
.HasColumnType("text");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<DateTime>("LastActivity")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.HasIndex("OwnerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Alloc", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<decimal>("CurrentBalance")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<decimal>("LastBalanceAdded")
.HasColumnType("numeric");
b.Property<DateTime>("LastTriggeredOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<TimeSpan>("Period")
.HasColumnType("interval");
b.Property<bool>("PersistanceEnabled")
.HasColumnType("boolean");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("Allocs");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.CurrencyType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<int>("DecimalPlaces")
.HasColumnType("integer");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyTypes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.InnerTransaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<int>("CreditAccountId")
.HasColumnType("integer");
b.Property<int>("CurrencyTypeId")
.HasColumnType("integer");
b.Property<int>("DebitAccountId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsPending")
.HasColumnType("boolean");
b.Property<string>("Notes")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("OuterTransactionId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CreditAccountId");
b.HasIndex("CurrencyTypeId");
b.HasIndex("DebitAccountId");
b.HasIndex("OuterTransactionId");
b.ToTable("InnerTransactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("AbsoluteValue")
.HasColumnType("numeric");
b.Property<int?>("AllocId")
.HasColumnType("integer");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<int>("HistoricLookbackDepth")
.HasColumnType("integer");
b.Property<TimeSpan>("HistoricPeriod")
.HasColumnType("interval");
b.Property<int>("HistoricStatistic")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<bool>("Negative")
.HasColumnType("boolean");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<decimal>("Percentage")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("AllocId");
b.ToTable("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.OuterTransaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.Property<string>("SplitDescription")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("UpdatedOn")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("OuterTransactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany("Accounts")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Alloc", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany("Allocs")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.InnerTransaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
.WithMany()
.HasForeignKey("CreditAccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "CurrencyType")
.WithMany()
.HasForeignKey("CurrencyTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "DebitAccount")
.WithMany()
.HasForeignKey("DebitAccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.OuterTransaction", null)
.WithMany("Transactions")
.HasForeignKey("OuterTransactionId");
b.Navigation("CreditAccount");
b.Navigation("CurrencyType");
b.Navigation("DebitAccount");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Alloc", null)
.WithMany("Operations")
.HasForeignKey("AllocId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.OuterTransaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Navigation("Allocs");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Alloc", b =>
{
b.Navigation("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.OuterTransaction", b =>
{
b.Navigation("Transactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Navigation("Accounts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,93 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
/// <inheritdoc />
public partial class ModifiedTranscationEntity : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_InnerTransactions_InnerTransactions_InnerTransactionId",
table: "InnerTransactions");
migrationBuilder.DropIndex(
name: "IX_InnerTransactions_InnerTransactionId",
table: "InnerTransactions");
migrationBuilder.DropColumn(
name: "CreatedOn",
table: "InnerTransactions");
migrationBuilder.DropColumn(
name: "ExternalId",
table: "InnerTransactions");
migrationBuilder.DropColumn(
name: "InnerTransactionId",
table: "InnerTransactions");
migrationBuilder.DropColumn(
name: "UpdatedOn",
table: "InnerTransactions");
migrationBuilder.AddColumn<DateTime>(
name: "Date",
table: "OuterTransactions",
type: "timestamp with time zone",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Date",
table: "OuterTransactions");
migrationBuilder.AddColumn<DateTime>(
name: "CreatedOn",
table: "InnerTransactions",
type: "timestamp with time zone",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
migrationBuilder.AddColumn<string>(
name: "ExternalId",
table: "InnerTransactions",
type: "text",
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<int>(
name: "InnerTransactionId",
table: "InnerTransactions",
type: "integer",
nullable: true);
migrationBuilder.AddColumn<DateTime>(
name: "UpdatedOn",
table: "InnerTransactions",
type: "timestamp with time zone",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
migrationBuilder.CreateIndex(
name: "IX_InnerTransactions_InnerTransactionId",
table: "InnerTransactions",
column: "InnerTransactionId");
migrationBuilder.AddForeignKey(
name: "FK_InnerTransactions_InnerTransactions_InnerTransactionId",
table: "InnerTransactions",
column: "InnerTransactionId",
principalTable: "InnerTransactions",
principalColumn: "Id");
}
}
}

View File

@ -1,365 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using AAIntegration.SimmonsBank.API.Config;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20231221150634_SimplifiedTransaction")]
partial class SimplifiedTransaction
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CurrencyId")
.HasColumnType("integer");
b.Property<string>("ExternalAccountNumber")
.IsRequired()
.HasColumnType("text");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<DateTime>("LastActivity")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.HasIndex("OwnerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Alloc", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<decimal>("CurrentBalance")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<decimal>("LastBalanceAdded")
.HasColumnType("numeric");
b.Property<DateTime>("LastTriggeredOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<TimeSpan>("Period")
.HasColumnType("interval");
b.Property<bool>("PersistanceEnabled")
.HasColumnType("boolean");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("Allocs");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.CurrencyType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<int>("DecimalPlaces")
.HasColumnType("integer");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyTypes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("AbsoluteValue")
.HasColumnType("numeric");
b.Property<int?>("AllocId")
.HasColumnType("integer");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<int>("HistoricLookbackDepth")
.HasColumnType("integer");
b.Property<TimeSpan>("HistoricPeriod")
.HasColumnType("interval");
b.Property<int>("HistoricStatistic")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<bool>("Negative")
.HasColumnType("boolean");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<decimal>("Percentage")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("AllocId");
b.ToTable("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CreditAccountId")
.HasColumnType("integer");
b.Property<int>("CurrencyTypeId")
.HasColumnType("integer");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<int>("DebitAccountId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsPending")
.HasColumnType("boolean");
b.Property<string>("Notes")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.Property<DateTime>("UpdatedOn")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CreditAccountId");
b.HasIndex("CurrencyTypeId");
b.HasIndex("DebitAccountId");
b.HasIndex("OwnerId");
b.ToTable("Transactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany("Accounts")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Alloc", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany("Allocs")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Alloc", null)
.WithMany("Operations")
.HasForeignKey("AllocId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
.WithMany()
.HasForeignKey("CreditAccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "CurrencyType")
.WithMany()
.HasForeignKey("CurrencyTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "DebitAccount")
.WithMany()
.HasForeignKey("DebitAccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CreditAccount");
b.Navigation("CurrencyType");
b.Navigation("DebitAccount");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Navigation("Allocs");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Alloc", b =>
{
b.Navigation("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Navigation("Accounts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,189 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
/// <inheritdoc />
public partial class SimplifiedTransaction : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "InnerTransactions");
migrationBuilder.DropTable(
name: "OuterTransactions");
migrationBuilder.CreateTable(
name: "Transactions",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
OwnerId = table.Column<int>(type: "integer", nullable: false),
Date = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
UpdatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
ExternalId = table.Column<string>(type: "text", nullable: false),
Description = table.Column<string>(type: "text", nullable: false),
DebitAccountId = table.Column<int>(type: "integer", nullable: false),
CreditAccountId = table.Column<int>(type: "integer", nullable: false),
Amount = table.Column<decimal>(type: "numeric", nullable: false),
CurrencyTypeId = table.Column<int>(type: "integer", nullable: false),
Notes = table.Column<string>(type: "text", nullable: false),
IsPending = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Transactions", x => x.Id);
table.ForeignKey(
name: "FK_Transactions_Accounts_CreditAccountId",
column: x => x.CreditAccountId,
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Transactions_Accounts_DebitAccountId",
column: x => x.DebitAccountId,
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Transactions_CurrencyTypes_CurrencyTypeId",
column: x => x.CurrencyTypeId,
principalTable: "CurrencyTypes",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Transactions_Users_OwnerId",
column: x => x.OwnerId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Transactions_CreditAccountId",
table: "Transactions",
column: "CreditAccountId");
migrationBuilder.CreateIndex(
name: "IX_Transactions_CurrencyTypeId",
table: "Transactions",
column: "CurrencyTypeId");
migrationBuilder.CreateIndex(
name: "IX_Transactions_DebitAccountId",
table: "Transactions",
column: "DebitAccountId");
migrationBuilder.CreateIndex(
name: "IX_Transactions_OwnerId",
table: "Transactions",
column: "OwnerId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Transactions");
migrationBuilder.CreateTable(
name: "OuterTransactions",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
OwnerId = table.Column<int>(type: "integer", nullable: false),
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
Date = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
ExternalId = table.Column<string>(type: "text", nullable: false),
SplitDescription = table.Column<string>(type: "text", nullable: false),
UpdatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_OuterTransactions", x => x.Id);
table.ForeignKey(
name: "FK_OuterTransactions_Users_OwnerId",
column: x => x.OwnerId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "InnerTransactions",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
CreditAccountId = table.Column<int>(type: "integer", nullable: false),
CurrencyTypeId = table.Column<int>(type: "integer", nullable: false),
DebitAccountId = table.Column<int>(type: "integer", nullable: false),
Amount = table.Column<decimal>(type: "numeric", nullable: false),
Description = table.Column<string>(type: "text", nullable: false),
IsPending = table.Column<bool>(type: "boolean", nullable: false),
Notes = table.Column<string>(type: "text", nullable: false),
OuterTransactionId = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_InnerTransactions", x => x.Id);
table.ForeignKey(
name: "FK_InnerTransactions_Accounts_CreditAccountId",
column: x => x.CreditAccountId,
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_InnerTransactions_Accounts_DebitAccountId",
column: x => x.DebitAccountId,
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_InnerTransactions_CurrencyTypes_CurrencyTypeId",
column: x => x.CurrencyTypeId,
principalTable: "CurrencyTypes",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_InnerTransactions_OuterTransactions_OuterTransactionId",
column: x => x.OuterTransactionId,
principalTable: "OuterTransactions",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_InnerTransactions_CreditAccountId",
table: "InnerTransactions",
column: "CreditAccountId");
migrationBuilder.CreateIndex(
name: "IX_InnerTransactions_CurrencyTypeId",
table: "InnerTransactions",
column: "CurrencyTypeId");
migrationBuilder.CreateIndex(
name: "IX_InnerTransactions_DebitAccountId",
table: "InnerTransactions",
column: "DebitAccountId");
migrationBuilder.CreateIndex(
name: "IX_InnerTransactions_OuterTransactionId",
table: "InnerTransactions",
column: "OuterTransactionId");
migrationBuilder.CreateIndex(
name: "IX_OuterTransactions_OwnerId",
table: "OuterTransactions",
column: "OwnerId");
}
}
}

View File

@ -1,351 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using AAIntegration.SimmonsBank.API.Config;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20231226233044_EnvelopeEntity")]
partial class EnvelopeEntity
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CurrencyId")
.HasColumnType("integer");
b.Property<string>("ExternalAccountNumber")
.IsRequired()
.HasColumnType("text");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<DateTime>("LastActivity")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.HasIndex("OwnerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.CurrencyType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<int>("DecimalPlaces")
.HasColumnType("integer");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyTypes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<bool>("IsPersistant")
.HasColumnType("boolean");
b.Property<DateTime?>("LastTriggeredOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<TimeSpan>("Period")
.HasColumnType("interval");
b.Property<int>("Priority")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("AbsoluteValue")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<int>("HistoricLookbackDepth")
.HasColumnType("integer");
b.Property<TimeSpan>("HistoricPeriod")
.HasColumnType("interval");
b.Property<int>("HistoricStatistic")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<bool>("Negative")
.HasColumnType("boolean");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<decimal>("Percentage")
.HasColumnType("numeric");
b.HasKey("Id");
b.ToTable("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CreditAccountId")
.HasColumnType("integer");
b.Property<int>("CurrencyTypeId")
.HasColumnType("integer");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<int>("DebitAccountId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsPending")
.HasColumnType("boolean");
b.Property<string>("Notes")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.Property<DateTime>("UpdatedOn")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CreditAccountId");
b.HasIndex("CurrencyTypeId");
b.HasIndex("DebitAccountId");
b.HasIndex("OwnerId");
b.ToTable("Transactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany("Accounts")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany("Envelopes")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
.WithMany()
.HasForeignKey("CreditAccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "CurrencyType")
.WithMany()
.HasForeignKey("CurrencyTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "DebitAccount")
.WithMany()
.HasForeignKey("DebitAccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CreditAccount");
b.Navigation("CurrencyType");
b.Navigation("DebitAccount");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Navigation("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Navigation("Accounts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,119 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
/// <inheritdoc />
public partial class EnvelopeEntity : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Operations_Allocs_AllocId",
table: "Operations");
migrationBuilder.DropTable(
name: "Allocs");
migrationBuilder.DropIndex(
name: "IX_Operations_AllocId",
table: "Operations");
migrationBuilder.DropColumn(
name: "AllocId",
table: "Operations");
migrationBuilder.CreateTable(
name: "Envelopes",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
AccountId = table.Column<int>(type: "integer", nullable: false),
Enabled = table.Column<bool>(type: "boolean", nullable: false),
Period = table.Column<TimeSpan>(type: "interval", nullable: false),
IsPersistant = table.Column<bool>(type: "boolean", nullable: false),
Priority = table.Column<int>(type: "integer", nullable: false),
Balance = table.Column<decimal>(type: "numeric", nullable: false),
InitialBalance = table.Column<decimal>(type: "numeric", nullable: false),
LastTriggeredOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Envelopes", x => x.Id);
table.ForeignKey(
name: "FK_Envelopes_Accounts_AccountId",
column: x => x.AccountId,
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Envelopes_AccountId",
table: "Envelopes",
column: "AccountId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Envelopes");
migrationBuilder.AddColumn<int>(
name: "AllocId",
table: "Operations",
type: "integer",
nullable: true);
migrationBuilder.CreateTable(
name: "Allocs",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
AccountId = table.Column<int>(type: "integer", nullable: false),
CurrentBalance = table.Column<decimal>(type: "numeric", nullable: false),
Enabled = table.Column<bool>(type: "boolean", nullable: false),
LastBalanceAdded = table.Column<decimal>(type: "numeric", nullable: false),
LastTriggeredOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
Name = table.Column<string>(type: "text", nullable: false),
Period = table.Column<TimeSpan>(type: "interval", nullable: false),
PersistanceEnabled = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Allocs", x => x.Id);
table.ForeignKey(
name: "FK_Allocs_Accounts_AccountId",
column: x => x.AccountId,
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Operations_AllocId",
table: "Operations",
column: "AllocId");
migrationBuilder.CreateIndex(
name: "IX_Allocs_AccountId",
table: "Allocs",
column: "AccountId");
migrationBuilder.AddForeignKey(
name: "FK_Operations_Allocs_AllocId",
table: "Operations",
column: "AllocId",
principalTable: "Allocs",
principalColumn: "Id");
}
}
}

View File

@ -1,461 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using AAIntegration.SimmonsBank.API.Config;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20231230032947_Autoclass")]
partial class Autoclass
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CurrencyId")
.HasColumnType("integer");
b.Property<string>("ExternalAccountNumber")
.IsRequired()
.HasColumnType("text");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<DateTime>("LastActivity")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.HasIndex("OwnerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("Field")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassChanges");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("CompareOperator")
.HasColumnType("integer");
b.Property<int>("TransactionField")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassExpressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("AutoclassRules");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.CurrencyType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<int>("DecimalPlaces")
.HasColumnType("integer");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyTypes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<bool>("IsPersistant")
.HasColumnType("boolean");
b.Property<DateTime?>("LastTriggeredOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<TimeSpan>("Period")
.HasColumnType("interval");
b.Property<int>("Priority")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("AbsoluteValue")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<int>("HistoricLookbackDepth")
.HasColumnType("integer");
b.Property<TimeSpan>("HistoricPeriod")
.HasColumnType("interval");
b.Property<int>("HistoricStatistic")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<bool>("Negative")
.HasColumnType("boolean");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<decimal>("Percentage")
.HasColumnType("numeric");
b.HasKey("Id");
b.ToTable("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CreditAccountId")
.HasColumnType("integer");
b.Property<int>("CurrencyTypeId")
.HasColumnType("integer");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<int>("DebitAccountId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsPending")
.HasColumnType("boolean");
b.Property<string>("Notes")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.Property<DateTime>("UpdatedOn")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CreditAccountId");
b.HasIndex("CurrencyTypeId");
b.HasIndex("DebitAccountId");
b.HasIndex("OwnerId");
b.ToTable("Transactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany("Accounts")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Changes")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Expressions")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany()
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany("Envelopes")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
.WithMany()
.HasForeignKey("CreditAccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "CurrencyType")
.WithMany()
.HasForeignKey("CurrencyTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "DebitAccount")
.WithMany()
.HasForeignKey("DebitAccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CreditAccount");
b.Navigation("CurrencyType");
b.Navigation("DebitAccount");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Navigation("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Navigation("Changes");
b.Navigation("Expressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Navigation("Accounts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,105 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
/// <inheritdoc />
public partial class Autoclass : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AutoclassRules",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
AccountId = table.Column<int>(type: "integer", nullable: false),
Enabled = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AutoclassRules", x => x.Id);
table.ForeignKey(
name: "FK_AutoclassRules_Accounts_AccountId",
column: x => x.AccountId,
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AutoclassChanges",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Field = table.Column<int>(type: "integer", nullable: false),
Value = table.Column<string>(type: "text", nullable: false),
AutoclassRuleId = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AutoclassChanges", x => x.Id);
table.ForeignKey(
name: "FK_AutoclassChanges_AutoclassRules_AutoclassRuleId",
column: x => x.AutoclassRuleId,
principalTable: "AutoclassRules",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
name: "AutoclassExpressions",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
TransactionField = table.Column<int>(type: "integer", nullable: false),
CompareOperator = table.Column<int>(type: "integer", nullable: false),
Value = table.Column<string>(type: "text", nullable: false),
AutoclassRuleId = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AutoclassExpressions", x => x.Id);
table.ForeignKey(
name: "FK_AutoclassExpressions_AutoclassRules_AutoclassRuleId",
column: x => x.AutoclassRuleId,
principalTable: "AutoclassRules",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_AutoclassChanges_AutoclassRuleId",
table: "AutoclassChanges",
column: "AutoclassRuleId");
migrationBuilder.CreateIndex(
name: "IX_AutoclassExpressions_AutoclassRuleId",
table: "AutoclassExpressions",
column: "AutoclassRuleId");
migrationBuilder.CreateIndex(
name: "IX_AutoclassRules_AccountId",
table: "AutoclassRules",
column: "AccountId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AutoclassChanges");
migrationBuilder.DropTable(
name: "AutoclassExpressions");
migrationBuilder.DropTable(
name: "AutoclassRules");
}
}
}

View File

@ -1,479 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using AAIntegration.SimmonsBank.API.Config;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20240118221018_AddedEnvelopetoTransaction")]
partial class AddedEnvelopetoTransaction
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CurrencyId")
.HasColumnType("integer");
b.Property<string>("ExternalAccountNumber")
.IsRequired()
.HasColumnType("text");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<DateTime>("LastActivity")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.HasIndex("OwnerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("Field")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassChanges");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("CompareOperator")
.HasColumnType("integer");
b.Property<int>("TransactionField")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassExpressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("AutoclassRules");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.CurrencyType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<int>("DecimalPlaces")
.HasColumnType("integer");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyTypes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<bool>("IsPersistant")
.HasColumnType("boolean");
b.Property<DateTime?>("LastTriggeredOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<TimeSpan>("Period")
.HasColumnType("interval");
b.Property<int>("Priority")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("AbsoluteValue")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<int>("HistoricLookbackDepth")
.HasColumnType("integer");
b.Property<TimeSpan>("HistoricPeriod")
.HasColumnType("interval");
b.Property<int>("HistoricStatistic")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<bool>("Negative")
.HasColumnType("boolean");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<decimal>("Percentage")
.HasColumnType("numeric");
b.HasKey("Id");
b.ToTable("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int?>("CreditAccountId")
.HasColumnType("integer");
b.Property<int?>("CreditEnvelopeId")
.HasColumnType("integer");
b.Property<int>("CurrencyTypeId")
.HasColumnType("integer");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<int?>("DebitAccountId")
.HasColumnType("integer");
b.Property<int?>("DebitEnvelopeId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsPending")
.HasColumnType("boolean");
b.Property<string>("Notes")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.Property<DateTime>("UpdatedOn")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CreditAccountId");
b.HasIndex("CreditEnvelopeId");
b.HasIndex("CurrencyTypeId");
b.HasIndex("DebitAccountId");
b.HasIndex("DebitEnvelopeId");
b.HasIndex("OwnerId");
b.ToTable("Transactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany("Accounts")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Changes")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Expressions")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany()
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany("Envelopes")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
.WithMany()
.HasForeignKey("CreditAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "CreditEnvelope")
.WithMany()
.HasForeignKey("CreditEnvelopeId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "CurrencyType")
.WithMany()
.HasForeignKey("CurrencyTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "DebitAccount")
.WithMany()
.HasForeignKey("DebitAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "DebitEnvelope")
.WithMany()
.HasForeignKey("DebitEnvelopeId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CreditAccount");
b.Navigation("CreditEnvelope");
b.Navigation("CurrencyType");
b.Navigation("DebitAccount");
b.Navigation("DebitEnvelope");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Navigation("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Navigation("Changes");
b.Navigation("Expressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Navigation("Accounts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,170 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
/// <inheritdoc />
public partial class AddedEnvelopetoTransaction : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Transactions_Accounts_CreditAccountId",
table: "Transactions");
migrationBuilder.DropForeignKey(
name: "FK_Transactions_Accounts_DebitAccountId",
table: "Transactions");
migrationBuilder.AddColumn<int>(
name: "DebitEnvelopeId",
table: "Transactions",
type: "integer",
nullable: true);
migrationBuilder.AlterColumn<int>(
name: "DebitAccountId",
table: "Transactions",
type: "integer",
nullable: true,
oldClrType: typeof(int),
oldType: "integer");
migrationBuilder.AddColumn<int>(
name: "CreditEnvelopeId",
table: "Transactions",
type: "integer",
nullable: true);
migrationBuilder.AlterColumn<int>(
name: "CreditAccountId",
table: "Transactions",
type: "integer",
nullable: true,
oldClrType: typeof(int),
oldType: "integer");
migrationBuilder.AddForeignKey(
name: "FK_Transactions_Accounts_CreditAccountId",
table: "Transactions",
column: "CreditAccountId",
principalTable: "Accounts",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Transactions_Accounts_DebitAccountId",
table: "Transactions",
column: "DebitAccountId",
principalTable: "Accounts",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Transactions_Envelopes_CreditEnvelopeId",
table: "Transactions",
column: "CreditEnvelopeId",
principalTable: "Envelopes",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Transactions_Envelopes_DebitEnvelopeId",
table: "Transactions",
column: "DebitEnvelopeId",
principalTable: "Envelopes",
principalColumn: "Id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Transactions_Accounts_CreditAccountId",
table: "Transactions");
migrationBuilder.DropForeignKey(
name: "FK_Transactions_Accounts_DebitAccountId",
table: "Transactions");
migrationBuilder.DropForeignKey(
name: "FK_Transactions_Envelopes_CreditEnvelopeId",
table: "Transactions");
migrationBuilder.DropForeignKey(
name: "FK_Transactions_Envelopes_DebitEnvelopeId",
table: "Transactions");
migrationBuilder.AlterColumn<int>(
name: "DebitEnvelopeId",
table: "Transactions",
type: "integer",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "integer",
oldNullable: true);
migrationBuilder.AlterColumn<int>(
name: "DebitAccountId",
table: "Transactions",
type: "integer",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "integer",
oldNullable: true);
migrationBuilder.AlterColumn<int>(
name: "CreditEnvelopeId",
table: "Transactions",
type: "integer",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "integer",
oldNullable: true);
migrationBuilder.AlterColumn<int>(
name: "CreditAccountId",
table: "Transactions",
type: "integer",
nullable: false,
defaultValue: 0,
oldClrType: typeof(int),
oldType: "integer",
oldNullable: true);
migrationBuilder.AddForeignKey(
name: "FK_Transactions_Accounts_CreditAccountId",
table: "Transactions",
column: "CreditAccountId",
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Transactions_Accounts_DebitAccountId",
table: "Transactions",
column: "DebitAccountId",
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Transactions_Envelopes_CreditEnvelopeId",
table: "Transactions",
column: "CreditEnvelopeId",
principalTable: "Envelopes",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Transactions_Envelopes_DebitEnvelopeId",
table: "Transactions",
column: "DebitEnvelopeId",
principalTable: "Envelopes",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
}
}

View File

@ -1,521 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using AAIntegration.SimmonsBank.API.Config;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20240122173813_EnvelopeFundingMethodEntity")]
partial class EnvelopeFundingMethodEntity
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CurrencyId")
.HasColumnType("integer");
b.Property<string>("ExternalAccountNumber")
.IsRequired()
.HasColumnType("text");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<DateTime>("LastActivity")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.HasIndex("OwnerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("Field")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassChanges");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("CompareOperator")
.HasColumnType("integer");
b.Property<int>("TransactionField")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassExpressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("AutoclassRules");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.CurrencyType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<int>("DecimalPlaces")
.HasColumnType("integer");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyTypes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<bool>("IsPersistant")
.HasColumnType("boolean");
b.Property<DateTime?>("LastTriggeredOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<TimeSpan>("Period")
.HasColumnType("interval");
b.Property<int>("Priority")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.EnvelopeFundingMethod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("EnvelopeId")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<int>("PeriodsToLookback")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("EnvelopeId");
b.ToTable("EnvelopeFundingMethods");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("AbsoluteValue")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<int>("HistoricLookbackDepth")
.HasColumnType("integer");
b.Property<TimeSpan>("HistoricPeriod")
.HasColumnType("interval");
b.Property<int>("HistoricStatistic")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<bool>("Negative")
.HasColumnType("boolean");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<decimal>("Percentage")
.HasColumnType("numeric");
b.HasKey("Id");
b.ToTable("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int?>("CreditAccountId")
.HasColumnType("integer");
b.Property<int?>("CreditEnvelopeId")
.HasColumnType("integer");
b.Property<int>("CurrencyTypeId")
.HasColumnType("integer");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<int?>("DebitAccountId")
.HasColumnType("integer");
b.Property<int?>("DebitEnvelopeId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsPending")
.HasColumnType("boolean");
b.Property<string>("Notes")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.Property<DateTime>("UpdatedOn")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CreditAccountId");
b.HasIndex("CreditEnvelopeId");
b.HasIndex("CurrencyTypeId");
b.HasIndex("DebitAccountId");
b.HasIndex("DebitEnvelopeId");
b.HasIndex("OwnerId");
b.ToTable("Transactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany("Accounts")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Changes")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Expressions")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany()
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany("Envelopes")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.EnvelopeFundingMethod", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "Envelope")
.WithMany()
.HasForeignKey("EnvelopeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Envelope");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
.WithMany()
.HasForeignKey("CreditAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "CreditEnvelope")
.WithMany()
.HasForeignKey("CreditEnvelopeId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "CurrencyType")
.WithMany()
.HasForeignKey("CurrencyTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "DebitAccount")
.WithMany()
.HasForeignKey("DebitAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "DebitEnvelope")
.WithMany()
.HasForeignKey("DebitEnvelopeId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CreditAccount");
b.Navigation("CreditEnvelope");
b.Navigation("CurrencyType");
b.Navigation("DebitAccount");
b.Navigation("DebitEnvelope");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Navigation("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Navigation("Changes");
b.Navigation("Expressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Navigation("Accounts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,50 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
/// <inheritdoc />
public partial class EnvelopeFundingMethodEntity : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "EnvelopeFundingMethods",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
EnvelopeId = table.Column<int>(type: "integer", nullable: false),
Order = table.Column<int>(type: "integer", nullable: false),
Mode = table.Column<int>(type: "integer", nullable: false),
Value = table.Column<string>(type: "text", nullable: false),
PeriodsToLookback = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_EnvelopeFundingMethods", x => x.Id);
table.ForeignKey(
name: "FK_EnvelopeFundingMethods_Envelopes_EnvelopeId",
column: x => x.EnvelopeId,
principalTable: "Envelopes",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_EnvelopeFundingMethods_EnvelopeId",
table: "EnvelopeFundingMethods",
column: "EnvelopeId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "EnvelopeFundingMethods");
}
}
}

View File

@ -1,532 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using AAIntegration.SimmonsBank.API.Config;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20240123162419_IsEnvelopeFundingTransaction")]
partial class IsEnvelopeFundingTransaction
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CurrencyId")
.HasColumnType("integer");
b.Property<string>("ExternalAccountNumber")
.IsRequired()
.HasColumnType("text");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<DateTime>("LastActivity")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.Property<decimal>("VirtualBalance")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.HasIndex("OwnerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("Field")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassChanges");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("CompareOperator")
.HasColumnType("integer");
b.Property<int>("TransactionField")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassExpressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("AutoclassRules");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.CurrencyType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<int>("DecimalPlaces")
.HasColumnType("integer");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyTypes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<bool>("IsPersistant")
.HasColumnType("boolean");
b.Property<DateTime?>("LastTriggeredOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<TimeSpan>("Period")
.HasColumnType("interval");
b.Property<int>("Priority")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.EnvelopeFundingMethod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("EnvelopeId")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<int>("PeriodsToLookback")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("EnvelopeId");
b.ToTable("EnvelopeFundingMethods");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("AbsoluteValue")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<int>("HistoricLookbackDepth")
.HasColumnType("integer");
b.Property<TimeSpan>("HistoricPeriod")
.HasColumnType("interval");
b.Property<int>("HistoricStatistic")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<bool>("Negative")
.HasColumnType("boolean");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<decimal>("Percentage")
.HasColumnType("numeric");
b.HasKey("Id");
b.ToTable("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int?>("CreditAccountId")
.HasColumnType("integer");
b.Property<int?>("CreditEnvelopeId")
.HasColumnType("integer");
b.Property<int>("CurrencyTypeId")
.HasColumnType("integer");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<int?>("DebitAccountId")
.HasColumnType("integer");
b.Property<int?>("DebitEnvelopeId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsEnvelopeFundingTransaction")
.HasColumnType("boolean");
b.Property<bool>("IsPending")
.HasColumnType("boolean");
b.Property<string>("Notes")
.IsRequired()
.HasColumnType("text");
b.Property<int>("OwnerId")
.HasColumnType("integer");
b.Property<DateTime>("UpdatedOn")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CreditAccountId");
b.HasIndex("CreditEnvelopeId");
b.HasIndex("CurrencyTypeId");
b.HasIndex("DebitAccountId");
b.HasIndex("DebitEnvelopeId");
b.HasIndex("OwnerId");
b.ToTable("Transactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany("Accounts")
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Changes")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Expressions")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany()
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany("Envelopes")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.EnvelopeFundingMethod", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "Envelope")
.WithMany("FundingMethods")
.HasForeignKey("EnvelopeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Envelope");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
.WithMany()
.HasForeignKey("CreditAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "CreditEnvelope")
.WithMany()
.HasForeignKey("CreditEnvelopeId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "CurrencyType")
.WithMany()
.HasForeignKey("CurrencyTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "DebitAccount")
.WithMany()
.HasForeignKey("DebitAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "DebitEnvelope")
.WithMany()
.HasForeignKey("DebitEnvelopeId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CreditAccount");
b.Navigation("CreditEnvelope");
b.Navigation("CurrencyType");
b.Navigation("DebitAccount");
b.Navigation("DebitEnvelope");
b.Navigation("Owner");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Navigation("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Navigation("Changes");
b.Navigation("Expressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.Navigation("FundingMethods");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Navigation("Accounts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,40 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
/// <inheritdoc />
public partial class IsEnvelopeFundingTransaction : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsEnvelopeFundingTransaction",
table: "Transactions",
type: "boolean",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<decimal>(
name: "VirtualBalance",
table: "Accounts",
type: "numeric",
nullable: false,
defaultValue: 0m);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsEnvelopeFundingTransaction",
table: "Transactions");
migrationBuilder.DropColumn(
name: "VirtualBalance",
table: "Accounts");
}
}
}

View File

@ -1,515 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using AAIntegration.SimmonsBank.API.Config;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20240123181903_removedOwner")]
partial class removedOwner
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CurrencyId")
.HasColumnType("integer");
b.Property<string>("ExternalAccountNumber")
.IsRequired()
.HasColumnType("text");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<DateTime>("LastActivity")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("UserId")
.HasColumnType("integer");
b.Property<decimal>("VirtualBalance")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.HasIndex("UserId");
b.ToTable("Accounts");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("Field")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassChanges");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("CompareOperator")
.HasColumnType("integer");
b.Property<int>("TransactionField")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassExpressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("AutoclassRules");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.CurrencyType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<int>("DecimalPlaces")
.HasColumnType("integer");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyTypes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<bool>("IsPersistant")
.HasColumnType("boolean");
b.Property<DateTime?>("LastTriggeredOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<TimeSpan>("Period")
.HasColumnType("interval");
b.Property<int>("Priority")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.EnvelopeFundingMethod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("EnvelopeId")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<int>("PeriodsToLookback")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("EnvelopeId");
b.ToTable("EnvelopeFundingMethods");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("AbsoluteValue")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<int>("HistoricLookbackDepth")
.HasColumnType("integer");
b.Property<TimeSpan>("HistoricPeriod")
.HasColumnType("interval");
b.Property<int>("HistoricStatistic")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<bool>("Negative")
.HasColumnType("boolean");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<decimal>("Percentage")
.HasColumnType("numeric");
b.HasKey("Id");
b.ToTable("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int?>("CreditAccountId")
.HasColumnType("integer");
b.Property<int?>("CreditEnvelopeId")
.HasColumnType("integer");
b.Property<int>("CurrencyTypeId")
.HasColumnType("integer");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<int?>("DebitAccountId")
.HasColumnType("integer");
b.Property<int?>("DebitEnvelopeId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsEnvelopeFundingTransaction")
.HasColumnType("boolean");
b.Property<bool>("IsPending")
.HasColumnType("boolean");
b.Property<string>("Notes")
.IsRequired()
.HasColumnType("text");
b.Property<DateTime>("UpdatedOn")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CreditAccountId");
b.HasIndex("CreditEnvelopeId");
b.HasIndex("CurrencyTypeId");
b.HasIndex("DebitAccountId");
b.HasIndex("DebitEnvelopeId");
b.ToTable("Transactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", null)
.WithMany("Accounts")
.HasForeignKey("UserId");
b.Navigation("Currency");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Changes")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Expressions")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany()
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany("Envelopes")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.EnvelopeFundingMethod", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "Envelope")
.WithMany("FundingMethods")
.HasForeignKey("EnvelopeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Envelope");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
.WithMany()
.HasForeignKey("CreditAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "CreditEnvelope")
.WithMany()
.HasForeignKey("CreditEnvelopeId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "CurrencyType")
.WithMany()
.HasForeignKey("CurrencyTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "DebitAccount")
.WithMany()
.HasForeignKey("DebitAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "DebitEnvelope")
.WithMany()
.HasForeignKey("DebitEnvelopeId");
b.Navigation("CreditAccount");
b.Navigation("CreditEnvelope");
b.Navigation("CurrencyType");
b.Navigation("DebitAccount");
b.Navigation("DebitEnvelope");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Navigation("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Navigation("Changes");
b.Navigation("Expressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.Navigation("FundingMethods");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Navigation("Accounts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,112 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
/// <inheritdoc />
public partial class removedOwner : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Accounts_Users_OwnerId",
table: "Accounts");
migrationBuilder.DropForeignKey(
name: "FK_Transactions_Users_OwnerId",
table: "Transactions");
migrationBuilder.DropIndex(
name: "IX_Transactions_OwnerId",
table: "Transactions");
migrationBuilder.DropIndex(
name: "IX_Accounts_OwnerId",
table: "Accounts");
migrationBuilder.DropColumn(
name: "OwnerId",
table: "Transactions");
migrationBuilder.DropColumn(
name: "OwnerId",
table: "Accounts");
migrationBuilder.AddColumn<int>(
name: "UserId",
table: "Accounts",
type: "integer",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Accounts_UserId",
table: "Accounts",
column: "UserId");
migrationBuilder.AddForeignKey(
name: "FK_Accounts_Users_UserId",
table: "Accounts",
column: "UserId",
principalTable: "Users",
principalColumn: "Id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Accounts_Users_UserId",
table: "Accounts");
migrationBuilder.DropIndex(
name: "IX_Accounts_UserId",
table: "Accounts");
migrationBuilder.DropColumn(
name: "UserId",
table: "Accounts");
migrationBuilder.AddColumn<int>(
name: "OwnerId",
table: "Transactions",
type: "integer",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "OwnerId",
table: "Accounts",
type: "integer",
nullable: false,
defaultValue: 0);
migrationBuilder.CreateIndex(
name: "IX_Transactions_OwnerId",
table: "Transactions",
column: "OwnerId");
migrationBuilder.CreateIndex(
name: "IX_Accounts_OwnerId",
table: "Accounts",
column: "OwnerId");
migrationBuilder.AddForeignKey(
name: "FK_Accounts_Users_OwnerId",
table: "Accounts",
column: "OwnerId",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_Transactions_Users_OwnerId",
table: "Transactions",
column: "OwnerId",
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
}
}

View File

@ -1,520 +0,0 @@
// <auto-generated />
using System;
using System.Collections.Generic;
using AAIntegration.SimmonsBank.API.Config;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20240201041006_TransactionTags")]
partial class TransactionTags
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CurrencyId")
.HasColumnType("integer");
b.Property<string>("ExternalAccountNumber")
.IsRequired()
.HasColumnType("text");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<DateTime>("LastActivity")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("UserId")
.HasColumnType("integer");
b.Property<decimal>("VirtualBalance")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.HasIndex("UserId");
b.ToTable("Accounts");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("Field")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassChanges");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("CompareOperator")
.HasColumnType("integer");
b.Property<int>("TransactionField")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassExpressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("AutoclassRules");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.CurrencyType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<int>("DecimalPlaces")
.HasColumnType("integer");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyTypes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<bool>("IsPersistant")
.HasColumnType("boolean");
b.Property<DateTime?>("LastTriggeredOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<TimeSpan>("Period")
.HasColumnType("interval");
b.Property<int>("Priority")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.EnvelopeFundingMethod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("EnvelopeId")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<int>("PeriodsToLookback")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("EnvelopeId");
b.ToTable("EnvelopeFundingMethods");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("AbsoluteValue")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<int>("HistoricLookbackDepth")
.HasColumnType("integer");
b.Property<TimeSpan>("HistoricPeriod")
.HasColumnType("interval");
b.Property<int>("HistoricStatistic")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<bool>("Negative")
.HasColumnType("boolean");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<decimal>("Percentage")
.HasColumnType("numeric");
b.HasKey("Id");
b.ToTable("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int?>("CreditAccountId")
.HasColumnType("integer");
b.Property<int?>("CreditEnvelopeId")
.HasColumnType("integer");
b.Property<int>("CurrencyTypeId")
.HasColumnType("integer");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<int?>("DebitAccountId")
.HasColumnType("integer");
b.Property<int?>("DebitEnvelopeId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsEnvelopeFundingTransaction")
.HasColumnType("boolean");
b.Property<bool>("IsPending")
.HasColumnType("boolean");
b.Property<string>("Notes")
.IsRequired()
.HasColumnType("text");
b.Property<List<string>>("Tags")
.IsRequired()
.HasColumnType("text[]");
b.Property<DateTime>("UpdatedOn")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CreditAccountId");
b.HasIndex("CreditEnvelopeId");
b.HasIndex("CurrencyTypeId");
b.HasIndex("DebitAccountId");
b.HasIndex("DebitEnvelopeId");
b.ToTable("Transactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", null)
.WithMany("Accounts")
.HasForeignKey("UserId");
b.Navigation("Currency");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Changes")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Expressions")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany()
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany("Envelopes")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.EnvelopeFundingMethod", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "Envelope")
.WithMany("FundingMethods")
.HasForeignKey("EnvelopeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Envelope");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
.WithMany()
.HasForeignKey("CreditAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "CreditEnvelope")
.WithMany()
.HasForeignKey("CreditEnvelopeId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "CurrencyType")
.WithMany()
.HasForeignKey("CurrencyTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "DebitAccount")
.WithMany()
.HasForeignKey("DebitAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "DebitEnvelope")
.WithMany()
.HasForeignKey("DebitEnvelopeId");
b.Navigation("CreditAccount");
b.Navigation("CreditEnvelope");
b.Navigation("CurrencyType");
b.Navigation("DebitAccount");
b.Navigation("DebitEnvelope");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Navigation("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Navigation("Changes");
b.Navigation("Expressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.Navigation("FundingMethods");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Navigation("Accounts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,29 +0,0 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
/// <inheritdoc />
public partial class TransactionTags : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<List<string>>(
name: "Tags",
table: "Transactions",
type: "text[]",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Tags",
table: "Transactions");
}
}
}

View File

@ -1,522 +0,0 @@
// <auto-generated />
using System;
using System.Collections.Generic;
using AAIntegration.SimmonsBank.API.Config;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20240224133139_UserApiKey")]
partial class UserApiKey
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CurrencyId")
.HasColumnType("integer");
b.Property<string>("ExternalAccountNumber")
.IsRequired()
.HasColumnType("text");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<DateTime>("LastActivity")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("UserId")
.HasColumnType("integer");
b.Property<decimal>("VirtualBalance")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.HasIndex("UserId");
b.ToTable("Accounts");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("Field")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassChanges");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("CompareOperator")
.HasColumnType("integer");
b.Property<int>("TransactionField")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassExpressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("AutoclassRules");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.CurrencyType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<int>("DecimalPlaces")
.HasColumnType("integer");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyTypes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<bool>("IsPersistant")
.HasColumnType("boolean");
b.Property<DateTime?>("LastTriggeredOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<TimeSpan>("Period")
.HasColumnType("interval");
b.Property<int>("Priority")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.EnvelopeFundingMethod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("EnvelopeId")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<int>("PeriodsToLookback")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("EnvelopeId");
b.ToTable("EnvelopeFundingMethods");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("AbsoluteValue")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<int>("HistoricLookbackDepth")
.HasColumnType("integer");
b.Property<TimeSpan>("HistoricPeriod")
.HasColumnType("interval");
b.Property<int>("HistoricStatistic")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<bool>("Negative")
.HasColumnType("boolean");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<decimal>("Percentage")
.HasColumnType("numeric");
b.HasKey("Id");
b.ToTable("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int?>("CreditAccountId")
.HasColumnType("integer");
b.Property<int?>("CreditEnvelopeId")
.HasColumnType("integer");
b.Property<int>("CurrencyTypeId")
.HasColumnType("integer");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<int?>("DebitAccountId")
.HasColumnType("integer");
b.Property<int?>("DebitEnvelopeId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsEnvelopeFundingTransaction")
.HasColumnType("boolean");
b.Property<bool>("IsPending")
.HasColumnType("boolean");
b.Property<string>("Notes")
.IsRequired()
.HasColumnType("text");
b.Property<List<string>>("Tags")
.HasColumnType("text[]");
b.Property<DateTime>("UpdatedOn")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CreditAccountId");
b.HasIndex("CreditEnvelopeId");
b.HasIndex("CurrencyTypeId");
b.HasIndex("DebitAccountId");
b.HasIndex("DebitEnvelopeId");
b.ToTable("Transactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ApiKey")
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("FirstName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("LastName")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", null)
.WithMany("Accounts")
.HasForeignKey("UserId");
b.Navigation("Currency");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Changes")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Expressions")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany()
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany("Envelopes")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.EnvelopeFundingMethod", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "Envelope")
.WithMany("FundingMethods")
.HasForeignKey("EnvelopeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Envelope");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
.WithMany()
.HasForeignKey("CreditAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "CreditEnvelope")
.WithMany()
.HasForeignKey("CreditEnvelopeId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "CurrencyType")
.WithMany()
.HasForeignKey("CurrencyTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "DebitAccount")
.WithMany()
.HasForeignKey("DebitAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "DebitEnvelope")
.WithMany()
.HasForeignKey("DebitEnvelopeId");
b.Navigation("CreditAccount");
b.Navigation("CreditEnvelope");
b.Navigation("CurrencyType");
b.Navigation("DebitAccount");
b.Navigation("DebitEnvelope");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Navigation("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Navigation("Changes");
b.Navigation("Expressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.Navigation("FundingMethods");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Navigation("Accounts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,46 +0,0 @@
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
/// <inheritdoc />
public partial class UserApiKey : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "ApiKey",
table: "Users",
type: "text",
nullable: true);
migrationBuilder.AlterColumn<List<string>>(
name: "Tags",
table: "Transactions",
type: "text[]",
nullable: true,
oldClrType: typeof(List<string>),
oldType: "text[]");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ApiKey",
table: "Users");
migrationBuilder.AlterColumn<List<string>>(
name: "Tags",
table: "Transactions",
type: "text[]",
nullable: false,
oldClrType: typeof(List<string>),
oldType: "text[]",
oldNullable: true);
}
}
}

View File

@ -0,0 +1,144 @@
// <auto-generated />
using System;
using AAIntegration.SimmonsBank.API.Config;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
[DbContext(typeof(DataContext))]
[Migration("20240320021418_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<string>("ExternalAccountNumber")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Accounts");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("Amount")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int?>("CreditAccountId")
.HasColumnType("integer");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<int?>("DebitAccountId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsPending")
.HasColumnType("boolean");
b.Property<DateTime>("UpdatedOn")
.HasColumnType("timestamp with time zone");
b.HasKey("Id");
b.HasIndex("CreditAccountId");
b.HasIndex("DebitAccountId");
b.ToTable("Transactions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ApiKey")
.IsRequired()
.HasColumnType("text");
b.Property<string>("MFAKey")
.IsRequired()
.HasColumnType("text");
b.Property<string>("SimmonsBankPassword")
.IsRequired()
.HasColumnType("text");
b.Property<string>("SimmonsBankUsername")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
.WithMany()
.HasForeignKey("CreditAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "DebitAccount")
.WithMany()
.HasForeignKey("DebitAccountId");
b.Navigation("CreditAccount");
b.Navigation("DebitAccount");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,101 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace AAIntegration.SimmonsBank.API.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Accounts",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
Balance = table.Column<decimal>(type: "numeric", nullable: false),
ExternalAccountNumber = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Accounts", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
ApiKey = table.Column<string>(type: "text", nullable: false),
SimmonsBankUsername = table.Column<string>(type: "text", nullable: false),
SimmonsBankPassword = table.Column<string>(type: "text", nullable: false),
MFAKey = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Transactions",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Date = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
UpdatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
ExternalId = table.Column<string>(type: "text", nullable: false),
Description = table.Column<string>(type: "text", nullable: false),
DebitAccountId = table.Column<int>(type: "integer", nullable: true),
CreditAccountId = table.Column<int>(type: "integer", nullable: true),
Amount = table.Column<decimal>(type: "numeric", nullable: false),
IsPending = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Transactions", x => x.Id);
table.ForeignKey(
name: "FK_Transactions_Accounts_CreditAccountId",
column: x => x.CreditAccountId,
principalTable: "Accounts",
principalColumn: "Id");
table.ForeignKey(
name: "FK_Transactions_Accounts_DebitAccountId",
column: x => x.DebitAccountId,
principalTable: "Accounts",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_Transactions_CreditAccountId",
table: "Transactions",
column: "CreditAccountId");
migrationBuilder.CreateIndex(
name: "IX_Transactions_DebitAccountId",
table: "Transactions",
column: "DebitAccountId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Transactions");
migrationBuilder.DropTable(
name: "Users");
migrationBuilder.DropTable(
name: "Accounts");
}
}
}

View File

@ -1,6 +1,5 @@
// <auto-generated />
using System;
using System.Collections.Generic;
using AAIntegration.SimmonsBank.API.Config;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
@ -34,257 +33,19 @@ namespace AAIntegration.SimmonsBank.API.Migrations
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<int>("CurrencyId")
.HasColumnType("integer");
b.Property<string>("ExternalAccountNumber")
.IsRequired()
.HasColumnType("text");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<DateTime>("LastActivity")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("UserId")
.HasColumnType("integer");
b.Property<decimal>("VirtualBalance")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.HasIndex("UserId");
b.ToTable("Accounts");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("Field")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassChanges");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("AutoclassRuleId")
.HasColumnType("integer");
b.Property<int>("CompareOperator")
.HasColumnType("integer");
b.Property<int>("TransactionField")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AutoclassRuleId");
b.ToTable("AutoclassExpressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("AutoclassRules");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.CurrencyType", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Code")
.IsRequired()
.HasColumnType("text");
b.Property<int>("DecimalPlaces")
.HasColumnType("integer");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyTypes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer");
b.Property<decimal>("Balance")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<decimal>("InitialBalance")
.HasColumnType("numeric");
b.Property<bool>("IsPersistant")
.HasColumnType("boolean");
b.Property<DateTime?>("LastTriggeredOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<TimeSpan>("Period")
.HasColumnType("interval");
b.Property<int>("Priority")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("AccountId");
b.ToTable("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.EnvelopeFundingMethod", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("EnvelopeId")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<int>("PeriodsToLookback")
.HasColumnType("integer");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("EnvelopeId");
b.ToTable("EnvelopeFundingMethods");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Operation", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<decimal>("AbsoluteValue")
.HasColumnType("numeric");
b.Property<bool>("Enabled")
.HasColumnType("boolean");
b.Property<int>("HistoricLookbackDepth")
.HasColumnType("integer");
b.Property<TimeSpan>("HistoricPeriod")
.HasColumnType("interval");
b.Property<int>("HistoricStatistic")
.HasColumnType("integer");
b.Property<int>("Mode")
.HasColumnType("integer");
b.Property<bool>("Negative")
.HasColumnType("boolean");
b.Property<int>("Order")
.HasColumnType("integer");
b.Property<decimal>("Percentage")
.HasColumnType("numeric");
b.HasKey("Id");
b.ToTable("Operations");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.Property<int>("Id")
@ -302,21 +63,12 @@ namespace AAIntegration.SimmonsBank.API.Migrations
b.Property<int?>("CreditAccountId")
.HasColumnType("integer");
b.Property<int?>("CreditEnvelopeId")
.HasColumnType("integer");
b.Property<int>("CurrencyTypeId")
.HasColumnType("integer");
b.Property<DateTime>("Date")
.HasColumnType("timestamp with time zone");
b.Property<int?>("DebitAccountId")
.HasColumnType("integer");
b.Property<int?>("DebitEnvelopeId")
.HasColumnType("integer");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text");
@ -325,19 +77,9 @@ namespace AAIntegration.SimmonsBank.API.Migrations
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsEnvelopeFundingTransaction")
.HasColumnType("boolean");
b.Property<bool>("IsPending")
.HasColumnType("boolean");
b.Property<string>("Notes")
.IsRequired()
.HasColumnType("text");
b.Property<List<string>>("Tags")
.HasColumnType("text[]");
b.Property<DateTime>("UpdatedOn")
.HasColumnType("timestamp with time zone");
@ -345,14 +87,8 @@ namespace AAIntegration.SimmonsBank.API.Migrations
b.HasIndex("CreditAccountId");
b.HasIndex("CreditEnvelopeId");
b.HasIndex("CurrencyTypeId");
b.HasIndex("DebitAccountId");
b.HasIndex("DebitEnvelopeId");
b.ToTable("Transactions");
});
@ -365,28 +101,18 @@ namespace AAIntegration.SimmonsBank.API.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ApiKey")
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("FirstName")
b.Property<string>("MFAKey")
.IsRequired()
.HasColumnType("text");
b.Property<string>("LastName")
b.Property<string>("SimmonsBankPassword")
.IsRequired()
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Role")
.HasColumnType("integer");
b.Property<string>("Username")
b.Property<string>("SimmonsBankUsername")
.IsRequired()
.HasColumnType("text");
@ -395,123 +121,19 @@ namespace AAIntegration.SimmonsBank.API.Migrations
b.ToTable("Users");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.User", null)
.WithMany("Accounts")
.HasForeignKey("UserId");
b.Navigation("Currency");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassChange", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Changes")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassExpression", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", null)
.WithMany("Expressions")
.HasForeignKey("AutoclassRuleId");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany()
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "Account")
.WithMany("Envelopes")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.EnvelopeFundingMethod", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "Envelope")
.WithMany("FundingMethods")
.HasForeignKey("EnvelopeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Envelope");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Transaction", b =>
{
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "CreditAccount")
.WithMany()
.HasForeignKey("CreditAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "CreditEnvelope")
.WithMany()
.HasForeignKey("CreditEnvelopeId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.CurrencyType", "CurrencyType")
.WithMany()
.HasForeignKey("CurrencyTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Account", "DebitAccount")
.WithMany()
.HasForeignKey("DebitAccountId");
b.HasOne("AAIntegration.SimmonsBank.API.Entities.Envelope", "DebitEnvelope")
.WithMany()
.HasForeignKey("DebitEnvelopeId");
b.Navigation("CreditAccount");
b.Navigation("CreditEnvelope");
b.Navigation("CurrencyType");
b.Navigation("DebitAccount");
b.Navigation("DebitEnvelope");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Account", b =>
{
b.Navigation("Envelopes");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.AutoclassRule", b =>
{
b.Navigation("Changes");
b.Navigation("Expressions");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.Envelope", b =>
{
b.Navigation("FundingMethods");
});
modelBuilder.Entity("AAIntegration.SimmonsBank.API.Entities.User", b =>
{
b.Navigation("Accounts");
});
#pragma warning restore 612, 618
}

View File

@ -9,12 +9,6 @@ public class AccountDTO
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime LastActivity { get; set; }
public decimal VirtualBalance { get; set; }
public decimal Balance { get; set; }
public DateTime CreatedOn { get; set; }
public decimal InitialBalance { get; set; }
public int CurrencyId { get; set; }
public string ExternalAccountNumber { get; set; }
public List<Envelope> Envelopes { get; set; }
}

View File

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using AAIntegration.SimmonsBank.API.Entities;
namespace AAIntegration.SimmonsBank.API.Models.Accounts;
public class AccountHistoricalDTO
{
//public int Id { get; set; }
public int AccountId { get; set; }
public int LookBack { get; set; }
public Statistic? Credit { get; set; } = null;
public Statistic? Debit { get; set; } = null;
public Statistic? Income { get; set; } = null;
}

View File

@ -1,13 +1,8 @@
namespace AAIntegration.SimmonsBank.API.Models.Accounts;
using System.ComponentModel.DataAnnotations;
using AAIntegration.SimmonsBank.API.Entities;
public class AccountUpdateRequest
{
public string Name { get; set; } = null;
public int? Owner { get; set; } = null;
public string InitialBalance { get; set; } = null;
public int? Currency { get; set; } = null;
public string ExternalAccountNumber { get; set; } = null;
public string? Name { get; set; } = null;
public string? Balance { get; set; } = null;
public string? ExternalAccountNumber { get; set; } = null;
}

View File

@ -1,29 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using AAIntegration.SimmonsBank.API.Entities;
namespace AAIntegration.SimmonsBank.API.Models.Autoclass;
public class AutoclassRuleDTO
{
public int Id { get; set; }
public string Name { get; set; }
public int AccountId { get; set; }
public IEnumerable<AutoclassExpressionDTO> Expressions { get; set; }
public IEnumerable<AutoclassChangeDTO> Changes { get; set; }
public bool Enabled { get; set; }
}
public class AutoclassExpressionDTO
{
public AutoclassTransactionField TransactionField { get; set; }
public AutoclassCompareOperator CompareOperator { get; set; }
public string Value { get; set; }
}
public class AutoclassChangeDTO
{
public AutoclassTransactionField Field { get; set; }
public string Value { get; set; }
}

View File

@ -1,155 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using AAIntegration.SimmonsBank.API.Entities;
namespace AAIntegration.SimmonsBank.API.Models.Autoclass;
public class AutoclassFieldMetaDTO
{
public AutoclassFieldMetaDTO(AutoclassTransactionField name)
{
Name = name;
}
public AutoclassTransactionField Name { get; set; }
public string Type {
get
{
switch (this.Name)
{
case AutoclassTransactionField.AMOUNT:
return "DECIMAL";
case AutoclassTransactionField.DATE:
return "DATETIME";
case AutoclassTransactionField.DESCRIPTION:
case AutoclassTransactionField.EXTERNAL_ID:
return "STRING";
case AutoclassTransactionField.IS_PENDING:
return "BOOLEAN";
case AutoclassTransactionField.CURRENCY_TYPE:
return "CURRENCYTYPE";
case AutoclassTransactionField.CREDIT_ACCOUNT:
case AutoclassTransactionField.DEBIT_ACCOUNT:
return "ACCOUNT";
case AutoclassTransactionField.CREDIT_ENVELOPE:
case AutoclassTransactionField.DEBIT_ENVELOPE:
return "ENVELOPE";
case AutoclassTransactionField.TAGS:
return "STRING_ARRAY";
default:
return "ERROR";
}
}
}
}
public class AutoclassTypeMetaDTO
{
public AutoclassType Type { get; set; }
public List<AutoclassOperatorMetaDTO> Operators { get; set; }
public AutoclassTypeMetaDTO(AutoclassType type)
{
Type = type;
switch(type)
{
case AutoclassType.DATETIME:
Operators = new List<AutoclassOperatorMetaDTO>() {
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.EQUAL),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.NOT_EQUAL),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.GREATER_THAN),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.GREATER_THAN_OR_EQUAL),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.LESS_THAN),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.LESS_THAN_OR_EQUAL),
};
break;
case AutoclassType.STRING:
Operators = new List<AutoclassOperatorMetaDTO>() {
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.EQUAL),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.NOT_EQUAL),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.CONTAINS),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.CONTAINS_INSENSITIVE),
};
break;
case AutoclassType.DECIMAL:
Operators = new List<AutoclassOperatorMetaDTO>() {
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.EQUAL),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.NOT_EQUAL),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.GREATER_THAN),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.GREATER_THAN_OR_EQUAL),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.LESS_THAN),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.LESS_THAN_OR_EQUAL),
};
break;
case AutoclassType.BOOLEAN:
Operators = new List<AutoclassOperatorMetaDTO>() {
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.EQUAL),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.NOT_EQUAL),
};
break;
case AutoclassType.ACCOUNT:
Operators = new List<AutoclassOperatorMetaDTO>() {
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.EQUAL),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.NOT_EQUAL),
};
break;
case AutoclassType.ENVELOPE:
Operators = new List<AutoclassOperatorMetaDTO>() {
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.EQUAL),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.NOT_EQUAL),
};
break;
case AutoclassType.CURRENCYTYPE:
Operators = new List<AutoclassOperatorMetaDTO>() {
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.EQUAL),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.NOT_EQUAL),
};
break;
case AutoclassType.STRING_ARRAY:
Operators = new List<AutoclassOperatorMetaDTO>() {
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.CONTAINS),
new AutoclassOperatorMetaDTO(AutoclassCompareOperator.CONTAINS_INSENSITIVE),
};
break;
}
}
}
public class AutoclassOperatorMetaDTO
{
public AutoclassOperatorMetaDTO(AutoclassCompareOperator op)
{
Operator = op;
}
public AutoclassCompareOperator Operator { get; set; }
public string DisplayName {
get
{
switch (this.Operator)
{
case AutoclassCompareOperator.EQUAL:
return "=";
case AutoclassCompareOperator.NOT_EQUAL:
return "!=";
case AutoclassCompareOperator.GREATER_THAN:
return ">";
case AutoclassCompareOperator.GREATER_THAN_OR_EQUAL:
return ">=";
case AutoclassCompareOperator.LESS_THAN:
return "<";
case AutoclassCompareOperator.LESS_THAN_OR_EQUAL:
return "<=";
case AutoclassCompareOperator.CONTAINS:
return "Contains";
case AutoclassCompareOperator.CONTAINS_INSENSITIVE:
return "Contains (case insensitive)";
default:
return "ERROR";
}
}
}
}

View File

@ -1,29 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Models.Autoclass;
using System.ComponentModel.DataAnnotations;
using System.Runtime.InteropServices;
using AAIntegration.SimmonsBank.API.Entities;
using System.Collections.Generic;
public class AutoclassRuleCreateRequest
{
public string Name { get; set; }
public int AccountId { get; set; }
public IEnumerable<AutoclassExpressionCreateRequest> Expressions { get; set; }
public IEnumerable<AutoclassChangeCreateRequest> Changes { get; set; }
public bool Enabled { get; set; }
public bool? TriggerOnCreate { get; set; } = null;
}
public class AutoclassExpressionCreateRequest
{
public AutoclassTransactionField TransactionField { get; set; }
public AutoclassCompareOperator CompareOperator { get; set; }
public string Value { get; set; }
}
public class AutoclassChangeCreateRequest
{
public AutoclassTransactionField Field { get; set; }
public string Value { get; set; }
}

View File

@ -1,16 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Models.Autoclass;
using System.ComponentModel.DataAnnotations;
using System.Runtime.InteropServices;
using AAIntegration.SimmonsBank.API.Entities;
using System.Collections.Generic;
public class AutoclassRuleUpdateRequest
{
public string Name { get; set; } = null;
public int? AccountId { get; set; } = null;
public IEnumerable<AutoclassExpressionCreateRequest> Expressions { get; set; } = null;
public IEnumerable<AutoclassChangeCreateRequest> Changes { get; set; } = null;
public bool? Enabled { get; set; } = null;
public bool? TriggerOnUpdate { get; set; } = null;
}

View File

@ -1,12 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Models.CurrencyType;
using System.ComponentModel.DataAnnotations;
using System.Runtime.InteropServices;
using AAIntegration.SimmonsBank.API.Entities;
public class CurrencyTypeCreateRequest
{
public string Code { get; set; } // USD
public string Symbol { get; set; } // $
public int DecimalPlaces { get; set; } // 2
}

View File

@ -1,26 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Models.Envelopes;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Runtime.InteropServices;
using AAIntegration.SimmonsBank.API.Entities;
public class EnvelopeCreateRequest
{
public string Name { get; set; }
public int Account { get; set; }
public string InitialBalance { get; set; }
public bool Enabled { get; set; }
public bool IsPersistant { get; set; }
public int Priority { get; set; }
public string ExternalAccountNumber { get; set; }
public IEnumerable<EnvelopeFundingMethodCreateRequest> FundingMethods { get; set; }
}
public class EnvelopeFundingMethodCreateRequest
{
public int Order { get; set; }
public EnvelopeFundingMethodModes Mode { get; set; }
public string Value { get; set; }
public int PeriodsToLookback { get; set; } = 0;
}

View File

@ -1,29 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using AAIntegration.SimmonsBank.API.Entities;
namespace AAIntegration.SimmonsBank.API.Models.Envelopes;
public class EnvelopeDTO
{
public int Id { get; set; }
public string Name { get; set; }
public int AccountId { get; set; }
public bool Enabled { get; set; }
public TimeSpan Period { get; set; }
public bool IsPersistant { get; set; }
public int Priority { get; set; }
public decimal Balance { get; set; }
public decimal InitialBalance { get; set; }
public DateTime? LastTriggeredOn { get; set; }
public IEnumerable<EnvelopeFundingMethodDTO> FundingMethods { get; set; }
}
public class EnvelopeFundingMethodDTO
{
public int Order { get; set; }
public EnvelopeFundingMethodModes Mode { get; set; }
public string Value { get; set; }
public int PeriodsToLookback { get; set; } = 0;
}

View File

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using AAIntegration.SimmonsBank.API.Entities;
namespace AAIntegration.SimmonsBank.API.Models.Envelopes;
public class EnvelopeHistoricalDTO
{
//public int Id { get; set; }
public int EnvelopeId { get; set; }
public int LookBack { get; set; }
public decimal? EnvelopeFunding { get; set; } = null;
public Statistic? Credit { get; set; } = null;
public Statistic? Debit { get; set; } = null;
}

View File

@ -1,19 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Models.Envelopes;
using System;
using System.Collections;
using System.ComponentModel.DataAnnotations;
using AAIntegration.SimmonsBank.API.Entities;
public class EnvelopeUpdateRequest
{
public string Name { get; set; } = null;
public int? Account { get; set; } = null;
public bool? Enabled { get; set; } = null;
public TimeSpan? Period { get; set; } = null;
public bool? IsPersistant { get; set; } = null;
public int? Priority { get; set; } = null;
public string? InitialBalance { get; set; } = null;
public DateTime? LastTriggeredOn { get; set; } = null;
public IEnumerable<EnvelopeFundingMethodCreateRequest> FundingMethods { get; set; } = null;
}

View File

@ -11,37 +11,6 @@ public class TransactionCreate
public string Description { get; set; }
public int? DebitAccount { get; set; }
public int? CreditAccount { get; set; }
public int? DebitEnvelope { get; set; }
public int? CreditEnvelope { get; set; }
public bool? IsEnvelopeFundingTransaction { get; set; } = null;
public decimal Amount { get; set; }
public int CurrencyType { get; set; }
public string Notes { get; set; }
public bool IsPending { get; set; }
public List<string>? Tags { get; set; } = null;
public bool? TriggerAutoclassRules { get; set; } = null;
}
/*
// TransactionCreate myDeserializedClass = JsonConvert.DeserializeObject<TransactionCreate>(myJsonResponse);
{
"Owner":1,
"SplitDescription":"string",
"UreatedOn":"2018-09-17T12:46:47+01:00",
"UpdatedOn":"2018-09-17T12:46:47+01:00",
"ExternalId":"string",
"Transactions":[
{
"Description":"string",
"DebitAccount":1,
"CreditAccount":1,
"Amount":"string",
"CreatedOn":"2018-09-17T12:46:47+01:00",
"UpdatedOn":"2018-09-17T12:46:47+01:00",
"ExternalId":"string",
"CreditAccount":1,
"Notes":"string",
"IsPending":true
}
]
}*/
}

View File

@ -14,11 +14,6 @@ public class TransactionDto
public string Description { get; set; }
public int DebitAccountId { get; set; }
public int CreditAccountId { get; set; }
public int DebitEnvelopeId { get; set; }
public int CreditEnvelopeId { get; set; }
public decimal Amount { get; set; }
public Entities.CurrencyType CurrencyType { get; set; }
public string Notes { get; set; }
public bool IsPending { get; set; }
public List<string>? Tags { get; set; }
}

View File

@ -10,13 +10,6 @@ public class TransactionUpdateRequest
public string? Description { get; set; } = null;
public int? DebitAccount { get; set; } = null;
public int? CreditAccount { get; set; } = null;
public int? DebitEnvelope { get; set; } = null;
public int? CreditEnvelope { get; set; } = null;
public bool? IsEnvelopeFundingTransaction { get; set; } = null;
public decimal? Amount { get; set; } = null;
public int? CurrencyType { get; set; } = null;
public string? Notes { get; set; } = null;
public bool? IsPending { get; set; } = null;
public bool? TriggerAutoclassRules { get; set; } = false;
public List<string>? Tags { get; set; } = null;
}

View File

@ -1,12 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Models.Users;
using System.ComponentModel.DataAnnotations;
public class AuthenticateRequest
{
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
}

View File

@ -1,10 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Models.Users;
public class AuthenticateResponse
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Username { get; set; }
public string Token { get; set; }
}

View File

@ -1,28 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Models.Users;
using System.ComponentModel.DataAnnotations;
using AAIntegration.SimmonsBank.API.Entities;
public class RegisterRequest
{
[Required]
public string Username { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
[EnumDataType(typeof(Role))]
public string Role { get; set; }
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[MinLength(6)]
public string Password { get; set; }
}

View File

@ -1,38 +1,9 @@
namespace AAIntegration.SimmonsBank.API.Models.Users;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using AAIntegration.SimmonsBank.API.Entities;
public class UserUpdateRequest
{
public string Username { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string? Username { get; set; } = null;
public string? Password { get; set; } = null;
public string? MFAKey { get; set; } = null;
[EnumDataType(typeof(Role))]
public string Role { get; set; }
[EmailAddress]
public string Email { get; set; }
// treat empty string as null for password fields to
// make them optional in front end apps
private string _password;
[MinLength(6)]
public string Password
{
get => _password;
set => _password = replaceEmptyWithNull(value);
}
// helpers
private string replaceEmptyWithNull(string value)
{
// replace empty string with null to make field optional
return string.IsNullOrEmpty(value) ? null : value;
}
}

View File

@ -1,53 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using AAIntegration.SimmonsBank.API.Configs;
using AAIntegration.SimmonsBank.API.Entities;
using AAIntegration.SimmonsBank.API.Models.Envelopes;
using AAIntegration.SimmonsBank.API.Models.Transactions;
using AAIntegration.SimmonsBank.API.Services;
using Microsoft.Extensions.Options;
namespace AAIntegration.SimmonsBank.API.Processes;
public class EnvelopeFundingProcess : IEnvelopeFundingProcess
{
private readonly EnvelopeFundConfig _config;
private readonly ILogger<EnvelopeFundingProcess> _logger;
public EnvelopeFundingProcess(
IOptions<EnvelopeFundConfig> config,
ILogger<EnvelopeFundingProcess> logger)
{
_config = config.Value;
_logger = logger;
}
public async Task FundEnvelopes(IEnvelopeService envelopeService)
{
_logger.LogInformation($"Starting envelope funding...");
// Grab envelopes
List<Envelope> envelopes = envelopeService.GetAll().ToList();
bool anyTriggered = false;
foreach (Envelope env in envelopes)
{
// Check if needs triggering
if (env.Enabled && !envelopeService.HasBeenFundedThisMonth(env.Id))
{
_logger.LogInformation($"Envelope '{env.Name}' (id={env.Id}) needs funding - Has now been triggered.");
anyTriggered = true;
// Fund Envelope
envelopeService.FundEnvelopeForThisMonth(env.Id);
}
}
if (!anyTriggered)
_logger.LogInformation($"No action taken.");
else
_logger.LogInformation($"Envelope funding complete.");
}
}

View File

@ -1,9 +0,0 @@
using System.Threading.Tasks;
using AAIntegration.SimmonsBank.API.Services;
namespace AAIntegration.SimmonsBank.API.Processes;
public interface IEnvelopeFundingProcess
{
Task FundEnvelopes(IEnvelopeService envelopeService);
}

View File

@ -5,8 +5,6 @@ using Microsoft.EntityFrameworkCore;
using AAIntegration.SimmonsBank.API.Services;
using Microsoft.OpenApi.Models;
using System.Text.Json.Serialization;
using AAIntegration.SimmonsBank.API.Processes;
using AAIntegration.SimmonsBank.API.Workers;
using AAIntegration.SimmonsBank.API.Configs;
using AAIntegration.SimmonsBank.API.Handlers;
using Microsoft.IdentityModel.Tokens;
@ -81,20 +79,12 @@ internal class Program
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IAccountService, AccountService>();
builder.Services.AddScoped<ICurrencyTypeService, CurrencyTypeService>();
builder.Services.AddScoped<ITransactionService, TransactionService>();
builder.Services.AddScoped<IEnvelopeService, EnvelopeService>();
builder.Services.AddScoped<IAutoclassService, AutoclassService>();
builder.Services.AddScoped<ICacheService, CacheService>();
builder.Services.AddScoped<IApiKeyService, ApiKeyService>();
builder.Services.AddScoped<IVersionService, VersionService>();
builder.Services.AddScoped<ApiKeyAuthenticationHandler>();
builder.Services.AddSingleton<IEnvelopeFundingProcess, EnvelopeFundingProcess>();
builder.Services.AddHostedService<EnvelopeFundWorker>();
var app = builder.Build();
// Apply Database Migrations - This is NOT recommended for multi-node deployment!!!

View File

@ -18,9 +18,7 @@ public interface IAccountService
Account GetById(int accountId);
void Create(AccountCreateRequest model);
void Update(int accountId, AccountUpdateRequest model);
Account RefreshAccountBalance(int accountId);
void Delete(int accountId);
AccountHistorical GetAccountHistorical(int accountId, int lookBack);
}
public class AccountService : IAccountService
@ -28,18 +26,15 @@ public class AccountService : IAccountService
private DataContext _context;
private readonly IMapper _mapper;
private IUserService _userService;
private ICurrencyTypeService _currencyTypeService;
public AccountService(
DataContext context,
IMapper mapper,
IUserService userService,
ICurrencyTypeService currencyTypeService)
IUserService userService)
{
_context = context;
_mapper = mapper;
_userService = userService;
_currencyTypeService = currencyTypeService;
}
public IEnumerable<Account> GetAll()
@ -73,13 +68,7 @@ public class AccountService : IAccountService
Account account = new Account {
Name = model.Name,
InitialBalance = Convert.ToDecimal(model.InitialBalance),
Balance = Convert.ToDecimal(model.InitialBalance),
VirtualBalance = Convert.ToDecimal(model.InitialBalance),
LastActivity = DateTime.UtcNow,
CreatedOn = DateTime.UtcNow,
CurrencyId = model.Currency,
Currency = _currencyTypeService.GetById(model.Currency),
ExternalAccountNumber = model.ExternalAccountNumber
};
@ -99,39 +88,12 @@ public class AccountService : IAccountService
if (!string.IsNullOrWhiteSpace(model.Name))
account.Name = model.Name;
// Owner
/*if (model.Owner.HasValue)
{
account.OwnerId = model.Owner.Value;
account.Owner = _userService.GetById(model.Owner.Value);
}*/
// Initial Balance
if (!string.IsNullOrWhiteSpace(model.InitialBalance))
account.InitialBalance = Convert.ToDecimal(model.InitialBalance);
// CurrencyType
if (model.Currency.HasValue)
{
account.CurrencyId = model.Currency.Value;
account.Currency = _context.CurrencyTypes.Find(model.Currency.Value);
}
// External Account Number
if (!string.IsNullOrWhiteSpace(model.ExternalAccountNumber))
account.ExternalAccountNumber = model.ExternalAccountNumber;
// copy model to account and save
//_mapper.Map(model, account);
_context.Accounts.Update(account);
_context.SaveChanges();
_context.RecalculateAccountBalance(accountId);
}
public Account RefreshAccountBalance(int accountId)
{
_context.RecalculateAccountBalance(accountId);
return _context.Accounts.Find(accountId);
}
public void Delete(int accountId)
@ -141,15 +103,6 @@ public class AccountService : IAccountService
_context.SaveChanges();
}
public AccountHistorical GetAccountHistorical(int accountId, int lookBack)
{
// Input validate lookBack
if (lookBack < 1)
throw new AppException($"Look Back value must be greater than 0.");
return _context.GetAccountHistorical(accountId, lookBack);
}
// helper methods
private Account getAccount(int id)

View File

@ -1,43 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Services;
using AutoMapper;
using BCrypt.Net;
using AAIntegration.SimmonsBank.API.Config;
using System;
using System.Security.Cryptography;
public interface IApiKeyService
{
string GenerateApiKey();
}
public class ApiKeyService : IApiKeyService
{
private DataContext _context;
private readonly IMapper _mapper;
public ApiKeyService(
DataContext context,
IMapper mapper)
{
_context = context;
_mapper = mapper;
}
private const string _prefix = "CT-";
private const int _numberOfSecureBytesToGenerate = 32;
private const int _lengthOfKey = 32;
public string GenerateApiKey()
{
var bytes = RandomNumberGenerator.GetBytes(_numberOfSecureBytesToGenerate);
string base64String = Convert.ToBase64String(bytes)
.Replace("+", "-")
.Replace("/", "_");
var keyLength = _lengthOfKey - _prefix.Length;
return _prefix + base64String[..keyLength];
}
}

View File

@ -1,407 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Services;
using AutoMapper;
using BCrypt.Net;
using AAIntegration.SimmonsBank.API.Entities;
using AAIntegration.SimmonsBank.API.Config;
using AAIntegration.SimmonsBank.API.Models.Autoclass;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System;
using Microsoft.EntityFrameworkCore;
using Internal;
public interface IAutoclassService
{
IEnumerable<AutoclassRule> GetAll(int? account = null);
AutoclassRule GetById(int id);
void Create(AutoclassRuleCreateRequest model);
void Update(int autoclassId, AutoclassRuleUpdateRequest model);
void Delete(int id);
List<AutoclassFieldMetaDTO> GetAllFieldInfo();
List<AutoclassTypeMetaDTO> GetAllTypeOperatorInfo();
Transaction ProcessRule(Transaction transaction, AutoclassRule rule, out bool ruleFired);
int ApplyRulesForTransaction(int transactionId);
int ApplyAutoclassRule(int autoclassRule);
int ApplyAutoclassRule(AutoclassRule autoclassRule);
}
public class AutoclassService : IAutoclassService
{
private DataContext _context;
private readonly IMapper _mapper;
private readonly ILogger<AutoclassService> _logger;
private List<AutoclassTypeMetaDTO> typeMetaData;
private List<AutoclassFieldMetaDTO> fieldMetaData;
public AutoclassService(
DataContext context,
IMapper mapper,
ILogger<AutoclassService> logger)
{
_context = context;
_mapper = mapper;
_logger = logger;
this.CreateFieldMetaData();
this.CreateTypeMetaData();
}
public IEnumerable<AutoclassRule> GetAll(int? account = null)
{
if (account.HasValue)
{
return _context.AutoclassRules
.Include(t => t.Account)
.Include(t => t.Expressions)
.Include(t => t.Changes)
.ToList()
.Where(a => a.Account.Id == account.Value);
}
return _context.AutoclassRules
.Include(t => t.Expressions)
.Include(t => t.Changes)
.ToList();
}
public AutoclassRule GetById(int id)
{
return getAutoclass(id);
}
public void Create(AutoclassRuleCreateRequest model)
{
AutoclassRule rule = new AutoclassRule {
Name = model.Name,
Account = _context.Accounts.Find(model.AccountId),
Expressions = _mapper.Map<IEnumerable<AutoclassExpression>>(model.Expressions),
Changes = _mapper.Map<IEnumerable<AutoclassChange>>(model.Changes),
Enabled = model.Enabled
};
if (rule.Account == null)
throw new AppException($"Could not find the account with id '{model.AccountId}'.");
if (rule.Account.Id == 0)
throw new AppException($"Can not add rules to account with id '0'.");
if (_context.AutoclassRules.Any(x =>
x.Name.ToUpper() == rule.Name.ToUpper()
&& x.Account.Id == rule.Account.Id))
{
throw new AppException("AutoclassRule with the same name already exists for this account.");
}
_context.AutoclassRules.Add(rule);
_context.SaveChanges();
if (model.TriggerOnCreate.HasValue && model.TriggerOnCreate.Value)
this.ApplyAutoclassRule(rule.Id);
}
public void Update(int autoclassId, AutoclassRuleUpdateRequest model)
{
AutoclassRule rule = getAutoclass(autoclassId);
// Account
if (model.AccountId.HasValue)
rule.Account = _context.Accounts.Find(model.AccountId.Value);
// Name
if (!string.IsNullOrWhiteSpace(model.Name))
{
if (model.Name != rule.Name && _context.AutoclassRules.Any(x =>
x.Name.ToUpper() == model.Name.ToUpper()
&& x.Account.Id == rule.Account.Id))
{
throw new AppException("AutoclassRule with the same name already exists for this account.");
}
rule.Name = model.Name;
}
// Enabled
if (model.Enabled.HasValue)
rule.Enabled = model.Enabled.Value;
// Expressions
if (model.Expressions != null)
{
// Remove expression defined on autoclass rule
foreach (AutoclassExpression expression in rule.Expressions)
_context.AutoclassExpressions.Remove(expression);
// Add the expressions from request
rule.Expressions = _mapper.Map<IEnumerable<AutoclassExpression>>(model.Expressions);
}
// Changes
if (model.Changes != null)
{
// Remove changes defined on autoclass rule
foreach (AutoclassChange changes in rule.Changes)
_context.AutoclassChanges.Remove(changes);
// Add the expressions from request
rule.Changes = _mapper.Map<IEnumerable<AutoclassChange>>(model.Changes);
}
_context.AutoclassRules.Update(rule);
_context.SaveChanges();
// TriggerOnUpdate
if (model.TriggerOnUpdate.HasValue && model.TriggerOnUpdate.Value)
this.ApplyAutoclassRule(rule.Id);
}
public void Delete(int id)
{
var autoclassRule = getAutoclass(id);
_context.AutoclassRules.Remove(autoclassRule);
_context.SaveChanges();
}
private AutoclassRule getAutoclass(int id)
{
var autoclassRule = _context.AutoclassRules
.Include(t => t.Account)
.Include(t => t.Expressions)
.Include(t => t.Changes)
.FirstOrDefault(o => o.Id == id);
//_context.Entry(autoclassRule).Reference(t => t.Expressions).Load();
//_context.Entry(autoclassRule).Reference(t => t.Changes).Load();
if (autoclassRule == null) throw new KeyNotFoundException("AutoclassRule not found");
return autoclassRule;
}
private void CreateFieldMetaData()
{
List<AutoclassFieldMetaDTO> fields = new List<AutoclassFieldMetaDTO>();
fields.Add(new AutoclassFieldMetaDTO(AutoclassTransactionField.AMOUNT));
fields.Add(new AutoclassFieldMetaDTO(AutoclassTransactionField.CREDIT_ACCOUNT));
fields.Add(new AutoclassFieldMetaDTO(AutoclassTransactionField.CREDIT_ENVELOPE));
fields.Add(new AutoclassFieldMetaDTO(AutoclassTransactionField.CURRENCY_TYPE));
fields.Add(new AutoclassFieldMetaDTO(AutoclassTransactionField.DATE));
fields.Add(new AutoclassFieldMetaDTO(AutoclassTransactionField.DEBIT_ACCOUNT));
fields.Add(new AutoclassFieldMetaDTO(AutoclassTransactionField.DEBIT_ENVELOPE));
fields.Add(new AutoclassFieldMetaDTO(AutoclassTransactionField.DESCRIPTION));
fields.Add(new AutoclassFieldMetaDTO(AutoclassTransactionField.EXTERNAL_ID));
fields.Add(new AutoclassFieldMetaDTO(AutoclassTransactionField.IS_PENDING));
fields.Add(new AutoclassFieldMetaDTO(AutoclassTransactionField.TAGS));
this.fieldMetaData = fields;
}
public List<AutoclassFieldMetaDTO> GetAllFieldInfo()
{
return this.fieldMetaData;
}
private void CreateTypeMetaData()
{
List<AutoclassTypeMetaDTO> types = new List<AutoclassTypeMetaDTO>();
types.Add(new AutoclassTypeMetaDTO(AutoclassType.DATETIME));
types.Add(new AutoclassTypeMetaDTO(AutoclassType.STRING));
types.Add(new AutoclassTypeMetaDTO(AutoclassType.DECIMAL));
types.Add(new AutoclassTypeMetaDTO(AutoclassType.BOOLEAN));
types.Add(new AutoclassTypeMetaDTO(AutoclassType.ACCOUNT));
types.Add(new AutoclassTypeMetaDTO(AutoclassType.ENVELOPE));
types.Add(new AutoclassTypeMetaDTO(AutoclassType.CURRENCYTYPE));
types.Add(new AutoclassTypeMetaDTO(AutoclassType.STRING_ARRAY));
this.typeMetaData = types;
}
public List<AutoclassTypeMetaDTO> GetAllTypeOperatorInfo()
{
return this.typeMetaData;
}
public int ApplyRulesForTransaction(int transactionId)
{
Transaction? transaction = _context.Transactions
.Include(t => t.DebitEnvelope)
.Include(t => t.DebitAccount)
.Include(t => t.CreditAccount)
.Include(t => t.CreditEnvelope)
.Include(t => t.CurrencyType)
.FirstOrDefault(t => t.Id == transactionId);
if (transaction == null)
throw new AppException($"Could not find transaction with id {transactionId}.");
int rulesFired = 0;
if (transaction.DebitAccount != null)
{
IEnumerable<AutoclassRule> debitAccountRules = _context.AutoclassRules
.Include(r => r.Account)
.Where(r => r.Account.Id == transaction.DebitAccount.Id)
.Include(r => r.Expressions)
.Include(r => r.Changes)
.ToList();
_logger.LogInformation($"Processing Autoclass Rules from DebitAccount '{transaction.DebitAccount.Id}' for new transaction '{transaction.Description}'.");
foreach (AutoclassRule rule in debitAccountRules)
{
transaction = ProcessRule(transaction, rule, out bool ruleFired);
if (ruleFired)
rulesFired++;
}
_logger.LogInformation($"...DebitAccount '{transaction.DebitAccount.Id}' rule processing complete.");
}
if (transaction.CreditAccount != null)
{
IEnumerable<AutoclassRule> creditAccountRules = _context.AutoclassRules
.Include(r => r.Account)
.Where(r => r.Account.Id == transaction.CreditAccount.Id)
.Include(r => r.Expressions)
.Include(r => r.Changes)
.ToList();
_logger.LogInformation($"Processing Autoclass Rules from CreditAccount '{transaction.CreditAccount.Id}' for new transaction '{transaction.Description}'.");
foreach (AutoclassRule rule in creditAccountRules)
{
transaction = ProcessRule(transaction, rule, out bool ruleFired);
if (ruleFired)
rulesFired++;
}
_logger.LogInformation($"...CreditAccount '{transaction.CreditAccount.Id}' rule processing complete.");
}
_context.Transactions.Update(transaction);
_context.SaveChanges();
return rulesFired;
}
public int ApplyAutoclassRule(int autoclassRuleId)
{
AutoclassRule? autoclassRule = _context.AutoclassRules
.Include(r => r.Account)
.Include(r => r.Expressions)
.Include(r => r.Changes)
.FirstOrDefault(r => r.Id == autoclassRuleId);
if (autoclassRule == null)
throw new AppException($"AutoclassRule with id {autoclassRuleId} not found.");
return this.ApplyAutoclassRule(autoclassRule);
}
public int ApplyAutoclassRule(AutoclassRule autoclassRule)
{
if (autoclassRule.Account == null)
throw new AppException($"System Error: AutoclassRule with id {autoclassRule} lacks an associated account.");
// Get Transactions
List<Transaction> transactions = _context.Transactions
.Include(t => t.DebitEnvelope)
.Include(t => t.DebitAccount)
.Include(t => t.CreditAccount)
.Include(t => t.CreditEnvelope)
.Include(t => t.CurrencyType)
.Where(t => (t.DebitAccount != null && t.DebitAccount.Id == autoclassRule.Account.Id)
|| (t.CreditAccount != null && t.CreditAccount.Id == autoclassRule.Account.Id))
.ToList();
int affectedTransactionsCount = 0;
// Process Each Transaction for this rule
for (int i = 0; i < transactions.Count; i++)
{
transactions[i] = ProcessRule(transactions[i], autoclassRule, out bool ruleFired);
_context.Transactions.Update(transactions[i]);
if (ruleFired)
affectedTransactionsCount++;
}
_context.SaveChanges();
return affectedTransactionsCount;
}
public Transaction ProcessRule(Transaction transaction, AutoclassRule rule, out bool ruleFired)
{
bool triggerRule = true;
foreach (AutoclassExpression exp in rule.Expressions)
{
triggerRule &= exp.Evaluate(transaction);
}
if (triggerRule)
{
_logger.LogInformation($"Rule '{rule.Name}' was triggered.");
foreach (AutoclassChange chg in rule.Changes)
{
_logger.LogInformation($"\tField {chg.Field} will be set to '{chg.Value}'.");
switch (chg.Field)
{
case AutoclassTransactionField.DATE:
transaction.Date = Convert.ToDateTime(chg.Value);
break;
case AutoclassTransactionField.EXTERNAL_ID:
transaction.ExternalId = chg.Value;
break;
case AutoclassTransactionField.DESCRIPTION:
transaction.Description = chg.Value;
break;
case AutoclassTransactionField.AMOUNT:
transaction.Amount = Convert.ToDecimal(chg.Value);
break;
case AutoclassTransactionField.IS_PENDING:
transaction.IsPending = Convert.ToBoolean(chg.Value);
break;
case AutoclassTransactionField.DEBIT_ACCOUNT:
transaction.DebitAccount = _context.Accounts.Find(Convert.ToInt32(chg.Value));
break;
case AutoclassTransactionField.CREDIT_ACCOUNT:
transaction.CreditAccount = _context.Accounts.Find(Convert.ToInt32(chg.Value));
break;
case AutoclassTransactionField.DEBIT_ENVELOPE:
transaction.DebitEnvelope = _context.Envelopes.Find(Convert.ToInt32(chg.Value));
break;
case AutoclassTransactionField.CREDIT_ENVELOPE:
transaction.CreditEnvelope = _context.Envelopes.Find(Convert.ToInt32(chg.Value));
break;
case AutoclassTransactionField.CURRENCY_TYPE:
transaction.CurrencyType = _context.CurrencyTypes.Find(Convert.ToInt32(chg.Value));
break;
case AutoclassTransactionField.TAGS:
transaction = transaction.AddTag(chg.Value);
break;
}
}
}
ruleFired = triggerRule;
return transaction;
}
}

View File

@ -35,7 +35,7 @@ public class CacheService : ICacheService
return clientId;
}
public void InvalidateApiKey(string apiKey)
/*public void InvalidateApiKey(string apiKey)
{
if (_memoryCache.TryGetValue<Dictionary<string, Guid>>("Authentication_ApiKeys", out var internalKeys))
{
@ -47,5 +47,5 @@ public class CacheService : ICacheService
}
_userService.InvalidateApiKey(apiKey);
}
}*/
}

View File

@ -1,108 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Services;
using AutoMapper;
using BCrypt.Net;
using AAIntegration.SimmonsBank.API.Entities;
using AAIntegration.SimmonsBank.API.Config;
using AAIntegration.SimmonsBank.API.Models.CurrencyType;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public interface ICurrencyTypeService
{
IEnumerable<CurrencyType> GetAll();
CurrencyType GetById(int id);
void Create(CurrencyTypeCreateRequest model);
//void Update(int id, AccountUpdateRequest model);
void Delete(int id);
}
public class CurrencyTypeService : ICurrencyTypeService
{
private DataContext _context;
private readonly IMapper _mapper;
public CurrencyTypeService(
DataContext context,
IMapper mapper)
{
_context = context;
_mapper = mapper;
if (_context.CurrencyTypes.Where(ct => ct.Code == "USD").ToList().Count() < 1)
this.createUSDCurrencyType();
}
private void createUSDCurrencyType()
{
_context.CurrencyTypes.Add(new CurrencyType() {
Code = "USD",
Symbol = "$",
DecimalPlaces = 2
});
_context.SaveChanges();
}
public IEnumerable<CurrencyType> GetAll()
{
return _context.CurrencyTypes;
}
public CurrencyType GetById(int id)
{
return getCurrencyType(id);
}
public void Create(CurrencyTypeCreateRequest model)
{
// Check that CurrencyType with same code doesn't exist
IEnumerable<CurrencyType> sameCode = _context.CurrencyTypes.Where(a => a.Code.ToUpper() == model.Code.ToUpper());
if (sameCode.Count() > 0)
throw new AppException("CurrencyType with code '" + model.Code + "' already exists");
// Check that CurrencyType with same symbol doesn't exist
IEnumerable<CurrencyType> sameSymbol = _context.CurrencyTypes.Where(a => a.Symbol.ToUpper() == model.Symbol.ToUpper());
if (sameSymbol.Count() > 0)
throw new AppException("CurrencyType with symbol '" + model.Symbol + "' already exists");
// map model to new account object
var currencyType = _mapper.Map<CurrencyType>(model);
_context.CurrencyTypes.Add(currencyType);
_context.SaveChanges();
}
/*public void Update(int id, AccountUpdateRequest model)
{
var account = getAccount(id);
// validate
if (model.Name != account.Name && _context.Accounts.Any(x => x.Name == model.Name))
throw new AppException("Account with the name '" + model.Name + "' already exists");
// copy model to account and save
_mapper.Map(model, account);
_context.Accounts.Update(account);
_context.SaveChanges();
}*/
public void Delete(int id)
{
var currencyType = getCurrencyType(id);
_context.CurrencyTypes.Remove(currencyType);
_context.SaveChanges();
}
// helper methods
private CurrencyType getCurrencyType(int id)
{
var currencyType = _context.CurrencyTypes.Find(id);
if (currencyType == null) throw new KeyNotFoundException("CurrencyType not found");
return currencyType;
}
}

View File

@ -1,396 +0,0 @@
namespace AAIntegration.SimmonsBank.API.Services;
using AutoMapper;
using BCrypt.Net;
using AAIntegration.SimmonsBank.API.Entities;
using AAIntegration.SimmonsBank.API.Config;
using AAIntegration.SimmonsBank.API.Models.Envelopes;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System;
using Internal;
using Microsoft.EntityFrameworkCore;
using AAIntegration.SimmonsBank.API.Models.Transactions;
public interface IEnvelopeService
{
IEnumerable<Envelope> GetAll(int? accountId = null);
Envelope GetById(int envelopeId);
void Create(EnvelopeCreateRequest model);
void Update(int envelopeId, EnvelopeUpdateRequest model);
//Envelope RefreshEnvelopeBalance(int envelopeId);
void Delete(int envelopeId);
bool HasBeenFundedThisMonth(int envelopeId);
EnvelopeHistorical GetEnvelopeHistorical(int envelopeId, int lookBack);
void FundEnvelopeForThisMonth(int envelopeId);
List<EnvelopeFundingMethodModes> GetEnvelopeFundingMethodModes();
}
public class EnvelopeService : IEnvelopeService
{
private DataContext _context;
private readonly IMapper _mapper;
private readonly ITransactionService _transactionService;
private readonly ILogger<EnvelopeService> _logger;
public EnvelopeService(
DataContext context,
IMapper mapper,
ITransactionService transactionService,
ILogger<EnvelopeService> logger)
{
_context = context;
_mapper = mapper;
_transactionService = transactionService;
_logger = logger;
}
public IEnumerable<Envelope> GetAll(int? accountId = null)
{
if (accountId != null)
return _context.Envelopes
.Include(e => e.Account)
.Include(e => e.FundingMethods)
.Where(e => e.Account.Id == accountId.Value);
return _context.Envelopes
.Include(e => e.FundingMethods);
}
public Envelope GetById(int envelopeId)
{
return getEnvelope(envelopeId);
}
public void Create(EnvelopeCreateRequest model)
{
Account account = _context.Accounts.Find(model.Account);
if (account == null)
throw new AppException("Could not create envelope. Account with id '" + model.Account + "' not found.");
// Check that envelope with same name or same external number doesn't exist
IEnumerable<Envelope> envelopesWithSameName = _context.Envelopes
.Include(e => e.Account)
.Where(e =>
e.Name.ToUpper() == model.Name.ToUpper()
&& e.Account.Id == model.Account);
if (envelopesWithSameName.Count() > 0)
throw new AppException("Envelope with name '" + model.Name + "' already exists for account '" + account.Name + "'.");
// map model to new envelope object
//var envelope = _mapper.Map<Envelope>(model);
Envelope envelope = new Envelope {
Name = model.Name,
Account = account,
InitialBalance = Convert.ToDecimal(model.InitialBalance),
Balance = Convert.ToDecimal(model.InitialBalance),
Enabled = model.Enabled,
IsPersistant = model.IsPersistant,
Priority = model.Priority,
LastTriggeredOn = null
};
_context.Envelopes.Add(envelope);
_context.SaveChanges();
foreach (EnvelopeFundingMethodCreateRequest methodReq in model.FundingMethods)
{
EnvelopeFundingMethod method = new EnvelopeFundingMethod {
Envelope = envelope,
Order = methodReq.Order,
Mode = methodReq.Mode,
Value = methodReq.Value,
PeriodsToLookback = methodReq.PeriodsToLookback
};
_context.EnvelopeFundingMethods.Add(method);
}
_context.SaveChanges();
}
public void Update(int envelopeId, EnvelopeUpdateRequest model)
{
Envelope envelope = getEnvelope(envelopeId);
// Name
if (!string.IsNullOrWhiteSpace(model.Name))
{
if (model.Name != envelope.Name && _context.Envelopes.Any(x => x.Name == model.Name))
throw new AppException("Envelope with the name '" + model.Name + "' already exists");
envelope.Name = model.Name;
}
// Account
if (model.Account.HasValue)
envelope.Account = _context.Accounts.Find(model.Account.Value);
// Enabled
if (model.Enabled.HasValue)
envelope.Enabled = model.Enabled.Value;
// Period
if (model.Period.HasValue)
envelope.Period = model.Period.Value;
// IsPersistant
if (model.IsPersistant.HasValue)
envelope.IsPersistant = model.IsPersistant.Value;
// Priority
if (model.Priority.HasValue)
envelope.Priority = model.Priority.Value;
// Last Triggered On
if (model.LastTriggeredOn.HasValue)
envelope.LastTriggeredOn = model.LastTriggeredOn;
// FundingMethods
if (model.FundingMethods != null)
{
// Remove funding methods defined on envelope
foreach (EnvelopeFundingMethod method in envelope.FundingMethods)
{
_context.EnvelopeFundingMethods.Remove(method);
}
// Add the methods from request
foreach (EnvelopeFundingMethodCreateRequest methodReq in model.FundingMethods)
{
EnvelopeFundingMethod method = new EnvelopeFundingMethod {
Envelope = envelope,
Order = methodReq.Order,
Mode = methodReq.Mode,
Value = methodReq.Value,
PeriodsToLookback = methodReq.PeriodsToLookback
};
_context.EnvelopeFundingMethods.Add(method);
}
}
// copy model to envelope and save
//_mapper.Map(model, envelope);
_context.Envelopes.Update(envelope);
_context.SaveChanges();
_context.RecalculateEnvelopeBalance(envelopeId);
}
/*
public Envelope RefreshEnvelopeBalance(int envelopeId)
{
_context.RecalculateEnvelopeBalance(envelopeId);
return _context.Envelopes.Find(envelopeId);
}*/
public void Delete(int envelopeId)
{
// MUST!!! Classify intra-account transactions as NULL account ids, and only envelope Ids
// MUST!!! Classify inter-account transactions as correct account ids, even with envelope ids
List<Transaction> delTransactions = _context.Transactions
.Include(t => t.CreditEnvelope)
.Include(t => t.DebitEnvelope)
.Include(t => t.CreditAccount)
.Include(t => t.DebitAccount)
.Where(t =>
(t.CreditEnvelope != null && t.CreditEnvelope.Id == envelopeId) ||
(t.DebitEnvelope != null && t.DebitEnvelope.Id == envelopeId))
.ToList();
foreach (Transaction tran in delTransactions)
{
if (tran.CreditAccount == null && tran.DebitAccount == null && (tran.CreditEnvelope == null || tran.DebitEnvelope == null))
{
// Delete transactions who only have credit or debit envelope of this envelope, and nothing else (funding type transactions)
_context.Transactions.Remove(tran);
}
else
{
// Change transactions that have a reference to this envelopeId
if (tran.DebitEnvelope?.Id == envelopeId)
tran.DebitEnvelope = null;
else
tran.CreditEnvelope = null;
}
}
var envelope = getEnvelope(envelopeId);
_context.Envelopes.Remove(envelope);
_context.SaveChanges();
}
public bool HasBeenFundedThisMonth(int envelopeId)
{
return _context.Transactions
.Include(t => t.CreditEnvelope)
.Where(t => t.CreditEnvelope != null && t.CreditEnvelope.Id == envelopeId && t.IsEnvelopeFundingTransaction == true)
.Any(t => t.Date.Year == DateTime.UtcNow.Year && t.Date.Month == DateTime.UtcNow.Month);
}
public EnvelopeHistorical GetEnvelopeHistorical(int envelopeId, int lookBack)
{
// Input validate lookBack
if (lookBack < 1)
throw new AppException($"Look Back value must be greater than 0.");
return _context.GetEnvelopeHistorical(envelopeId, lookBack);
}
public void FundEnvelopeForThisMonth(int envelopeId)
{
// !!!!!!
// Add notes in UI about how things are calculated
Envelope env = _context.Envelopes
.Include(e => e.FundingMethods)
.FirstOrDefault(e => e.Id == envelopeId);
if (env.Enabled == false)
{
_logger.LogInformation($"Envelope {env.GetLogString()} is disabled. No funding will occur.");
}
if (env.FundingMethods == null || env.FundingMethods.Any() == false)
{
_logger.LogInformation($"Envelope {env.GetLogString()} couldn't be funded. No funding methods found.");
return;
}
if (env.IsPersistant == false)
{
this.ZeroOutEnvelopeFunds(env);
}
DateTime firstOfThisMonth = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1);
decimal amount = this.CalculateFundingAmount(envelopeId);
TransactionCreate transaction = new TransactionCreate {
Description = $"Funding Envelope",
Date = firstOfThisMonth.ToUniversalTime(),
CreditEnvelope = envelopeId,
IsEnvelopeFundingTransaction = true,
Amount = amount,
CurrencyType = 1,// CHANGE TO DYNAMIC
IsPending = false,
Notes = "Automated Transaction. Envelope Funding Event."
};
_transactionService.Create(transaction);
}
public void ZeroOutEnvelopeFunds(int envelopeId)
{
ZeroOutEnvelopeFunds(getEnvelope(envelopeId));
}
public void ZeroOutEnvelopeFunds(Envelope envelope)
{
if (envelope.Balance == 0)
{
_logger.LogInformation($"Envelope {envelope.GetLogString()} is already at zero.");
return;
}
DateTime lastOfLastMonth = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1).AddDays(-1);
TransactionCreate transaction = new TransactionCreate {
Description = $"Envelope Balance Reset",
Date = lastOfLastMonth.ToUniversalTime(),
IsEnvelopeFundingTransaction = true,
Amount = envelope.Balance,
CurrencyType = 1,// CHANGE TO DYNAMIC
IsPending = false,
Notes = "Automated Transaction. Envelope Clearing Event."
};
if (envelope.Balance < 0)
transaction.CreditEnvelope = envelope.Id;
else
transaction.DebitEnvelope = envelope.Id;
_transactionService.Create(transaction);
_logger.LogInformation($"Envelope {envelope.GetLogString()} set to zero.");
}
private decimal CalculateFundingAmount(int envelopeId, DateTime? month = null)
{
DateTime dt = month.HasValue ? month.Value : DateTime.UtcNow;
Envelope envelope = _context.Envelopes
.Include(e => e.Account)
.Include(e => e.FundingMethods)
.FirstOrDefault(e => e.Id == envelopeId);
decimal virtualBalance = envelope.Account.VirtualBalance;
decimal fundingAmount = 0;
List<EnvelopeFundingMethod> fundingMethods = envelope.FundingMethods.OrderBy(f => f.Order).ToList();
foreach (EnvelopeFundingMethod method in fundingMethods)
{
decimal value = Convert.ToDecimal(method.Value);
decimal amount = 0;
switch (method.Mode)
{
case EnvelopeFundingMethodModes.PERCENTAGE:
amount = virtualBalance * value / 100m;
amount = amount < 0 ? 0 : amount;
break;
case EnvelopeFundingMethodModes.HISTORICAL_MEDIAN:
case EnvelopeFundingMethodModes.HISTORICAL_MEAN:
EnvelopeHistorical hist = this.GetEnvelopeHistorical(envelopeId, method.PeriodsToLookback);
if (hist.Debit == null || hist.Credit == null)
amount = value;
else if (method.Mode == EnvelopeFundingMethodModes.HISTORICAL_MEDIAN)
if (!hist.Debit.Median.HasValue || !hist.Credit.Median.HasValue)
amount = value;
else
amount = hist.Debit.Median.Value - hist.Credit.Median.Value;
else if (method.Mode == EnvelopeFundingMethodModes.HISTORICAL_MEAN)
if (!hist.Debit.Mean.HasValue || !hist.Credit.Mean.HasValue)
amount = value;
else
amount = hist.Debit.Mean.Value - hist.Credit.Mean.Value;
amount = amount > value ? amount : value;
break;
case EnvelopeFundingMethodModes.ABSOLUTE:
default:
amount = Convert.ToDecimal(method.Value);
break;
}
_logger.LogInformation($"FundMethod -> Order:{method.Order}, Mode:{method.Mode}, Value:{method.Value}, Amount:{amount}");
fundingAmount += amount;
}
_logger.LogInformation($"Calculated Fund Amount for envelope {envelopeId}: {fundingAmount}");
return fundingAmount;
}
public List<EnvelopeFundingMethodModes> GetEnvelopeFundingMethodModes()
{
return Enum.GetValues<EnvelopeFundingMethodModes>().ToList();
}
// helper methods
private Envelope getEnvelope(int id)
{
var envelope = _context.Envelopes
.Include(e => e.Account)
.Include(e => e.FundingMethods)
.FirstOrDefault(e => e.Id == id);
if (envelope == null) throw new KeyNotFoundException("Envelope not found");
return envelope;
}
}

View File

@ -28,28 +28,22 @@ public class TransactionService : ITransactionService
private DataContext _context;
private readonly IMapper _mapper;
private readonly ILogger<TransactionService> _logger;
private readonly IAutoclassService _autoclassService;
public TransactionService(
DataContext context,
IMapper mapper,
ILogger<TransactionService> logger,
IAutoclassService autoclassService)
ILogger<TransactionService> logger)
{
_context = context;
_mapper = mapper;
_logger = logger;
_autoclassService = autoclassService;
}
public IEnumerable<Transaction> GetAll()
{
return _context.Transactions
.Include(t => t.CurrencyType)
.Include(t => t.DebitAccount)
.Include(t => t.CreditAccount)
.Include(t => t.DebitEnvelope)
.Include(t => t.CreditEnvelope)
.ToList();
}
@ -72,23 +66,6 @@ public class TransactionService : ITransactionService
return account;
}
private Envelope prepareEnvelope(int? envelopeId)
{
if (envelopeId == null || envelopeId.Value == 0)
{
return null;
}
Envelope envelope = _context.Envelopes
.Include(e => e.Account)
.FirstOrDefault(e => e.Id == envelopeId.Value);
if (envelope == null)
throw new AppException("Could not find envelope with ID of '" + envelopeId.Value + "'.");
return envelope;
}
public IEnumerable<Transaction> BulkCreate(List<TransactionCreate> model)
{
List<Transaction> transactions = new List<Transaction>();
@ -113,14 +90,8 @@ public class TransactionService : ITransactionService
ExternalId = string.IsNullOrWhiteSpace(model.ExternalId) ? "" : model.ExternalId,
DebitAccount = prepareAccount(model.DebitAccount),
CreditAccount = prepareAccount(model.CreditAccount),
DebitEnvelope = prepareEnvelope(model.DebitEnvelope),
CreditEnvelope = prepareEnvelope(model.CreditEnvelope),
IsEnvelopeFundingTransaction = model.IsEnvelopeFundingTransaction == null ? false : model.IsEnvelopeFundingTransaction.Value,
Amount = Convert.ToDecimal(model.Amount),
CurrencyType = _context.CurrencyTypes.Find(model.CurrencyType),
Notes = model.Notes,
IsPending = model.IsPending,
Tags = model.Tags,
IsPending = model.IsPending
};
if (this.ValidateTransaction(transaction, errorOnFail) == false)
@ -136,12 +107,6 @@ public class TransactionService : ITransactionService
_logger.LogInformation("New transaction successfully created.");
if (!model.TriggerAutoclassRules.HasValue || model.TriggerAutoclassRules.Value)
_autoclassService.ApplyRulesForTransaction(transaction.Id);
//transaction = this.ApplyAutoclassRules(transaction);
this.UpdateAccountsAndEnvelopes(transaction);
return transaction;
}
@ -149,8 +114,6 @@ public class TransactionService : ITransactionService
{
Transaction transaction = getTransaction(id);
string temp = "";
// Transaction.Date
if (model.Date.HasValue)
transaction.Date = model.Date.Value;
@ -171,50 +134,22 @@ public class TransactionService : ITransactionService
if (model.CreditAccount.HasValue)
transaction.CreditAccount = prepareAccount(model.CreditAccount.Value);
// Transaction.DebitEnvelope
if (model.DebitEnvelope.HasValue)
transaction.DebitEnvelope = prepareEnvelope(model.DebitEnvelope.Value);
// Transaction.CreditEnvelope
if (model.CreditEnvelope.HasValue)
transaction.CreditEnvelope = prepareEnvelope(model.CreditEnvelope.Value);
// Transaction.IsEnvelopeFundingTransaction
if (model.IsEnvelopeFundingTransaction.HasValue)
transaction.IsEnvelopeFundingTransaction = model.IsEnvelopeFundingTransaction.Value;
// Transaction.Amount
if (model.Amount.HasValue)
transaction.Amount = model.Amount.Value;
// Transaction.CurrencyType
if (model.CurrencyType.HasValue)
transaction.CurrencyType = _context.CurrencyTypes.Find(model.CurrencyType.Value);
// Transaction.Notes
if (model.Notes != null)
transaction.Notes = model.Notes;
// Transaction.IsPending
if (model.IsPending.HasValue)
transaction.IsPending = model.IsPending.Value;
// Tags
if (model.Tags != null)
transaction.Tags = model.Tags;
this.ValidateTransaction(transaction);
transaction.UpdatedOn = DateTime.UtcNow;
_context.Transactions.Update(transaction);
_context.SaveChanges();
_logger.LogInformation($"Transaction '{id}' successfully updated.");
if (model.TriggerAutoclassRules.HasValue && model.TriggerAutoclassRules == true)
_autoclassService.ApplyRulesForTransaction(transaction.Id);
//transaction = this.ApplyAutoclassRules(transaction);
this.UpdateAccountsAndEnvelopes(transaction);
}
private bool ValidateTransaction(int transactionId)
@ -231,121 +166,47 @@ public class TransactionService : ITransactionService
return false;
}
// FIX VALIDATETRANSACTION REFERENCES TO USE BOOL
private bool ValidateTransaction(Transaction transaction, bool errorOnFail = true)
{
// MUST!!! Classify intra-account transactions as NULL account ids, and only envelope Ids
// MUST!!! Classify inter-account transactions as correct account ids, even with envelope ids
// There has to be at least 1 specified account or envelope
if (transaction.DebitAccount == null
&& transaction.CreditAccount == null
&& transaction.DebitEnvelope == null
&& transaction.CreditEnvelope == null)
// There has to be at least 1 specified account
if (transaction.DebitAccount == null && transaction.CreditAccount == null)
return ErrorOrFalse(errorOnFail, "There must be an envelope or account chosen for a transaction.");
// Envelopes must have associated parent account entities
if (transaction.CreditEnvelope != null && transaction.CreditEnvelope.Account == null)
return ErrorOrFalse(errorOnFail, $"The parent account of envelope '{transaction.CreditEnvelope.Name}' with id '{transaction.CreditEnvelope.Id}' could not be found.");
if (transaction.DebitEnvelope != null && transaction.DebitEnvelope.Account == null)
return ErrorOrFalse(errorOnFail, $"The parent account of envelope '{transaction.DebitEnvelope.Name}' with id '{transaction.DebitEnvelope.Id}' could not be found.");
// Accounts cannot be the same
if (transaction.DebitAccount != null && transaction.CreditAccount != null &&
transaction.DebitAccount.Id == transaction.CreditAccount.Id)
return ErrorOrFalse(errorOnFail, "The debit and credit accounts of a transaction cannot be the same.");
// Envelopes cannot be the same
if (transaction.DebitEnvelope != null && transaction.CreditEnvelope != null &&
transaction.DebitEnvelope.Id == transaction.CreditEnvelope.Id)
return ErrorOrFalse(errorOnFail, "The debit and credit envelopes of a transaction cannot be the same.");
// Envelopes must be child of underlying parent account
if (transaction.DebitEnvelope != null && transaction.DebitAccount != null &&
transaction.DebitEnvelope.Account.Id != transaction.DebitAccount.Id)
return ErrorOrFalse(errorOnFail, "The debit envelope of a transaction must be a child of the debit account.");
if (transaction.CreditEnvelope != null && transaction.CreditAccount != null &&
transaction.CreditEnvelope.Account.Id != transaction.CreditAccount.Id)
return ErrorOrFalse(errorOnFail, "The credit envelope of a transaction must be a child of the credit account.");
// If just envelopes are specified, they must belong to the same parent account, or add appropriate accounts
if (transaction.CreditEnvelope != null
&& transaction.DebitEnvelope != null
&& (transaction.DebitAccount != null || transaction.CreditAccount != null))
{
// There is an account specified when the envelopes are of the same account
if (transaction.CreditEnvelope.Account.Id == transaction.DebitEnvelope.Account.Id)
{
transaction.CreditAccount = null;
transaction.DebitAccount = null;
}
else
// There are envelopes from different accounts, without the underlying accounts specified
{
transaction.CreditAccount = transaction.CreditEnvelope.Account;
transaction.DebitAccount = transaction.DebitEnvelope.Account;
}
}
// Transaction Duplication Check - External ID
if (!string.IsNullOrWhiteSpace(transaction.ExternalId) && _context.Transactions.Any(x => x.ExternalId == transaction.ExternalId))
return ErrorOrFalse(errorOnFail, "Transaction with the external ID '" + transaction.ExternalId + "' already exists");
// Transaction Duplication Check - All other fields
if (_context.Transactions.Any(x =>
/*if (_context.Transactions.Any(x =>
x.Description == transaction.Description
&& x.Date == transaction.Date
&& x.DebitAccount == transaction.DebitAccount
&& x.CreditAccount == transaction.CreditAccount
&& x.DebitEnvelope == transaction.DebitEnvelope
&& x.CreditEnvelope == transaction.CreditEnvelope
&& x.Amount == transaction.Amount))
{
return ErrorOrFalse(errorOnFail, "Transaction with the same fields already exists");
}
}*/
return true;
}
private void UpdateAccountsAndEnvelopes(Transaction transaction, bool invert = false)
{
_logger.LogInformation($"Updating accounts and envelopes affected by transaction '{transaction.Id}'.");
decimal debitAmount = invert ? transaction.Amount : -transaction.Amount;
decimal creditAmount = invert ? -transaction.Amount : transaction.Amount;
if (transaction.DebitAccount != null)
_context.AddAmountToAccount(transaction.DebitAccount.Id, debitAmount);
if (transaction.CreditAccount != null)
_context.AddAmountToAccount(transaction.CreditAccount.Id, creditAmount);
if (transaction.DebitEnvelope != null)
_context.AddAmountToEnvelope(transaction.DebitEnvelope.Id, debitAmount);
if (transaction.CreditEnvelope != null)
_context.AddAmountToEnvelope(transaction.CreditEnvelope.Id, creditAmount);
}
public void Delete(int id)
{
var transaction = getTransaction(id);
_context.Transactions.Remove(transaction);
_context.SaveChanges();
UpdateAccountsAndEnvelopes(transaction, true);
}
private Transaction getTransaction(int id)
{
var transaction = _context.Transactions
.Include(t => t.DebitEnvelope)
.Include(t => t.DebitAccount)
.Include(t => t.CreditAccount)
.Include(t => t.CreditEnvelope)
.Include(t => t.CurrencyType)
.FirstOrDefault(t => t.Id == id);
if (transaction == null)

View File

@ -14,9 +14,17 @@ using System.Text;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.Extensions.Options;
using System.Security.Cryptography;
public interface IUserService
{
// New Based way
string Create(UserCreateRequest model);
void Update(string apiKey, UserUpdateRequest model);
void Delete(string apiKey);
Dictionary<string, int> GetAllApiKeys();
/* Other cringe way
AuthenticateResponse Authenticate(AuthenticateRequest model);
void Register(RegisterRequest model);
IEnumerable<User> GetAll();
@ -27,129 +35,70 @@ public interface IUserService
string GetUserApiKey(int id);
void InvalidateApiKey(string apiKey);
string CreateUserApiKey(int id);
*/
}
public class UserService : IUserService
{
private DataContext _context;
private readonly IMapper _mapper;
private readonly IApiKeyService _apiKeyService;
private readonly IOptions<AppSettings> _appSettings;
public UserService(
DataContext context,
IMapper mapper,
IApiKeyService apiKeyService,
IOptions<AppSettings> appSettings)
{
_apiKeyService = apiKeyService;
_context = context;
_mapper = mapper;
_appSettings = appSettings;
}
public AuthenticateResponse Authenticate(AuthenticateRequest model)
public string Create(UserCreateRequest model)
{
var user = _context.Users.SingleOrDefault(x => x.Username == model.Username);
User user = new User();
user.SimmonsBankUsername = model.Username;
user.SimmonsBankPassword = model.Password;
user.MFAKey = model.MFAKey;
// validate
if (user == null || !BCrypt.Verify(model.Password, user.PasswordHash))
throw new AppException("Username or password is incorrect");
// Authentication successful
// Create Claims
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
new Claim(ClaimTypes.Name, user.Username),
};
// Create JWT Token
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_appSettings.Value.Secret));
var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256Signature);
var tokeOptions = new JwtSecurityToken(
issuer: _appSettings.Value.APIUrl,
audience: _appSettings.Value.APIUrl,
claims: claims,
expires: DateTime.Now.AddDays(7),
signingCredentials: signinCredentials
);
var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions);
var response = _mapper.Map<AuthenticateResponse>(user);
response.Token = tokenString;
return response;
}
public void Register(RegisterRequest model)
{
// validate username
if (_context.Users.Any(x => x.Username == model.Username))
throw new AppException("Username '" + model.Username + "' is already taken");
// validate email
if (_context.Users.Any(x => x.Email == model.Email))
throw new AppException("Email '" + model.Email + "' is already taken");
// map model to new user object
var user = _mapper.Map<User>(model);
// hash password
user.PasswordHash = BCrypt.HashPassword(model.Password);
// Generate API Key
user.ApiKey = generateApiKey();
// save user
_context.Users.Add(user);
_context.SaveChanges();
// Return API Key
return user.ApiKey;
}
public IEnumerable<User> GetAll()
public void Update(string apiKey, UserUpdateRequest model)
{
return _context.Users;
}
var user = getUser(apiKey);
public User GetById(int id)
{
return getUser(id);
}
// User.Username
if (model.Username != null)
user.SimmonsBankUsername = model.Username;
public void Update(int id, UserUpdateRequest model)
{
var user = getUser(id);
// User.Password
if (model.Password != null)
user.SimmonsBankPassword = model.Password;
// validate
if (model.Email != user.Email && _context.Users.Any(x => x.Email == model.Email))
throw new AppException("User with the email '" + model.Email + "' already exists");
// User.MFAKey
if (model.MFAKey != null)
user.MFAKey = model.MFAKey;
// hash password if it was entered
if (!string.IsNullOrEmpty(model.Password))
user.PasswordHash = BCrypt.HashPassword(model.Password);
// copy model to user and save
_mapper.Map(model, user);
_context.Users.Update(user);
_context.SaveChanges();
}
public void Delete(int id)
public void Delete(string apiKey)
{
var user = getUser(id);
var user = getUser(apiKey);
_context.Users.Remove(user);
_context.SaveChanges();
}
public string CreateUserApiKey(int id)
{
var user = getUser(id);
user.ApiKey = _apiKeyService.GenerateApiKey();
_context.Users.Update(user);
_context.SaveChanges();
return user.ApiKey;
}
public Dictionary<string, int> GetAllApiKeys()
{
return _context.Users
@ -157,18 +106,6 @@ public class UserService : IUserService
.ToDictionary(u => u.ApiKey, u => u.Id);
}
public string GetUserApiKey(int id)
{
return this.getUser(id).ApiKey;
}
public void InvalidateApiKey(string apiKey)
{
User? user = _context.Users.FirstOrDefault(u => u.ApiKey == apiKey);
if (user is not null)
user.ApiKey = null;
}
// helper methods
@ -178,4 +115,32 @@ public class UserService : IUserService
if (user == null) throw new KeyNotFoundException("User not found");
return user;
}
private User getUser(string ApiKey)
{
var user = _context.Users
.Where(u => u.ApiKey == ApiKey)
.FirstOrDefault();
if (user == null) throw new KeyNotFoundException("User not found");
return user;
}
private const string _prefix = "CT-";
private const int _numberOfSecureBytesToGenerate = 32;
private const int _lengthOfKey = 32;
private string generateApiKey()
{
var bytes = RandomNumberGenerator.GetBytes(_numberOfSecureBytesToGenerate);
string base64String = Convert.ToBase64String(bytes)
.Replace("+", "-")
.Replace("/", "_");
var keyLength = _lengthOfKey - _prefix.Length;
return _prefix + base64String[..keyLength];
}
}

View File

@ -1,49 +0,0 @@
using System;
using AAIntegration.SimmonsBank.API.Configs;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using AAIntegration.SimmonsBank.API.Processes;
using AAIntegration.SimmonsBank.API.Services;
namespace AAIntegration.SimmonsBank.API.Workers;
public class EnvelopeFundWorker : BackgroundService
{
private readonly EnvelopeFundConfig _config;
private readonly IEnvelopeFundingProcess _envelopeFundingProcess;
private readonly ILogger<EnvelopeFundWorker> _logger;
private readonly IServiceScopeFactory _serviceScopeFactory;
public EnvelopeFundWorker(IOptions<EnvelopeFundConfig> config, IEnvelopeFundingProcess envelopeFundingProcess, ILogger<EnvelopeFundWorker> logger, IServiceScopeFactory serviceScopeFactory)
{
_config = config.Value;
_envelopeFundingProcess = envelopeFundingProcess;
_logger = logger;
_serviceScopeFactory = serviceScopeFactory;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
DateTime? lastExecutedOn = null;
using (var scope = _serviceScopeFactory.CreateScope())
{
IEnvelopeService envelopeService = scope.ServiceProvider.GetService<IEnvelopeService>();
// This is how we keep the app running (in the background)
while (!stoppingToken.IsCancellationRequested)
{
if (lastExecutedOn != null)
{
int minutesRemaining = _config.CheckIntervalInMinutes - (int)DateTime.UtcNow.Subtract(lastExecutedOn.Value).TotalMinutes;
await Task.Delay(TimeSpan.FromMinutes(minutesRemaining < 0 ? 0 : minutesRemaining), stoppingToken);
}
lastExecutedOn = DateTime.UtcNow;
_logger.LogInformation("EnvelopeFundWorker running at: {time}", DateTimeOffset.Now);
await _envelopeFundingProcess.FundEnvelopes(envelopeService);
}
}
}
}

View File

@ -5,7 +5,7 @@
"Name": "AAISB_DB",
"User": "postgres",
"Password": "nqA3UV3CliLLHpLL",
"Port": "15432"
"Port": "25432"
},
"AllowedHosts": [
"*"

View File

@ -5,7 +5,7 @@ services:
container_name: aa-integration-simmonsbank-pg-db
image: 'postgres:15'
ports:
- 15432:5432
- 25432:5432
env_file:
- .env
networks:
@ -18,7 +18,7 @@ services:
container_name: aa-integration-simmonsbank-pg-admin
image: 'dpage/pgadmin4:7.1'
ports:
- 15433:80
- 25433:80
env_file:
- .env
depends_on:
@ -30,4 +30,4 @@ services:
networks:
postgres-network:
driver: bridge
driver: bridge