Publish from private repository

This commit is contained in:
Gitea Actions
2026-08-01 11:57:50 +00:00
commit 10d87c4ff1
694 changed files with 69367 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
namespace MyOffice.Core;
public class Error
{
private Exception? _exception;
public Error(string message)
{
Message = message;
}
public Error(Exception exception): this(exception.GetType().Name)
{
_exception = exception;
}
public Error(string message, Exception exception): this(message)
{
_exception = exception;
}
public string Message { get; private set;}
}
+106
View File
@@ -0,0 +1,106 @@
namespace MyOffice.Core;
public enum GeneralExecStatus
{
success,
failure,
not_found,
forbidden
}
public class Exec<TResult> : Exec<TResult, GeneralExecStatus>
where TResult : class
{
public Exec(TResult result, GeneralExecStatus status) : base(result, status)
{
}
public Exec(GeneralExecStatus status) : base(status)
{
}
public Exec() : base(GeneralExecStatus.success)
{
}
public new Exec<TResult> Set(GeneralExecStatus status)
{
Status = status;
return this;
}
public new Exec<TResult> Set(TResult? result)
{
Result = result;
Status = result == null ? GeneralExecStatus.failure : GeneralExecStatus.success;
return this;
}
}
public class Exec<TResult, TStatus>
where TResult : class
where TStatus : Enum
{
public static Exec<TResult, TStatus> Start(TResult result, TStatus status)
{
return new Exec<TResult, TStatus>(result, status);
}
public static Exec<TResult, TStatus> Start(TStatus status)
{
return new Exec<TResult, TStatus>(status);
}
public static Exec<TResult, GeneralExecStatus> StartSuccess()
{
return new Exec<TResult, GeneralExecStatus>(GeneralExecStatus.success);
}
public static Exec<TResult, GeneralExecStatus> StartFailure()
{
return new Exec<TResult, GeneralExecStatus>(GeneralExecStatus.failure);
}
public static Exec<TResult, GeneralExecStatus> StartNotFound()
{
return new Exec<TResult, GeneralExecStatus>(GeneralExecStatus.not_found);
}
public Exec(TResult result, TStatus status)
{
Result = result;
Status = status;
}
public Exec(TStatus status)
{
Status = status;
}
public TResult? Result { get; internal set; }
public TStatus Status { get; internal set; }
public Exec<TResult, TStatus> Set(TResult result, TStatus status)
{
Result = result;
Status = status;
return this;
}
public Exec<TResult, TStatus> Set(TStatus status)
{
Status = status;
return this;
}
public Exec<TResult, TStatus> Set(TResult result)
{
Result = result;
return this;
}
}
@@ -0,0 +1,14 @@
namespace MyOffice.Core.Extensions;
public static class BoolExtensions
{
public static string ToLowerCase(this bool value)
{
return value.ToString().ToLower();
}
public static string? ToLowerCase(this bool? value)
{
return value == null ? null : value.ToString()?.ToLower();
}
}
@@ -0,0 +1,31 @@
namespace MyOffice.Core.Extensions;
using System.Security.Claims;
public static class ClaimsExtensions
{
public static string? GetValue(this IEnumerable<Claim> claims, string type)
{
return claims.FirstOrDefault(x => x.Type.Equals(type, StringComparison.OrdinalIgnoreCase))?.Value;
}
public static string? GetValue(this IEnumerable<Claim> claims, string[] types)
{
return claims.FirstOrDefault(x => types.Any(z => x.Type.Equals(z, StringComparison.OrdinalIgnoreCase)))?.Value;
}
public static string? GetEmail(this IEnumerable<Claim> claims)
{
return GetValue(claims, new[] { ClaimTypes.Email, "email" });
}
public static string? GetNameIdentifier(this IEnumerable<Claim> claims)
{
return GetValue(claims, ClaimTypes.NameIdentifier);
}
public static string? GetSID(this IEnumerable<Claim> claims)
{
return GetValue(claims, "sid");
}
}
@@ -0,0 +1,19 @@
namespace MyOffice.Core.Extensions;
public static class DateTimeExtensions
{
public static DateTime StartOfDay(this DateTime dateTime)
{
return dateTime.Date;
}
public static DateTime EndOfDay(this DateTime dateTime)
{
return dateTime.AddDays(1).AddTicks(-1);
}
public static DateTime ToUtc(this DateTime dateTime)
{
return new DateTime(dateTime.Ticks, DateTimeKind.Utc);
}
}
@@ -0,0 +1,19 @@
namespace MyOffice.Core.Extensions;
public static class GuidExtensions
{
public static bool EqualsString(this Guid guid, string str)
{
return guid.ToString().EqualsIgnoreCase(str);
}
public static string ToShort(this Guid guid)
{
return guid.ToString("N");
}
public static string? ToShort(this Guid? guid)
{
return guid?.ToString("N");
}
}
@@ -0,0 +1,65 @@
namespace MyOffice.Core.Extensions;
using Microsoft.Extensions.Logging;
public static class StringExtensions
{
public static bool IsMissing(this string? str)
{
return str == null || string.IsNullOrEmpty(str) || string.IsNullOrEmpty(str.Trim());
}
public static bool IsPresent(this string? str)
{
return !IsMissing(str);
}
public static string? NullIfEmpty(this string? str)
{
return IsMissing(str) ? null : str;
}
public static bool EqualsIgnoreCase(this string? str, string? value)
{
return str != null && str.Equals(value, StringComparison.OrdinalIgnoreCase);
}
public static string? SafeTrim(this string? str)
{
return str == null ? str : str!.Trim();
}
public static string? MaxOf(this string? str, int maxLength)
{
if (str == null)
{
return null;
}
if (str.Length < maxLength)
{
return str;
}
return str.Substring(0, maxLength);
}
public static bool AsBool(this string? str, bool defaultValue = false)
{
return true.ToString().Equals(str, StringComparison.OrdinalIgnoreCase) || defaultValue;
}
public static Guid AsGuid(this string str)
{
return Guid.Parse(str);
}
public static Guid? AsGuidNull(this string? str)
{
if (Guid.TryParse(str, out var guid))
{
return guid;
}
return null;
}
}
+31
View File
@@ -0,0 +1,31 @@
namespace MyOffice.Core.Helpers
{
using System.Text.Json;
using System.Text.Json.Serialization;
public static class JsonHelper
{
public static string ToJson(this object entity, JsonSerializerOptions? options = null)
{
options ??= new JsonSerializerOptions
{
MaxDepth = 0,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
ReferenceHandler = ReferenceHandler.IgnoreCycles,
WriteIndented = true,
};
return JsonSerializer.Serialize(entity, options);
}
}
/*public class CustomIgnoreReferenceHandler : ReferenceHandler
{
//public CustomIgnoreReferenceHandler() => HandlingStrategy = ReferenceHandlingStrategy.IgnoreCycles;
public CustomIgnoreReferenceHandler()
{
new HandlingStrategy { } = true;
}
public override ReferenceResolver CreateResolver() => new IgnoreReferenceResolver();
}*/
}
@@ -0,0 +1,18 @@
namespace MyOffice.Core.Helpers;
using MyOffice.Core.Extensions;
public class RandomizationHelper
{
public static string Generate(int length)
{
var result = "";
while(result.Length < length)
{
result += Guid.NewGuid().ToShort();
}
return result.Substring(0, length);
}
}
@@ -0,0 +1,47 @@
namespace MyOffice.Core.Identity;
using System;
using System.Diagnostics.Contracts;
public interface IExternalProviderValidator
{
string Provider { get; }
public bool IsConfigured { get; }
Task<ExternalProviderValidatorResult> ValidateAsync(string token);
}
public class ExternalProviderValidatorResult
{
public static ExternalProviderValidatorResult Failed()
{
return new ExternalProviderValidatorResult();
}
public static ExternalProviderValidatorResult Success(string email, bool emailVerified, string externalId,
string? fullName)
{
return new ExternalProviderValidatorResult(email, emailVerified, externalId, fullName);
}
public ExternalProviderValidatorResult()
{
IsSuccessed = false;
}
public ExternalProviderValidatorResult(string email, bool emailVerified, string externalId, string? fullName) :
this()
{
Email = email;
EmailVerified = emailVerified;
IsSuccessed = true;
ExternalId = externalId;
FullName = fullName;
}
public bool IsSuccessed { get; }
public string? Email { get; }
public bool EmailVerified { get; }
public string? ExternalId { get; }
public string? FullName { get; }
}
+6
View File
@@ -0,0 +1,6 @@
namespace MyOffice.Core;
public interface IDataModel
{
}
@@ -0,0 +1,6 @@
namespace MyOffice.Core;
public interface IDataModelDto<TSource> where TSource : IDataModel
{
}
+13
View File
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
</ItemGroup>
</Project>
+51
View File
@@ -0,0 +1,51 @@
namespace MyOffice.Data.Models.Accounts;
using Currencies;
using MyOffice.Core;
using MyOffice.Data.Models.Users;
public class Account: IDataModel
{
public Guid Id { get; set; }
public string CurrencyGlobalId { get; set; } = null!;
public CurrencyGlobal? CurrencyGlobal { get; set; }
public Guid? OwnerId { get; set; }
public User? Owner { get; set; }
public string Name { get; set; } = null!;
public IEnumerable<AccountAccess>? AccessRights { get; set; }
public IEnumerable<Motion>? Motions { get; set; }
public IEnumerable<AccountAccountCategory>? Categories { get; set; }
public IEnumerable<AccountAccessInvite>? Invites { get; set; }
}
public class AccountDetailed: IDataModel
{
public Account Account { get; set; } = null!;
public decimal TotalPlus { get; set; }
public decimal TotalMinus { get; set; }
public decimal Rest => TotalPlus - TotalMinus;
}
public class AccountSimple
{
public Guid Id { get; set; }
public string Name { get; set; } = null!;
public AccountAccessTypeEnum Type { get; set; }
public string? CurrencyName { get; set; }
public string? CurrencyShortName { get; set; }
public decimal? CurrencyRate { get; set; }
public int? CurrencyQuantity { get; set; }
public decimal? TotalPlus { get; set; }
public decimal? TotalMinus { get; set; }
public decimal? Balance { get; set; }
}
public class MotionTotalSimple
{
public Guid? Id { get; set; }
public string Name { get; set; } = null!;
public string CurrencyId { get; set; } = null!;
public string CurrencyName { get; set; } = null!;
public decimal CurrencyRate { get; set; }
public decimal Amount { get; set; }
}
@@ -0,0 +1,28 @@
namespace MyOffice.Data.Models.Accounts;
using MyOffice.Data.Models.Users;
public enum AccountAccessTypeEnum
{
balance,
credit,
external,
other,
}
public class AccountAccess
{
public int Id { get; set; }
public Guid AccountId { get; set; }
public Account? Account { get; set; }
public Guid UserId { get; set; }
public User? User { get; set; }
public Guid OwnerId { get; set; }
public User? Owner { get; set; }
public bool IsAllowRead { get; set; }
public bool IsAllowWrite { get; set; }
public bool IsAllowManage { get; set; }
public AccountAccessTypeEnum Type { get; set; }
public string? Name { get; set; }
}
@@ -0,0 +1,17 @@
namespace MyOffice.Data.Models.Accounts;
using Users;
public class AccountAccessInvite
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public User? User { get; set; }
public Guid AccountId { get; set; }
public Account? Account { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime? AcceptedOn { get; set; }
public DateTime? RejectedOn { get; set; }
public string Email { get; set; } = null!;
public bool IsAllowWrite { get; set; }
}
@@ -0,0 +1,10 @@
namespace MyOffice.Data.Models.Accounts;
public class AccountAccountCategory
{
public int Id { get; set; }
public Guid AccountId { get; set; }
public Account Account { get; set; } = null!;
public Guid CategoryId { get; set; }
public AccountCategory Category { get; set; } = null!;
}
@@ -0,0 +1,12 @@
namespace MyOffice.Data.Models.Accounts;
using MyOffice.Data.Models.Users;
public class AccountCategory
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public User? User { get; set; }
public string Name { get; set; } = null!;
public IEnumerable<AccountAccountCategory>? Accounts { get; set; }
}
@@ -0,0 +1,10 @@
namespace MyOffice.Data.Models.Accounts.Domain;
using Currencies;
public class AccountWithRate
{
public Account Account { get; set; } = null!;
public Currency? Currency { get; set; }
public CurrencyRate? Rate { get; set; }
}
+22
View File
@@ -0,0 +1,22 @@
namespace MyOffice.Data.Models.Accounts;
using Items;
/// <summary>
/// Account motion
/// DateTime: 2023-01-01, Account: 'Debit card', Item.ItemGlobal: 'Primary salary', AmountPlus: 5000
/// </summary>
public class Motion
{
public Guid Id { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime DateTime { get; set; }
public Guid AccountId { get; set; }
public Account Account { get; set; } = null!;
public int ItemId { get; set; }
public Item Item { get; set; } = null!;
public string? Description { get; set; }
public decimal AmountPlus { get; set; }
public decimal AmountMinus { get; set; }
public DateTime? DeletedOn { get; set; }
}
@@ -0,0 +1,21 @@
namespace MyOffice.Data.Models.Currencies;
using MyOffice.Data.Models.Users;
public class Currency
{
public Guid Id { get; set; }
public string CurrencyGlobalId { get; set; } = null!;
public CurrencyGlobal? CurrencyGlobal { get; set; }
public Guid UserId { get; set; }
public User? User { get; set; }
public string Name { get; set; } = null!;
public string ShortName { get; set; } = null!;
public IEnumerable<CurrencyRate>? Rates { get; set; }
public int? CurrentRateId { get; set; }
public CurrencyRate? CurrentRate { get; set; }
public bool IsPrimary { get; set; }
}
@@ -0,0 +1,26 @@
namespace MyOffice.Data.Models.Currencies;
using MyOffice.Data.Models.Accounts;
public enum CurrencyGlobalIdEnum
{
UAH,
USD,
EUR,
GBP,
RUB,
BTC,
ETH,
TON,
OTHER,
}
public class CurrencyGlobal
{
public string Id { get; set; } = null!;
public string Name { get; set; } = null!;
public string Symbol { get; set; } = null!;
public int DefaultQuantity { get; set; }
public IEnumerable<Currency>? Currencies { get; set; }
public IEnumerable<Account>? Accounts { get; set; }
}
@@ -0,0 +1,12 @@
namespace MyOffice.Data.Models.Currencies;
public class CurrencyRate
{
public int Id { get; set; }
public Guid CurrencyId { get; set; }
public Currency? Currency { get; set; }
public DateTime DateTime { get; set; }
public int Quantity { get; set; }
public decimal Rate { get; set; }
public IEnumerable<Currency>? Currencies { get; set; }
}
+20
View File
@@ -0,0 +1,20 @@
namespace MyOffice.Data.Models.Items;
using MyOffice.Data.Models.Accounts;
/// <summary>
/// User 'Item' linked to global item
/// ItemGlobal: 'Primary salary', ItemCategory: 'Incomes'
/// </summary>
public class Item
{
public int Id { get; set; }
/// <summary>
/// UnCategorized category is CategoryId = UserId
/// </summary>
public Guid CategoryId { get; set; }
public ItemCategory? Category { get; set; }
public Guid ItemGlobalId { get; set; }
public ItemGlobal ItemGlobal { get; set; } = null!;
public List<Motion>? Motions { get; set; }
}
@@ -0,0 +1,13 @@
namespace MyOffice.Data.Models.Items;
using MyOffice.Data.Models.Users;
public class ItemCategory
{
public Guid Id { get; set; }
public Guid UserId { get; set; }
public User User { get; set; } = null!;
public string Name { get; set; } = null!;
public List<Item> Items { get; set; } = null!;
public bool IsInternal { get; set; }
}
+8
View File
@@ -0,0 +1,8 @@
namespace MyOffice.Data.Models.Items;
public class ItemGlobal
{
public Guid Id { get; set; }
public string Name { get; set; } = null!;
public IEnumerable<Item> Items { get; set; } = null!;
}
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MyOffice.Core\MyOffice.Core.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,17 @@
namespace MyOffice.Data.Models.Notifications;
public enum EmailTemplateEnum
{
PasswordRestore,
}
public class EmailTemplate
{
public string Id { get; set; }
public DateTime CreatedOn { get; set; }
public string Description { get; set; }
public string Subject { get; set; }
public string Sender { get; set; }
public string SenderName { get; set; }
public string Template { get; set; }
}
+35
View File
@@ -0,0 +1,35 @@
namespace MyOffice.Data.Models.Users;
using Accounts;
using Currencies;
using Items;
public class User
{
public User()
{
CurrencyId = "USD";
}
public Guid Id { get; set; }
public string UserName { get; set; } = null!;
public string Email { get; set; } = null!;
public string PasswordHash { get; set; } = null!;
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? FullName { get; set; }
public string? Phone { get; set; }
public bool IsEmailConfirmed { get; set; }
public IEnumerable<UserExternal>? UserClaims { get; set; }
public string CurrencyId { get; set; }
public CurrencyGlobal? Currency { get; set; }
public IEnumerable<Currency>? Currencies { get; set; }
public IEnumerable<AccountAccess>? AccountAccess { get; set; }
public IEnumerable<Motion>? AccountMotions { get; set; }
public IEnumerable<AccountCategory>? AccountCategories { get; set; }
public IEnumerable<ItemCategory>? ItemCategories { get; set; }
public IEnumerable<Account>? Accounts { get; set; }
public IEnumerable<AccountAccess>? AccountAccessOwners { get; set; }
public IEnumerable<AccountAccessInvite>? AccountAccessInvites { get; set; }
}
@@ -0,0 +1,12 @@
namespace MyOffice.Data.Models.Users;
public class UserExternal
{
public int Id { get; set; }
public DateTime CreatedOn { get; set; }
public Guid UserId { get; set; }
public User User { get; set; } = null!;
public string ExternalId { get; set; } = null!;
public string Email { get; set; } = null!;
public string Provider { get; set; } = null!;
}
@@ -0,0 +1,18 @@
namespace MyOffice.Data.Models.Verifications;
using MyOffice.Data.Models.Users;
public class VerificationCode
{
public int Id { get; set; }
public Guid UserId { get; set; }
public User? User { get; set; }
public string Code { get; set; } = null!;
public string DestinationType { get; set; } = null!;
public string Destination { get; set; } = null!;
public DateTime CreatedOn { get; set; }
public DateTime ExpiresOn { get; set; }
public DateTime? VerifiedOn { get; set; }
public string Template { get; set; } = null!;
public string? Metadata { get; set; }
}
@@ -0,0 +1,7 @@
namespace MyOffice.Data.Models.Verifications;
public enum VerificationCodeTemplateEnum
{
password_restore,
email_confirm,
}
@@ -0,0 +1,7 @@
namespace MyOffice.Data.Models.Verifications;
public enum VerificationCodeTypeEnum
{
email,
phone,
}
@@ -0,0 +1,81 @@
namespace MyOffice.Data.Repositories.Account;
using Microsoft.EntityFrameworkCore;
using Models.Accounts;
using MyOffice.Data.Repositories;
using MyOffice.DbContext;
public class AccountAccessInviteRepository : AppRepository<AccountAccessInvite>, IAccountAccessInviteRepository
{
public AccountAccessInviteRepository(AppDbContext context) : base(context)
{
}
public AccountAccessInvite? Get(Guid userId, string email)
{
return _context.AccountAccessInvites
.FirstOrDefault(x => x.UserId == userId
&& x.Email == email
&& !x.AcceptedOn.HasValue
&& !x.RejectedOn.HasValue
);
}
public async Task<AccountAccessInvite?> GetAsync(Guid userId, string email, CancellationToken cancellationToken = default)
{
return await _context.AccountAccessInvites
.FirstOrDefaultAsync(x => x.UserId == userId
&& x.Email == email
&& !x.AcceptedOn.HasValue
&& !x.RejectedOn.HasValue,
cancellationToken);
}
public bool Add(AccountAccessInvite invite)
{
return AddBase(invite) > 0;
}
public async Task<bool> AddAsync(AccountAccessInvite invite, CancellationToken cancellationToken = default)
{
return await AddBaseAsync(invite, cancellationToken) > 0;
}
public bool Update(AccountAccessInvite invite)
{
return UpdateBase(invite) > 0;
}
public async Task<bool> UpdateAsync(AccountAccessInvite invite, CancellationToken cancellationToken = default)
{
return await UpdateBaseAsync(invite, cancellationToken) > 0;
}
public IEnumerable<AccountAccessInvite> GetActive(string email)
{
return _context
.AccountAccessInvites
.Include(x => x.Account)
.Where(x => x.Email == email && !x.AcceptedOn.HasValue && !x.RejectedOn.HasValue);
}
public async Task<List<AccountAccessInvite>> GetActiveAsync(string email, CancellationToken cancellationToken = default)
{
return await _context
.AccountAccessInvites
.Include(x => x.Account)
.Where(x => x.Email == email && !x.AcceptedOn.HasValue && !x.RejectedOn.HasValue)
.ToListAsync(cancellationToken);
}
public AccountAccessInvite? Get(Guid id)
{
return _context.AccountAccessInvites.FirstOrDefault(x => x.Id == id);
}
public async Task<AccountAccessInvite?> GetAsync(Guid id, CancellationToken cancellationToken = default)
{
return await _context.AccountAccessInvites.FirstOrDefaultAsync(x => x.Id == id, cancellationToken);
}
}
@@ -0,0 +1,42 @@
namespace MyOffice.Data.Repositories.Account;
using Models.Accounts;
using MyOffice.Data.Repositories;
using MyOffice.DbContext;
public class AccountAccessRepository : AppRepository<AccountAccess>, IAccountAccessRepository
{
public AccountAccessRepository(AppDbContext context) : base(context)
{
}
public bool Add(AccountAccess accountAccess)
{
return AddBase(accountAccess) > 0;
}
public async Task<bool> AddAsync(AccountAccess accountAccess, CancellationToken cancellationToken = default)
{
return await AddBaseAsync(accountAccess, cancellationToken) > 0;
}
public bool Update(AccountAccess accountAccess)
{
return UpdateBase(accountAccess) > 0;
}
public async Task<bool> UpdateAsync(AccountAccess accountAccess, CancellationToken cancellationToken = default)
{
return await UpdateBaseAsync(accountAccess, cancellationToken) > 0;
}
public bool Delete(AccountAccess accountAccess)
{
return RemoveBase(accountAccess) > 0;
}
public async Task<bool> DeleteAsync(AccountAccess accountAccess, CancellationToken cancellationToken = default)
{
return await RemoveBaseAsync(accountAccess, cancellationToken) > 0;
}
}
@@ -0,0 +1,55 @@
namespace MyOffice.Data.Repositories.Account;
using Microsoft.EntityFrameworkCore;
using Models.Accounts;
using MyOffice.DbContext;
public class AccountAccountCategoryRepository : AppRepository<AccountAccountCategory>, IAccountAccountCategoryRepository
{
public AccountAccountCategoryRepository(AppDbContext context) : base(context)
{
}
public List<AccountAccountCategory> Get(Guid userId, Guid accountId, Guid categoryId)
{
return _context.AccountAccountCategories
.Include(x => x.Account)
.Include(x => x.Category)
.Where(x => x.AccountId == accountId && x.CategoryId == categoryId && x.Category.UserId == userId)
.ToList();
}
public async Task<List<AccountAccountCategory>> GetAsync(
Guid userId,
Guid accountId,
Guid categoryId,
CancellationToken cancellationToken = default
)
{
return await _context.AccountAccountCategories
.Include(x => x.Account)
.Include(x => x.Category)
.Where(x => x.AccountId == accountId && x.CategoryId == categoryId && x.Category.UserId == userId)
.ToListAsync(cancellationToken);
}
public bool Remove(AccountAccountCategory accountAccountCategory)
{
return RemoveBase(accountAccountCategory) > 0;
}
public async Task<bool> RemoveAsync(AccountAccountCategory accountAccountCategory, CancellationToken cancellationToken = default)
{
return await RemoveBaseAsync(accountAccountCategory, cancellationToken) > 0;
}
public bool Add(AccountAccountCategory accountAccountCategory)
{
return AddBase(accountAccountCategory) > 0;
}
public async Task<bool> AddAsync(AccountAccountCategory accountAccountCategory, CancellationToken cancellationToken = default)
{
return await AddBaseAsync(accountAccountCategory, cancellationToken) > 0;
}
}
@@ -0,0 +1,73 @@
namespace MyOffice.Data.Repositories.Account;
using Microsoft.EntityFrameworkCore;
using Models.Accounts;
using MyOffice.Data.Repositories;
using MyOffice.DbContext;
public class AccountCategoryRepository : AppRepository<AccountCategory>, IAccountCategoryRepository
{
public AccountCategoryRepository(AppDbContext context) : base(context)
{
}
public List<AccountCategory> GetAll(Guid userId)
{
return _context.AccountCategories
.Include(x => x.Accounts)
.Where(x => x.UserId == userId)
.ToList();
}
public async Task<List<AccountCategory>> GetAllAsync(Guid userId, CancellationToken cancellationToken = default)
{
return await _context.AccountCategories
.Include(x => x.Accounts)
.Where(x => x.UserId == userId)
.ToListAsync(cancellationToken);
}
public bool Add(AccountCategory accountCategory)
{
return AddBase(accountCategory) > 0;
}
public async Task<bool> AddAsync(AccountCategory accountCategory, CancellationToken cancellationToken = default)
{
return await AddBaseAsync(accountCategory, cancellationToken) > 0;
}
public AccountCategory? Get(Guid userId, Guid id)
{
return _context.AccountCategories
.Include(x => x.Accounts)
.FirstOrDefault(x => x.Id == id && x.UserId == userId);
}
public async Task<AccountCategory?> GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default)
{
return await _context.AccountCategories
.Include(x => x.Accounts)
.FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId, cancellationToken);
}
public bool Update(AccountCategory accountCategory)
{
return UpdateBase(accountCategory) > 0;
}
public async Task<bool> UpdateAsync(AccountCategory accountCategory, CancellationToken cancellationToken = default)
{
return await UpdateBaseAsync(accountCategory, cancellationToken) > 0;
}
public bool Remove(AccountCategory accountCategory)
{
return RemoveBase(accountCategory) > 0;
}
public async Task<bool> RemoveAsync(AccountCategory accountCategory, CancellationToken cancellationToken = default)
{
return await RemoveBaseAsync(accountCategory, cancellationToken) > 0;
}
}
@@ -0,0 +1,641 @@
namespace MyOffice.Data.Repositories.Account;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Models.Accounts;
using MyOffice.Data.Models.Accounts.Domain;
using MyOffice.Data.Models.Currencies;
using MyOffice.Data.Repositories;
using MyOffice.DbContext;
public class AccountRepository : AppRepository<Account>, IAccountRepository
{
private readonly ILogger<AccountRepository> _logger;
public AccountRepository(
AppDbContext context,
ILogger<AccountRepository> logger
) : base(context)
{
_logger = logger;
}
public List<Account> GetAll(Guid userId)
{
return _context.Accounts!
.Include(x => x.CurrencyGlobal)
// categories created with current user
.Include(x => x.Categories!.Where(c => c.Category.UserId == userId))!
.ThenInclude(x => x.Category)
// access rights created with current user
.Include(x => x.AccessRights!.Where(a => a.OwnerId == userId))!
.ThenInclude(x => x.User)
// require only one motions to check if can to delete account
.Include(x => x.Motions!.Take(1))!
// only accounts with access to current user
.Where(x => x.AccessRights!.Any(a => a.UserId == userId))
.ToList();
}
public async Task<List<Account>> GetAllAsync(Guid userId, CancellationToken cancellationToken = default)
{
return await _context.Accounts!
.Include(x => x.CurrencyGlobal)
// categories created with current user
.Include(x => x.Categories!.Where(c => c.Category.UserId == userId))!
.ThenInclude(x => x.Category)
// access rights created with current user
.Include(x => x.AccessRights!.Where(a => a.OwnerId == userId))!
.ThenInclude(x => x.User)
// require only one motions to check if can to delete account
.Include(x => x.Motions!.Take(1))!
// only accounts with access to current user
.Where(x => x.AccessRights!.Any(a => a.UserId == userId))
.ToListAsync(cancellationToken);
}
public List<Account> GetByCategory(Guid userId, Guid categoryId)
{
return _context.Accounts!
.Include(x => x.CurrencyGlobal)
.Include(x => x.Categories)!
.ThenInclude(x => x.Category)
.Include(x => x.AccessRights)!
.ThenInclude(x => x.User)
.Include(x => x.Motions)!
.Where(x => x.Categories!.Any(c => c.CategoryId == categoryId) && x.AccessRights!.Any(a => a.UserId == userId))
.ToList();
}
public async Task<List<Account>> GetByCategoryAsync(Guid userId, Guid categoryId, CancellationToken cancellationToken = default)
{
return await _context.Accounts!
.Include(x => x.CurrencyGlobal)
.Include(x => x.Categories)!
.ThenInclude(x => x.Category)
.Include(x => x.AccessRights)!
.ThenInclude(x => x.User)
.Include(x => x.Motions)!
.Where(x => x.Categories!.Any(c => c.CategoryId == categoryId) && x.AccessRights!.Any(a => a.UserId == userId))
.ToListAsync(cancellationToken);
}
public List<AccountDetailed> GetByCategoryDetailed(Guid userId, Guid categoryId)
{
return _context.Accounts!
.Include(x => x.CurrencyGlobal)
.Include(x => x.Categories)!
.ThenInclude(x => x.Category)
.Include(x => x.AccessRights)!
.ThenInclude(x => x.User)
.Where(x => x.Categories!.Any(c => c.CategoryId == categoryId) && x.AccessRights!.Any(a => a.UserId == userId))
.Select(x => new AccountDetailed
{
Account = x,
TotalPlus = x.Motions!.Sum(m => m.AmountPlus),
TotalMinus = x.Motions!.Sum(m => m.AmountMinus),
})
.ToList();
}
public Task<List<AccountDetailed>> GetByCategoryDetailedAsync(
Guid userId,
Guid categoryId,
CancellationToken cancellationToken = default
)
{
return _context.Accounts!
.Include(x => x.CurrencyGlobal)
.Include(x => x.Categories)!
.ThenInclude(x => x.Category)
.Include(x => x.AccessRights)!
.ThenInclude(x => x.User)
.Where(x => x.Categories!.Any(c => c.CategoryId == categoryId) && x.AccessRights!.Any(a => a.UserId == userId))
.Select(x => new AccountDetailed
{
Account = x,
TotalPlus = x.Motions!.Sum(m => m.AmountPlus),
TotalMinus = x.Motions!.Sum(m => m.AmountMinus),
})
.ToListAsync(cancellationToken);
}
public AccountDetailed? GetByIdDetailed(Guid userId, Guid id)
{
return _context.Accounts!
.Include(x => x.CurrencyGlobal)
.Include(x => x.Categories)!
.ThenInclude(x => x.Category)
.Include(x => x.AccessRights)!
.ThenInclude(x => x.User)
.Where(x => x.Id == id && x.AccessRights!.Any(a => a.UserId == userId))
.Select(x => new AccountDetailed
{
Account = x,
TotalPlus = x.Motions!.Sum(m => m.AmountPlus),
TotalMinus = x.Motions!.Sum(m => m.AmountMinus),
})
.FirstOrDefault();
}
public Task<AccountDetailed?> GetByIdDetailedAsync(
Guid userId,
Guid id,
CancellationToken cancellationToken = default
)
{
return _context.Accounts!
.Include(x => x.CurrencyGlobal)
.Include(x => x.Categories)!
.ThenInclude(x => x.Category)
.Include(x => x.AccessRights)!
.ThenInclude(x => x.User)
.Where(x => x.Id == id && x.AccessRights!.Any(a => a.UserId == userId))
.Select(x => new AccountDetailed
{
Account = x,
TotalPlus = x.Motions!.Sum(m => m.AmountPlus),
TotalMinus = x.Motions!.Sum(m => m.AmountMinus),
})
.FirstOrDefaultAsync(cancellationToken);
}
public bool Add(Account account)
{
return AddBase(account) > 0;
}
public async Task<bool> AddAsync(Account account, CancellationToken cancellationToken = default)
{
return await AddBaseAsync(account, cancellationToken) > 0;
}
public bool Delete(Account account)
{
return RemoveBase(account) > 0;
}
public async Task<bool> DeleteAsync(Account account, CancellationToken cancellationToken = default)
{
return await RemoveBaseAsync(account, cancellationToken) > 0;
}
public Account? Get(Guid userId, Guid id)
{
return _context.Accounts!
.Include(x => x.Categories!.Where(c => c.Category.UserId == userId))!
.ThenInclude(x => x.Category)
.Include(x => x.AccessRights)!
.ThenInclude(x => x.User)
//.Include(x => x.Motions)!
.FirstOrDefault(x => x.Id == id && x.AccessRights!.Any(r => r.UserId == userId));
}
public Task<Account?> GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default)
{
return _context.Accounts!
.Include(x => x.Categories!.Where(c => c.Category.UserId == userId))!
.ThenInclude(x => x.Category)
.Include(x => x.AccessRights)!
.ThenInclude(x => x.User)
.FirstOrDefaultAsync(
x => x.Id == id && x.AccessRights!.Any(r => r.UserId == userId),
cancellationToken);
}
public bool Update(Account account)
{
return UpdateBase(account) > 0;
}
public async Task<bool> UpdateAsync(Account account, CancellationToken cancellationToken = default)
{
return await UpdateBaseAsync(account, cancellationToken) > 0;
}
public bool Remove(Account account)
{
return RemoveBase(account) > 0;
}
public List<Account> FindAccounts(Guid userId, string term)
{
return _context.Accounts
.Where(x => x.AccessRights!.Any(a => a.UserId == userId))
.Where(x => x.Name.ToLower().Contains(term.ToLower()))
.ToList();
}
public async Task<List<Account>> FindAccountsAsync(Guid userId, string term, CancellationToken cancellationToken = default)
{
return await _context.Accounts
.Where(x => x.AccessRights!.Any(a => a.UserId == userId))
.Where(x => x.Name.ToLower().Contains(term.ToLower()))
.ToListAsync(cancellationToken);
}
public List<AccountWithRate> GetAccountsWithRate(Guid userId, DateTime date)
{
var accounts = _context.Accounts
.Where(x => x.AccessRights!.Any(a => a.UserId == userId))
.ToList();
var currencyIds = accounts
.Select(x => x.CurrencyGlobalId)
.ToList();
var rates = _context.CurrencyRates
.Include(x => x.Currency)
.Where(x => x.Currency!.UserId == userId)
.Where(x => x.DateTime <= date)
.Where(x => currencyIds.Contains(x.Currency!.CurrencyGlobalId))
.GroupBy(x => x.Currency!.CurrencyGlobalId)
.Select(x => x.OrderByDescending(r => r.DateTime).First())
.ToList();
return accounts
.Select(account =>
{
var rate = rates.FirstOrDefault(rate => rate.Currency!.CurrencyGlobalId == account.CurrencyGlobalId);
var result = new AccountWithRate
{
Account = account,
Currency = rate?.Currency,
Rate = rate,
};
return result;
})
.ToList();
}
public List<AccountSimple> GetRestAtDate(Guid userId, DateTime date)
{
return _context.AccountAccesses!
.Where(x => x.UserId == userId)
.Include(x => x.Account!)
.ThenInclude(x => x.CurrencyGlobal!)
.ThenInclude(x => x.Currencies!)
.ThenInclude(x => x.CurrentRate!)
.Include(x => x.Account)
.ThenInclude(x => x!.Motions)
.Select(x => new
{
Id = x.AccountId,
Name = x.Account!.Name,
Type = x.Type,
Currency = x.Account!.CurrencyGlobal!.Currencies!.FirstOrDefault(c => c.UserId == userId),
CurrentRate = x.Account!.CurrencyGlobal!.Currencies!.FirstOrDefault(c => c.UserId == userId)!.CurrentRate,
Plus = x.Account.Motions!
.Where(x => !x.DeletedOn.HasValue)
.Sum(m => m.AmountPlus),
Minus = x.Account.Motions!
.Where(x => !x.DeletedOn.HasValue)
.Sum(m => m.AmountMinus),
})
.ToList()
.Select(x => new AccountSimple
{
Id = x.Id,
Name = x.Name,
Type = x.Type,
CurrencyName = x.Currency?.Name,
CurrencyShortName = x.Currency?.ShortName,
CurrencyRate = x.CurrentRate?.Rate,
CurrencyQuantity = x.CurrentRate?.Quantity,
TotalMinus = x.Minus,
TotalPlus = x.Plus,
Balance = x.Plus - x.Minus,
})
.ToList();
}
public List<MotionTotalSimple> GetIncomeByCategories(Guid userId, DateTime from, DateTime to)
{
var accounts = GetAccountsWithRate(userId, to);
var accountIds = accounts.Select(x => x.Account.Id);
return _context.Motions
.Where(x => x.DateTime >= from && x.DateTime <= to)
.Where(x => accountIds.Contains(x.AccountId))
.Where(x => !x.Item.Category!.IsInternal)
.GroupBy(x => new
{
Id = x.Item.CategoryId,
Name = x.Item.Category!.Name,
IsUserCategory = x.Item.Category!.UserId == userId,
CurrencyId = x.Account.CurrencyGlobalId,
CurrencyName = x.Account.CurrencyGlobal!.Name,
})
.ToList()
.Select(x => new MotionTotalSimple
{
Id = x.Key.IsUserCategory ? x.Key.Id : userId,
Name = x.Key.Name,
CurrencyId = x.Key.CurrencyId,
CurrencyName = x.Key.CurrencyName,
Amount = x.Sum(a => a.AmountPlus),
})
.ToList();
}
public List<MotionTotalSimple> GetIncomeByCategory(Guid userId, Guid categoryId, DateTime from, DateTime to)
{
return _context.Motions
.Where(x => x.DateTime >= from && x.DateTime <= to)
.Where(x => x.Item.Category!.UserId == userId)
.Where(x => x.Item.CategoryId == categoryId)
.Where(x => !x.Item.Category!.IsInternal)
.Where(x => x.Item.Category!.UserId == userId)
.GroupBy(x => new
{
Id = x.Item.ItemGlobalId,
Name = x.Item.ItemGlobal!.Name,
CurrencyId = x.Account.CurrencyGlobalId,
CurrencyName = x.Account.CurrencyGlobal!.Name,
})
.Select(x => new MotionTotalSimple
{
Name = x.Key.Name,
CurrencyId = x.Key.CurrencyId,
CurrencyName = x.Key.CurrencyName,
Amount = x.Sum(a => a.AmountPlus),
})
.ToList();
}
public List<MotionTotalSimple> GetOutcomeByCategories(Guid userId, DateTime from, DateTime to)
{
var accounts = GetAccountsWithRate(userId, to);
var accountIds = accounts.Select(x => x.Account.Id);
return _context.Motions
.Where(x => x.DateTime >= from && x.DateTime <= to)
.Where(x => accountIds.Contains(x.AccountId))
.Where(x => !x.Item.Category!.IsInternal)
.GroupBy(x => new
{
Id = x.Item.CategoryId,
Name = x.Item.Category!.Name,
IsUserCategory = x.Item.Category!.UserId == userId,
CurrencyId = x.Account.CurrencyGlobalId,
CurrencyName = x.Account.CurrencyGlobal!.Name,
})
.Select(x => new MotionTotalSimple
{
Id = x.Key.IsUserCategory ? x.Key.Id : userId,
Name = x.Key.IsUserCategory ? x.Key.Name : "UnCategorized",
//Name = x.Key.Name,
CurrencyId = x.Key.CurrencyId,
CurrencyName = x.Key.CurrencyName,
Amount = x.Sum(a => a.AmountMinus),
}).ToList();
}
public List<MotionTotalSimple> GetOutcomeByCategory(Guid userId, Guid categoryId, DateTime from, DateTime to)
{
var accounts = GetAccountsWithRate(userId, to);
var accountIds = accounts.Select(x => x.Account.Id);
return _context.Motions
.Where(x => x.DateTime >= from && x.DateTime <= to)
.Where(x => accountIds.Contains(x.AccountId))
.Where(x => !x.Item.Category!.IsInternal)
.Where(x => x.Item.CategoryId == categoryId)
.GroupBy(x => new
{
Id = x.Item.ItemGlobalId,
Name = x.Item.ItemGlobal!.Name,
CurrencyId = x.Account.CurrencyGlobalId,
CurrencyName = x.Account.CurrencyGlobal!.Name,
})
.Select(x => new MotionTotalSimple
{
CurrencyId = x.Key.CurrencyId,
CurrencyName = x.Key.CurrencyName,
Name = x.Key.Name,
Amount = x.Sum(a => a.AmountMinus),
})
.ToList();
}
public async Task<List<AccountWithRate>> GetAccountsWithRateAsync(
Guid userId,
DateTime date,
CancellationToken cancellationToken = default
)
{
var accounts = await _context.Accounts
.Where(x => x.AccessRights!.Any(a => a.UserId == userId))
.ToListAsync(cancellationToken);
var currencyIds = accounts
.Select(x => x.CurrencyGlobalId)
.ToList();
var rates = await _context.CurrencyRates
.Include(x => x.Currency)
.Where(x => x.Currency!.UserId == userId)
.Where(x => x.DateTime <= date)
.Where(x => currencyIds.Contains(x.Currency!.CurrencyGlobalId))
.GroupBy(x => x.Currency!.CurrencyGlobalId)
.Select(x => x.OrderByDescending(r => r.DateTime).First())
.ToListAsync(cancellationToken);
return accounts
.Select(account =>
{
var rate = rates.FirstOrDefault(r => r.Currency!.CurrencyGlobalId == account.CurrencyGlobalId);
return new AccountWithRate
{
Account = account,
Currency = rate?.Currency,
Rate = rate,
};
})
.ToList();
}
public async Task<List<AccountSimple>> GetRestAtDateAsync(
Guid userId,
DateTime date,
CancellationToken cancellationToken = default
)
{
var rows = await _context.AccountAccesses!
.Where(x => x.UserId == userId)
.Include(x => x.Account!)
.ThenInclude(x => x.CurrencyGlobal!)
.ThenInclude(x => x.Currencies!)
.ThenInclude(x => x.CurrentRate!)
.Include(x => x.Account)
.ThenInclude(x => x!.Motions)
.Select(x => new
{
Id = x.AccountId,
Name = x.Account!.Name,
Type = x.Type,
Currency = x.Account!.CurrencyGlobal!.Currencies!.FirstOrDefault(c => c.UserId == userId),
CurrentRate = x.Account!.CurrencyGlobal!.Currencies!.FirstOrDefault(c => c.UserId == userId)!.CurrentRate,
Plus = x.Account.Motions!
.Where(m => !m.DeletedOn.HasValue)
.Sum(m => m.AmountPlus),
Minus = x.Account.Motions!
.Where(m => !m.DeletedOn.HasValue)
.Sum(m => m.AmountMinus),
})
.ToListAsync(cancellationToken);
return rows
.Select(x => new AccountSimple
{
Id = x.Id,
Name = x.Name,
Type = x.Type,
CurrencyName = x.Currency?.Name,
CurrencyShortName = x.Currency?.ShortName,
CurrencyRate = x.CurrentRate?.Rate,
CurrencyQuantity = x.CurrentRate?.Quantity,
TotalMinus = x.Minus,
TotalPlus = x.Plus,
Balance = x.Plus - x.Minus,
})
.ToList();
}
public async Task<List<MotionTotalSimple>> GetIncomeByCategoriesAsync(
Guid userId,
DateTime from,
DateTime to,
CancellationToken cancellationToken = default
)
{
var accounts = await GetAccountsWithRateAsync(userId, to, cancellationToken);
var accountIds = accounts.Select(x => x.Account.Id).ToList();
var groups = await _context.Motions
.Where(x => x.DateTime >= from && x.DateTime <= to)
.Where(x => accountIds.Contains(x.AccountId))
.Where(x => !x.Item.Category!.IsInternal)
.GroupBy(x => new
{
Id = x.Item.CategoryId,
Name = x.Item.Category!.Name,
IsUserCategory = x.Item.Category!.UserId == userId,
CurrencyId = x.Account.CurrencyGlobalId,
CurrencyName = x.Account.CurrencyGlobal!.Name,
})
.ToListAsync(cancellationToken);
return groups
.Select(x => new MotionTotalSimple
{
Id = x.Key.IsUserCategory ? x.Key.Id : userId,
Name = x.Key.Name,
CurrencyId = x.Key.CurrencyId,
CurrencyName = x.Key.CurrencyName,
Amount = x.Sum(a => a.AmountPlus),
})
.ToList();
}
public Task<List<MotionTotalSimple>> GetIncomeByCategoryAsync(
Guid userId,
Guid categoryId,
DateTime from,
DateTime to,
CancellationToken cancellationToken = default
)
{
return _context.Motions
.Where(x => x.DateTime >= from && x.DateTime <= to)
.Where(x => x.Item.Category!.UserId == userId)
.Where(x => x.Item.CategoryId == categoryId)
.Where(x => !x.Item.Category!.IsInternal)
.Where(x => x.Item.Category!.UserId == userId)
.GroupBy(x => new
{
Id = x.Item.ItemGlobalId,
Name = x.Item.ItemGlobal!.Name,
CurrencyId = x.Account.CurrencyGlobalId,
CurrencyName = x.Account.CurrencyGlobal!.Name,
})
.Select(x => new MotionTotalSimple
{
Name = x.Key.Name,
CurrencyId = x.Key.CurrencyId,
CurrencyName = x.Key.CurrencyName,
Amount = x.Sum(a => a.AmountPlus),
})
.ToListAsync(cancellationToken);
}
public async Task<List<MotionTotalSimple>> GetOutcomeByCategoriesAsync(
Guid userId,
DateTime from,
DateTime to,
CancellationToken cancellationToken = default
)
{
var accounts = await GetAccountsWithRateAsync(userId, to, cancellationToken);
var accountIds = accounts.Select(x => x.Account.Id).ToList();
return await _context.Motions
.Where(x => x.DateTime >= from && x.DateTime <= to)
.Where(x => accountIds.Contains(x.AccountId))
.Where(x => !x.Item.Category!.IsInternal)
.GroupBy(x => new
{
Id = x.Item.CategoryId,
Name = x.Item.Category!.Name,
IsUserCategory = x.Item.Category!.UserId == userId,
CurrencyId = x.Account.CurrencyGlobalId,
CurrencyName = x.Account.CurrencyGlobal!.Name,
})
.Select(x => new MotionTotalSimple
{
Id = x.Key.IsUserCategory ? x.Key.Id : userId,
Name = x.Key.IsUserCategory ? x.Key.Name : "UnCategorized",
CurrencyId = x.Key.CurrencyId,
CurrencyName = x.Key.CurrencyName,
Amount = x.Sum(a => a.AmountMinus),
})
.ToListAsync(cancellationToken);
}
public async Task<List<MotionTotalSimple>> GetOutcomeByCategoryAsync(
Guid userId,
Guid categoryId,
DateTime from,
DateTime to,
CancellationToken cancellationToken = default
)
{
var accounts = await GetAccountsWithRateAsync(userId, to, cancellationToken);
var accountIds = accounts.Select(x => x.Account.Id).ToList();
return await _context.Motions
.Where(x => x.DateTime >= from && x.DateTime <= to)
.Where(x => accountIds.Contains(x.AccountId))
.Where(x => !x.Item.Category!.IsInternal)
.Where(x => x.Item.CategoryId == categoryId)
.GroupBy(x => new
{
Id = x.Item.ItemGlobalId,
Name = x.Item.ItemGlobal!.Name,
CurrencyId = x.Account.CurrencyGlobalId,
CurrencyName = x.Account.CurrencyGlobal!.Name,
})
.Select(x => new MotionTotalSimple
{
CurrencyId = x.Key.CurrencyId,
CurrencyName = x.Key.CurrencyName,
Name = x.Key.Name,
Amount = x.Sum(a => a.AmountMinus),
})
.ToListAsync(cancellationToken);
}
}
@@ -0,0 +1,17 @@
namespace MyOffice.Data.Repositories.Account;
using Models.Accounts;
public interface IAccountAccessInviteRepository
{
AccountAccessInvite? Get(Guid userId, string email);
Task<AccountAccessInvite?> GetAsync(Guid userId, string email, CancellationToken cancellationToken = default);
IEnumerable<AccountAccessInvite> GetActive(string email);
Task<List<AccountAccessInvite>> GetActiveAsync(string email, CancellationToken cancellationToken = default);
AccountAccessInvite? Get(Guid id);
Task<AccountAccessInvite?> GetAsync(Guid id, CancellationToken cancellationToken = default);
bool Add(AccountAccessInvite invite);
Task<bool> AddAsync(AccountAccessInvite invite, CancellationToken cancellationToken = default);
bool Update(AccountAccessInvite invite);
Task<bool> UpdateAsync(AccountAccessInvite invite, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,13 @@
namespace MyOffice.Data.Repositories.Account;
using Models.Accounts;
public interface IAccountAccessRepository
{
bool Add(AccountAccess accountAccess);
Task<bool> AddAsync(AccountAccess accountAccess, CancellationToken cancellationToken = default);
bool Update(AccountAccess accountAccess);
Task<bool> UpdateAsync(AccountAccess accountAccess, CancellationToken cancellationToken = default);
bool Delete(AccountAccess accountAccess);
Task<bool> DeleteAsync(AccountAccess accountAccess, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,13 @@
namespace MyOffice.Data.Repositories.Account;
using Models.Accounts;
public interface IAccountAccountCategoryRepository
{
List<AccountAccountCategory> Get(Guid userId, Guid accountId, Guid categoryId);
Task<List<AccountAccountCategory>> GetAsync(Guid userId, Guid accountId, Guid categoryId, CancellationToken cancellationToken = default);
bool Remove(AccountAccountCategory accountAccountCategory);
Task<bool> RemoveAsync(AccountAccountCategory accountAccountCategory, CancellationToken cancellationToken = default);
bool Add(AccountAccountCategory accountAccountCategory);
Task<bool> AddAsync(AccountAccountCategory accountAccountCategory, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,17 @@
namespace MyOffice.Data.Repositories.Account;
using Models.Accounts;
public interface IAccountCategoryRepository
{
List<AccountCategory> GetAll(Guid userId);
Task<List<AccountCategory>> GetAllAsync(Guid userId, CancellationToken cancellationToken = default);
bool Add(AccountCategory accountCategory);
Task<bool> AddAsync(AccountCategory accountCategory, CancellationToken cancellationToken = default);
AccountCategory? Get(Guid userId, Guid id);
Task<AccountCategory?> GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default);
bool Update(AccountCategory accountCategory);
Task<bool> UpdateAsync(AccountCategory accountCategory, CancellationToken cancellationToken = default);
bool Remove(AccountCategory accountCategory);
Task<bool> RemoveAsync(AccountCategory accountCategory, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,37 @@
namespace MyOffice.Data.Repositories.Account;
using Models.Accounts;
public interface IAccountRepository
{
List<Account> GetAll(Guid userId);
Task<List<Account>> GetAllAsync(Guid userId, CancellationToken cancellationToken = default);
List<Account> GetByCategory(Guid userId, Guid categoryId);
Task<List<Account>> GetByCategoryAsync(Guid userId, Guid categoryId, CancellationToken cancellationToken = default);
List<AccountDetailed> GetByCategoryDetailed(Guid userId, Guid categoryId);
Task<List<AccountDetailed>> GetByCategoryDetailedAsync(Guid userId, Guid categoryId, CancellationToken cancellationToken = default);
AccountDetailed? GetByIdDetailed(Guid userId, Guid id);
Task<AccountDetailed?> GetByIdDetailedAsync(Guid userId, Guid id, CancellationToken cancellationToken = default);
bool Add(Account account);
Task<bool> AddAsync(Account account, CancellationToken cancellationToken = default);
bool Delete(Account account);
Task<bool> DeleteAsync(Account account, CancellationToken cancellationToken = default);
Account? Get(Guid userId, Guid id);
Task<Account?> GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default);
bool Update(Account account);
Task<bool> UpdateAsync(Account account, CancellationToken cancellationToken = default);
bool Remove(Account account);
List<Account> FindAccounts(Guid userId, string term);
Task<List<Account>> FindAccountsAsync(Guid userId, string term, CancellationToken cancellationToken = default);
List<AccountSimple> GetRestAtDate(Guid userId, DateTime date);
Task<List<AccountSimple>> GetRestAtDateAsync(Guid userId, DateTime date, CancellationToken cancellationToken = default);
List<MotionTotalSimple> GetIncomeByCategories(Guid userId, DateTime from, DateTime to);
Task<List<MotionTotalSimple>> GetIncomeByCategoriesAsync(Guid userId, DateTime from, DateTime to, CancellationToken cancellationToken = default);
List<MotionTotalSimple> GetIncomeByCategory(Guid userId, Guid categoryId, DateTime from, DateTime to);
Task<List<MotionTotalSimple>> GetIncomeByCategoryAsync(Guid userId, Guid categoryId, DateTime from, DateTime to, CancellationToken cancellationToken = default);
List<MotionTotalSimple> GetOutcomeByCategories(Guid userId, DateTime from, DateTime to);
Task<List<MotionTotalSimple>> GetOutcomeByCategoriesAsync(Guid userId, DateTime from, DateTime to, CancellationToken cancellationToken = default);
List<MotionTotalSimple> GetOutcomeByCategory(Guid userId, Guid categoryId, DateTime from, DateTime to);
Task<List<MotionTotalSimple>> GetOutcomeByCategoryAsync(Guid userId, Guid categoryId, DateTime from, DateTime to, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,12 @@
namespace MyOffice.Data.Repositories.Account;
using Models.Accounts;
public interface IMotionRepository
{
Task<bool> AddAsync(Motion motion, CancellationToken cancellationToken = default);
Task<List<Motion>> GetByAccountAsync(Guid accountId, DateTime dateFrom, DateTime dateTo, CancellationToken cancellationToken = default);
Task<Motion?> GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default);
Task<bool> UpdateAsync(Motion motion, CancellationToken cancellationToken = default);
Task<bool> RemoveAsync(Motion motion, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,55 @@
namespace MyOffice.Data.Repositories.Account;
using Microsoft.EntityFrameworkCore;
using Models.Accounts;
using MyOffice.DbContext;
public class MotionRepository : AppRepository<Motion>, IMotionRepository
{
public MotionRepository(AppDbContext context) : base(context)
{
}
public async Task<bool> AddAsync(Motion motion, CancellationToken cancellationToken = default)
{
return await AddBaseAsync(motion, cancellationToken) > 0;
}
public async Task<List<Motion>> GetByAccountAsync(
Guid accountId,
DateTime dateFrom,
DateTime dateTo,
CancellationToken cancellationToken = default
)
{
return await _context
.Motions
.Include(x => x.Item)
.ThenInclude(x => x.ItemGlobal)
.Where(x => x.AccountId == accountId && x.DateTime >= dateFrom && x.DateTime <= dateTo)
.OrderByDescending(x => x.DateTime)
.ThenByDescending(x => x.CreatedOn)
.ToListAsync(cancellationToken);
}
public async Task<Motion?> GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default)
{
return await _context
.Motions
.Include(x => x.Item)
.ThenInclude(x => x.ItemGlobal)
.FirstOrDefaultAsync(
x => x.Account!.AccessRights!.Any(a => a.UserId == userId) && x.Id == id,
cancellationToken);
}
public async Task<bool> UpdateAsync(Motion motion, CancellationToken cancellationToken = default)
{
return await UpdateBaseAsync(motion, cancellationToken) > 0;
}
public async Task<bool> RemoveAsync(Motion motion, CancellationToken cancellationToken = default)
{
return await RemoveBaseAsync(motion, cancellationToken) > 0;
}
}
@@ -0,0 +1,10 @@
namespace MyOffice.Data.Repositories;
using DbContext;
public class AppRepository<TEntity> : RepositoryBase<TEntity> where TEntity : class
{
public AppRepository(AppDbContext context) : base(context)
{
}
}
@@ -0,0 +1,22 @@
namespace MyOffice.Data.Repositories.Currency;
using Microsoft.EntityFrameworkCore;
using Models.Currencies;
using MyOffice.DbContext;
public class CurrencyGlobalRepository : AppRepository<CurrencyGlobal>, ICurrencyGlobalRepository
{
public CurrencyGlobalRepository(AppDbContext context) : base(context)
{
}
public List<CurrencyGlobal> GetAll()
{
return _context.CurrencyGlobals.ToList();
}
public async Task<List<CurrencyGlobal>> GetAllAsync(CancellationToken cancellationToken = default)
{
return await _context.CurrencyGlobals.ToListAsync(cancellationToken);
}
}
@@ -0,0 +1,115 @@
namespace MyOffice.Data.Repositories.Currency;
using System.Xml.Schema;
using Microsoft.EntityFrameworkCore;
using Models.Currencies;
using MyOffice.DbContext;
public class CurrencyRateRepository : AppRepository<CurrencyRate>, ICurrencyRateRepository
{
public CurrencyRateRepository(AppDbContext context) : base(context)
{
}
public List<CurrencyRate> GetLastRates(Guid currencyId, DateTime? before = null, int count = 1)
{
before = before ?? DateTime.UtcNow;
return _context.CurrencyRates
.Where(x => x.CurrencyId == currencyId)
.Where(x => x.DateTime <= before)
.OrderByDescending(x => x.DateTime)
.ThenByDescending(x => x.Id)
.Take(count)
.ToList();
}
public async Task<List<CurrencyRate>> GetLastRatesAsync(
Guid currencyId,
DateTime? before = null,
int count = 1,
CancellationToken cancellationToken = default)
{
before ??= DateTime.UtcNow;
return await _context.CurrencyRates
.Where(x => x.CurrencyId == currencyId)
.Where(x => x.DateTime <= before)
.OrderByDescending(x => x.DateTime)
.ThenByDescending(x => x.Id)
.Take(count)
.ToListAsync(cancellationToken);
}
public Dictionary<string, CurrencyRate> GetLastRates(Guid userId, List<string> currencyIds, DateTime? before = null)
{
return _context.CurrencyRates
.Include(x => x.Currency)
.Include(x => x.Currency!.CurrencyGlobal)
.Where(x => x.DateTime <= before)
.Where(x => x.Currency!.UserId == userId)
.Where(x => currencyIds.Contains(x.Currency!.CurrencyGlobalId))
.GroupBy(x => new
{
x.Currency!.CurrencyGlobalId
}, (key, g) => new
{
key.CurrencyGlobalId,
rate = g.OrderByDescending(x => x.DateTime).First()
})
.ToDictionary(x => x.CurrencyGlobalId, x => x.rate);
}
public async Task<Dictionary<string, CurrencyRate>> GetLastRatesAsync(
Guid userId,
List<string> currencyIds,
DateTime? before = null,
CancellationToken cancellationToken = default
)
{
var rows = await _context.CurrencyRates
.Include(x => x.Currency)
.Include(x => x.Currency!.CurrencyGlobal)
.Where(x => x.DateTime <= before)
.Where(x => x.Currency!.UserId == userId)
.Where(x => currencyIds.Contains(x.Currency!.CurrencyGlobalId))
.GroupBy(x => new
{
x.Currency!.CurrencyGlobalId
}, (key, g) => new
{
key.CurrencyGlobalId,
rate = g.OrderByDescending(x => x.DateTime).First()
})
.ToListAsync(cancellationToken);
return rows.ToDictionary(x => x.CurrencyGlobalId, x => x.rate);
}
public bool AddRate(CurrencyRate currencyRate)
{
return this.AddBase(currencyRate) > 0;
}
public async Task<bool> AddRateAsync(CurrencyRate currencyRate, CancellationToken cancellationToken = default)
{
return await AddBaseAsync(currencyRate, cancellationToken) > 0;
}
public List<CurrencyRate> GetAtDate(Guid currencyId, DateTime date)
{
return _context.CurrencyRates
.Where(x => x.CurrencyId == currencyId && x.DateTime == date)
.ToList();
}
public async Task<List<CurrencyRate>> GetAtDateAsync(
Guid currencyId,
DateTime date,
CancellationToken cancellationToken = default)
{
return await _context.CurrencyRates
.Where(x => x.CurrencyId == currencyId && x.DateTime == date)
.ToListAsync(cancellationToken);
}
}
@@ -0,0 +1,102 @@
namespace MyOffice.Data.Repositories.Currency;
using Microsoft.EntityFrameworkCore;
using Models.Currencies;
using MyOffice.Data.Repositories;
using MyOffice.DbContext;
public class CurrencyRepository : AppRepository<Currency>, ICurrencyRepository
{
public CurrencyRepository(AppDbContext context) : base(context)
{
}
public List<Currency> GetAll(Guid userId)
{
return _context.Currencies
.Include(x => x.CurrencyGlobal)
.Where(x => x.UserId == userId)
.ToList();
}
public async Task<List<Currency>> GetAllAsync(Guid userId, CancellationToken cancellationToken = default)
{
return await _context.Currencies
.Include(x => x.CurrencyGlobal)
.Where(x => x.UserId == userId)
.ToListAsync(cancellationToken);
}
public Currency? Get(Guid userId, Guid id)
{
return _context
.Currencies
.Include(x => x.CurrencyGlobal)
.FirstOrDefault(x => x.Id == id && x.UserId == userId);
}
public async Task<Currency?> GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default)
{
return await _context
.Currencies
.Include(x => x.CurrencyGlobal)
.FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId, cancellationToken);
}
public Currency? GetByGlobalCurrency(Guid userId, string globalCurrencyId)
{
return _context.Currencies.FirstOrDefault(x => x.UserId == userId && x.CurrencyGlobalId == globalCurrencyId);
}
public async Task<Currency?> GetByGlobalCurrencyAsync(
Guid userId,
string globalCurrencyId,
CancellationToken cancellationToken = default)
{
return await _context.Currencies.FirstOrDefaultAsync(
x => x.UserId == userId && x.CurrencyGlobalId == globalCurrencyId,
cancellationToken);
}
public bool Add(Currency currency)
{
return AddBase(currency) > 0;
}
public async Task<bool> AddAsync(Currency currency, CancellationToken cancellationToken = default)
{
return await AddBaseAsync(currency, cancellationToken) > 0;
}
public bool Update(Currency currency)
{
return UpdateBase(currency) > 0;
}
public async Task<bool> UpdateAsync(Currency currency, CancellationToken cancellationToken = default)
{
return await UpdateBaseAsync(currency, cancellationToken) > 0;
}
public bool Remove(Currency currency)
{
return RemoveBase(currency) > 0;
}
public async Task<bool> RemoveAsync(Currency currency, CancellationToken cancellationToken = default)
{
return await RemoveBaseAsync(currency, cancellationToken) > 0;
}
public List<Currency> GetPrimaries(Guid userId)
{
return _context.Currencies.Where(x => x.UserId == userId && x.IsPrimary).ToList();
}
public async Task<List<Currency>> GetPrimariesAsync(Guid userId, CancellationToken cancellationToken = default)
{
return await _context.Currencies
.Where(x => x.UserId == userId && x.IsPrimary)
.ToListAsync(cancellationToken);
}
}
@@ -0,0 +1,9 @@
namespace MyOffice.Data.Repositories.Currency;
using Models.Currencies;
public interface ICurrencyGlobalRepository
{
List<CurrencyGlobal> GetAll();
Task<List<CurrencyGlobal>> GetAllAsync(CancellationToken cancellationToken = default);
}
@@ -0,0 +1,19 @@
namespace MyOffice.Data.Repositories.Currency;
using Models.Currencies;
public interface ICurrencyRateRepository
{
List<CurrencyRate> GetLastRates(Guid currencyId, DateTime? before = null, int count = 1);
Task<List<CurrencyRate>> GetLastRatesAsync(Guid currencyId, DateTime? before = null, int count = 1, CancellationToken cancellationToken = default);
Dictionary<string, CurrencyRate> GetLastRates(Guid userId, List<string> currencyIds, DateTime? before = null);
Task<Dictionary<string, CurrencyRate>> GetLastRatesAsync(
Guid userId,
List<string> currencyIds,
DateTime? before = null,
CancellationToken cancellationToken = default);
bool AddRate(CurrencyRate currencyRate);
Task<bool> AddRateAsync(CurrencyRate currencyRate, CancellationToken cancellationToken = default);
List<CurrencyRate> GetAtDate(Guid currencyId, DateTime date);
Task<List<CurrencyRate>> GetAtDateAsync(Guid currencyId, DateTime date, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,21 @@
namespace MyOffice.Data.Repositories.Currency;
using Models.Currencies;
public interface ICurrencyRepository
{
List<Currency> GetAll(Guid userId);
Task<List<Currency>> GetAllAsync(Guid userId, CancellationToken cancellationToken = default);
Currency? Get(Guid userId, Guid id);
Task<Currency?> GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default);
Currency? GetByGlobalCurrency(Guid userId, string globalCurrencyId);
Task<Currency?> GetByGlobalCurrencyAsync(Guid userId, string globalCurrencyId, CancellationToken cancellationToken = default);
bool Add(Currency currency);
Task<bool> AddAsync(Currency currency, CancellationToken cancellationToken = default);
bool Update(Currency currency);
Task<bool> UpdateAsync(Currency currency, CancellationToken cancellationToken = default);
bool Remove(Currency currency);
Task<bool> RemoveAsync(Currency currency, CancellationToken cancellationToken = default);
List<Currency> GetPrimaries(Guid userId);
Task<List<Currency>> GetPrimariesAsync(Guid userId, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,17 @@
namespace MyOffice.Data.Repositories.Item;
using MyOffice.Data.Models.Items;
public interface IItemCategoryRepository
{
List<ItemCategory> GetAll(Guid userId);
Task<List<ItemCategory>> GetAllAsync(Guid userId, CancellationToken cancellationToken = default);
bool Add(ItemCategory accountCategory);
Task<bool> AddAsync(ItemCategory accountCategory, CancellationToken cancellationToken = default);
ItemCategory? Get(Guid userId, Guid id);
Task<ItemCategory?> GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default);
bool Update(ItemCategory accountCategory);
Task<bool> UpdateAsync(ItemCategory accountCategory, CancellationToken cancellationToken = default);
bool Remove(ItemCategory accountCategory);
Task<bool> RemoveAsync(ItemCategory accountCategory, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,14 @@
namespace MyOffice.Data.Repositories.Item;
using MyOffice.Data.Models.Items;
public interface IItemGlobalRepository
{
ItemGlobal? Get(Guid id);
ItemGlobal? GetByName(string name);
Task<ItemGlobal?> GetByNameAsync(string name, CancellationToken cancellationToken = default);
bool Add(ItemGlobal itemGlobal);
Task<bool> AddAsync(ItemGlobal itemGlobal, CancellationToken cancellationToken = default);
List<ItemGlobal> GetAvailableToUser(Guid userId);
Task<List<ItemGlobal>> GetAvailableToUserAsync(Guid userId, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,19 @@
namespace MyOffice.Data.Repositories.Item;
using MyOffice.Data.Models.Items;
public interface IItemRepository
{
List<Item> GetAll(Guid userId);
Task<List<Item>> GetAllAsync(Guid userId, CancellationToken cancellationToken = default);
List<Item> GetByCategory(Guid userId, Guid categoryId);
Task<List<Item>> GetByCategoryAsync(Guid userId, Guid categoryId, CancellationToken cancellationToken = default);
Item? GetByGlobal(Guid userId, Guid globalItemId);
Task<Item?> GetByGlobalAsync(Guid userId, Guid globalItemId, CancellationToken cancellationToken = default);
bool Add(Item item);
Task<bool> AddAsync(Item item, CancellationToken cancellationToken = default);
bool Update(Item item);
Task<bool> UpdateAsync(Item item, CancellationToken cancellationToken = default);
List<Item> Find(Guid userId, string term, int limit);
Task<List<Item>> FindAsync(Guid userId, string term, int limit, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,72 @@
namespace MyOffice.Data.Repositories.Item;
using Microsoft.EntityFrameworkCore;
using MyOffice.Data.Models.Items;
using MyOffice.DbContext;
public class ItemCategoryRepository : AppRepository<ItemCategory>, IItemCategoryRepository
{
public ItemCategoryRepository(AppDbContext context) : base(context)
{
}
public List<ItemCategory> GetAll(Guid userId)
{
return _context.ItemCategories
.Include(x => x.Items)
.Where(x => x.UserId == userId)
.ToList();
}
public async Task<List<ItemCategory>> GetAllAsync(Guid userId, CancellationToken cancellationToken = default)
{
return await _context.ItemCategories
.Include(x => x.Items)
.Where(x => x.UserId == userId)
.ToListAsync(cancellationToken);
}
public bool Add(ItemCategory itemCategory)
{
return AddBase(itemCategory) > 0;
}
public async Task<bool> AddAsync(ItemCategory itemCategory, CancellationToken cancellationToken = default)
{
return await AddBaseAsync(itemCategory, cancellationToken) > 0;
}
public ItemCategory? Get(Guid userId, Guid id)
{
return _context.ItemCategories
.Include(x => x.Items)
.FirstOrDefault(x => x.Id == id && x.UserId == userId);
}
public async Task<ItemCategory?> GetAsync(Guid userId, Guid id, CancellationToken cancellationToken = default)
{
return await _context.ItemCategories
.Include(x => x.Items)
.FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId, cancellationToken);
}
public bool Update(ItemCategory itemCategory)
{
return UpdateBase(itemCategory) > 0;
}
public async Task<bool> UpdateAsync(ItemCategory itemCategory, CancellationToken cancellationToken = default)
{
return await UpdateBaseAsync(itemCategory, cancellationToken) > 0;
}
public bool Remove(ItemCategory itemCategory)
{
return RemoveBase(itemCategory) > 0;
}
public async Task<bool> RemoveAsync(ItemCategory itemCategory, CancellationToken cancellationToken = default)
{
return await RemoveBaseAsync(itemCategory, cancellationToken) > 0;
}
}
@@ -0,0 +1,69 @@
namespace MyOffice.Data.Repositories.Item;
using Microsoft.EntityFrameworkCore;
using MyOffice.Data.Models.Items;
using MyOffice.DbContext;
public class ItemGlobalRepository : AppRepository<ItemGlobal>, IItemGlobalRepository
{
public ItemGlobalRepository(AppDbContext context) : base(context)
{
}
public ItemGlobal? Get(Guid id)
{
return _context.ItemGlobals.FirstOrDefault(x => x.Id == id);
}
public ItemGlobal? GetByName(string name)
{
return _context.ItemGlobals.FirstOrDefault(x => x.Name == name);
}
public Task<ItemGlobal?> GetByNameAsync(string name, CancellationToken cancellationToken = default)
{
return _context.ItemGlobals.FirstOrDefaultAsync(x => x.Name == name, cancellationToken);
}
public bool Add(ItemGlobal itemGlobal)
{
return AddBase(itemGlobal) > 0;
}
public async Task<bool> AddAsync(ItemGlobal itemGlobal, CancellationToken cancellationToken = default)
{
return await AddBaseAsync(itemGlobal, cancellationToken) > 0;
}
public List<ItemGlobal> GetAvailableToUser(Guid userId)
{
return _context.Motions
.Include(x => x.Item)
.ThenInclude(x => x.ItemGlobal)
.ThenInclude(x => x.Items)
.ThenInclude(x => x.Category)
.Where(x => x.Account.AccessRights!.Any(a => a.UserId == userId))
.Where(x => x.Item.ItemGlobal.Items.All(g => g.Category!.UserId != userId))
.Select(x => x.Item.ItemGlobal)
.GroupBy(x => x.Id)
.Select(x => x.First())
.ToList();
}
public async Task<List<ItemGlobal>> GetAvailableToUserAsync(
Guid userId,
CancellationToken cancellationToken = default)
{
return await _context.Motions
.Include(x => x.Item)
.ThenInclude(x => x.ItemGlobal)
.ThenInclude(x => x.Items)
.ThenInclude(x => x.Category)
.Where(x => x.Account.AccessRights!.Any(a => a.UserId == userId))
.Where(x => x.Item.ItemGlobal.Items.All(g => g.Category!.UserId != userId))
.Select(x => x.Item.ItemGlobal)
.GroupBy(x => x.Id)
.Select(x => x.First())
.ToListAsync(cancellationToken);
}
}
@@ -0,0 +1,121 @@
namespace MyOffice.Data.Repositories.Item;
using Microsoft.EntityFrameworkCore;
using MyOffice.Data.Models.Items;
using MyOffice.DbContext;
public class ItemRepository : AppRepository<Item>, IItemRepository
{
public ItemRepository(AppDbContext context) : base(context)
{
}
public List<Item> GetAll(Guid userId)
{
return _context.Items
.Include(x => x.Motions)
.Include(x => x.Category)
.Include(x => x.ItemGlobal)
.Where(x => x.Category!.UserId == userId)
.ToList();
}
public async Task<List<Item>> GetAllAsync(Guid userId, CancellationToken cancellationToken = default)
{
return await _context.Items
.Include(x => x.Motions)
.Include(x => x.Category)
.Include(x => x.ItemGlobal)
.Where(x => x.Category!.UserId == userId)
.ToListAsync(cancellationToken);
}
public List<Item> GetByCategory(Guid userId, Guid categoryId)
{
return _context.Items
.Include(x => x.Motions)
.Include(x => x.Category)
.Include(x => x.ItemGlobal)
.Where(x => x.Category!.UserId == userId && x.CategoryId == categoryId)
.ToList();
}
public async Task<List<Item>> GetByCategoryAsync(
Guid userId,
Guid categoryId,
CancellationToken cancellationToken = default)
{
return await _context.Items
.Include(x => x.Motions)
.Include(x => x.Category)
.Include(x => x.ItemGlobal)
.Where(x => x.Category!.UserId == userId && x.CategoryId == categoryId)
.ToListAsync(cancellationToken);
}
public Item? GetByGlobal(Guid userId, Guid globalItemId)
{
return _context.Items
.Include(x => x.Motions)
.Include(x => x.Category)
.Include(x => x.ItemGlobal)
.FirstOrDefault(x => x.Category!.UserId == userId && x.ItemGlobalId == globalItemId);
}
public Task<Item?> GetByGlobalAsync(Guid userId, Guid globalItemId, CancellationToken cancellationToken = default)
{
return _context.Items
.Include(x => x.Motions)
.Include(x => x.Category)
.Include(x => x.ItemGlobal)
.FirstOrDefaultAsync(
x => x.Category!.UserId == userId && x.ItemGlobalId == globalItemId,
cancellationToken);
}
public bool Update(Item item)
{
return base.UpdateBase(item) > 0;
}
public async Task<bool> UpdateAsync(Item item, CancellationToken cancellationToken = default)
{
return await UpdateBaseAsync(item, cancellationToken) > 0;
}
public bool Add(Item item)
{
return base.AddBase(item) > 0;
}
public async Task<bool> AddAsync(Item item, CancellationToken cancellationToken = default)
{
return await AddBaseAsync(item, cancellationToken) > 0;
}
public List<Item> Find(Guid userId, string term, int limit)
{
return _context
.Items
.Include(x => x.ItemGlobal)
.Where(x => x.Category!.UserId == userId && x.ItemGlobal.Name.ToLower().Contains(term.ToLower()))
.OrderByDescending(x => x!.Motions!.Count())
.Take(limit)
.ToList();
}
public async Task<List<Item>> FindAsync(
Guid userId,
string term,
int limit,
CancellationToken cancellationToken = default)
{
return await _context
.Items
.Include(x => x.ItemGlobal)
.Where(x => x.Category!.UserId == userId && x.ItemGlobal.Name.ToLower().Contains(term.ToLower()))
.OrderByDescending(x => x!.Motions!.Count())
.Take(limit)
.ToListAsync(cancellationToken);
}
}
@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Compile Remove="AppDbContext.cs" />
<Compile Remove="AppDbContextFactory.cs" />
<Compile Remove="RepositoryInitializer.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyOffice.Data.Models\MyOffice.Data.Models.csproj" />
<ProjectReference Include="..\MyOffice.DbContext\MyOffice.DbContext.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,17 @@
namespace MyOffice.Data.Repositories.Item;
using MyOffice.Data.Models.Notifications;
using MyOffice.DbContext;
public class EmailTemplateRepository : AppRepository<EmailTemplate>, IEmailTemplateRepository
{
public EmailTemplateRepository(AppDbContext context) : base(context)
{
}
public EmailTemplate? Get(EmailTemplateEnum emailTemplate)
{
var emailTemplateStr = emailTemplate.ToString();
return _context.EmailTemplates.FirstOrDefault(x => x.Id == emailTemplateStr);
}
}
@@ -0,0 +1,8 @@
namespace MyOffice.Data.Repositories.Item;
using MyOffice.Data.Models.Notifications;
public interface IEmailTemplateRepository
{
EmailTemplate? Get(EmailTemplateEnum emailTemplate);
}
@@ -0,0 +1,108 @@
namespace MyOffice.Data.Repositories;
using Microsoft.EntityFrameworkCore;
using DbContext;
public class RepositoryBase<TEntity> where TEntity : class
{
protected readonly AppDbContext _context;
protected RepositoryBase(
AppDbContext context
)
{
_context = context;
}
protected async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
try
{
return await _context.SaveChangesAsync(cancellationToken);
}
catch (DbUpdateException updateException)
{
throw updateException;
}
}
protected int SaveChanges()
{
try
{
return _context.SaveChanges();
}
catch (DbUpdateException updateException)
{
throw updateException;
}
}
protected async Task<TEntity?> GetBaseAsync(Guid id)
{
return await _context.Set<TEntity>().FindAsync(id);
}
protected TEntity? GetBase(Guid id)
{
return _context.Set<TEntity>().Find(id);
}
protected int AddBase(TEntity entity)
{
_context.Entry(entity).State = EntityState.Added;
var result = SaveChanges();
_context.Entry(entity).State = EntityState.Detached;
return result;
}
protected async Task<int> AddBaseAsync(TEntity entity, CancellationToken cancellationToken = default)
{
_context.Entry(entity).State = EntityState.Added;
var result = await SaveChangesAsync(cancellationToken);
_context.Entry(entity).State = EntityState.Detached;
return result;
}
protected int RemoveBase(TEntity entity)
{
_context.Set<TEntity>().Remove(entity);
_context.Entry(entity).State = EntityState.Deleted;
var result = SaveChanges();
_context.Entry(entity).State = EntityState.Detached;
return result;
}
protected async Task<int> RemoveBaseAsync(TEntity entity, CancellationToken cancellationToken = default)
{
_context.Set<TEntity>().Remove(entity);
_context.Entry(entity).State = EntityState.Deleted;
var result = await SaveChangesAsync(cancellationToken);
_context.Entry(entity).State = EntityState.Detached;
return result;
}
protected int UpdateBase(TEntity entity)
{
_context.Entry(entity).State = EntityState.Modified;
var result = SaveChanges();
_context.Entry(entity).State = EntityState.Detached;
return result;
}
protected async Task<int> UpdateBaseAsync(TEntity entity, CancellationToken cancellationToken = default)
{
_context.Entry(entity).State = EntityState.Modified;
var result = await SaveChangesAsync(cancellationToken);
_context.Entry(entity).State = EntityState.Detached;
return result;
}
}
@@ -0,0 +1,20 @@
namespace MyOffice.Data.Repositories.Users;
using Models.Users;
public interface IUserExternalRepository
{
int AddUserExternal(UserExternal external);
Task<int> AddUserExternalAsync(UserExternal external, CancellationToken cancellationToken = default);
Task<List<UserExternal>> GetUserExternalsByUserIdAsync(Guid userId);
Task<UserExternal?> GetByUserIdAsync(Guid userId, string provider);
UserExternal? GetByUserId(Guid userId, string provider);
UserExternal? GetByExternalId(string externalId, string provider);
Task<UserExternal?> GetByExternalIdAsync(string externalId, string provider);
void RemoveUserExternal(UserExternal userExternal);
Task RemoveUserExternalAsync(UserExternal userExternal, CancellationToken cancellationToken = default);
}
@@ -0,0 +1,15 @@
namespace MyOffice.Data.Repositories.Users;
using MyOffice.Data.Models.Users;
public interface IUserRepository
{
Task<User?> GetUserAsync(Guid id);
User? GetUser(Guid id);
Task<User?> GetByUserUserNameAsync(string userName);
User? GetByUserUserName(string userName);
int AddUser(User user);
int UpdateUser(User user);
}
@@ -0,0 +1,108 @@
namespace MyOffice.Data.Repositories.Users;
using MyOffice.Data.Models.Users;
using Repositories;
using Microsoft.EntityFrameworkCore;
using MyOffice.DbContext;
public class UserExternalRepository : AppRepository<UserExternal>, IUserExternalRepository
{
public UserExternalRepository(AppDbContext context) : base(context)
{
}
public int AddUserExternal(UserExternal userExternal)
{
return AddBase(userExternal);
}
public async Task<int> AddUserExternalAsync(UserExternal userExternal, CancellationToken cancellationToken = default)
{
return await AddBaseAsync(userExternal, cancellationToken);
}
public async Task<int> AddUserExternalsAsync(IEnumerable<UserExternal> claims)
{
_context.AddRange(claims);
return await SaveChangesAsync();
}
public async Task<List<UserExternal>> GetUserExternalsByUserNameAsync(string userName)
{
return await _context
.UserClaims
.Where(x => x.User.UserName == userName)
.Include(x => x.User)
.ToListAsync();
}
public async Task<List<UserExternal>> GetUserExternalsByUserIdAsync(Guid userId)
{
return await _context
.UserClaims
.Where(x => x.UserId == userId)
.Include(x => x.User)
.ToListAsync();
}
public List<UserExternal> GetUserExternalsByUser(Guid userId)
{
return _context
.UserClaims
.Where(x => x.UserId == userId)
.Include(x => x.User)
.ToList();
}
public List<UserExternal> GetUserExternalsByUserName(string userName)
{
return _context
.UserClaims
.Where(x => x.User.UserName == userName)
.Include(x => x.User)
.ToList();
}
public async Task<UserExternal?> GetByUserIdAsync(Guid userId, string provider)
{
return await _context
.UserClaims
.Include(x => x.User)
.FirstOrDefaultAsync(x => x.UserId == userId && x.Provider == provider);
}
public UserExternal? GetByUserId(Guid userId, string provider)
{
return _context
.UserClaims
.Include(x => x.User)
.FirstOrDefault(x => x.UserId == userId && x.Provider == provider);
}
public UserExternal? GetByExternalId(string externalId, string provider)
{
return _context
.UserClaims
.Include(x => x.User)
.FirstOrDefault(x => x.ExternalId == externalId && x.Provider == provider);
}
public Task<UserExternal?> GetByExternalIdAsync(string externalId, string provider)
{
return _context
.UserClaims
.Include(x => x.User)
.FirstOrDefaultAsync(x => x.ExternalId == externalId && x.Provider == provider);
}
public void RemoveUserExternal(UserExternal userExternal)
{
RemoveBase(userExternal);
}
public async Task RemoveUserExternalAsync(UserExternal userExternal, CancellationToken cancellationToken = default)
{
await RemoveBaseAsync(userExternal, cancellationToken);
}
}
@@ -0,0 +1,43 @@
namespace MyOffice.Data.Repositories.Users;
using MyOffice.Data.Models.Users;
using Repositories;
using Microsoft.EntityFrameworkCore;
using MyOffice.DbContext;
public class UserRepository : AppRepository<User>, IUserRepository
{
public UserRepository(AppDbContext context) : base(context)
{
}
public async Task<User?> GetUserAsync(Guid id)
{
return await GetBaseAsync(id);
}
public User? GetUser(Guid id)
{
return GetBase(id);
}
public async Task<User?> GetByUserUserNameAsync(string userName)
{
return await _context.Users.FirstOrDefaultAsync(x => x.UserName == userName);
}
public User? GetByUserUserName(string userName)
{
return _context.Users.FirstOrDefault(x => x.UserName == userName);
}
public int AddUser(User user)
{
return AddBase(user);
}
public int UpdateUser(User user)
{
return UpdateBase(user);
}
}
@@ -0,0 +1,11 @@
using MyOffice.Data.Models.Verifications;
namespace MyOffice.Data.Repositories.Item;
public interface IVerificationCodeRepository
{
VerificationCode? GetByCode(string code);
bool Add(VerificationCode entity);
bool Update(VerificationCode entity);
}
@@ -0,0 +1,27 @@
namespace MyOffice.Data.Repositories.Item;
using Microsoft.EntityFrameworkCore;
using MyOffice.Data.Models.Verifications;
using MyOffice.DbContext;
public class VerificationCodeRepository : AppRepository<VerificationCode>, IVerificationCodeRepository
{
public VerificationCodeRepository(AppDbContext context) : base(context)
{
}
public bool Add(VerificationCode entity)
{
return AddBase(entity) > 0;
}
public bool Update(VerificationCode entity)
{
return UpdateBase(entity) > 0;
}
public VerificationCode? GetByCode(string code)
{
return _context.Verifications.FirstOrDefault(x => x.Code == code);
}
}
+335
View File
@@ -0,0 +1,335 @@
namespace MyOffice.DbContext;
using Data.Models.Accounts;
using Data.Models.Currencies;
using Data.Models.Items;
using Microsoft.EntityFrameworkCore;
using Data.Models.Users;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyOffice.Data.Models.Verifications;
using MyOffice.Data.Models.Notifications;
public enum AppDbContextProvidersEnum
{
sqlite,
mssql,
npgsql
}
public class AppDbContext : DbContext
{
private readonly AppDbContextProvidersEnum _provider;
private readonly Dictionary<AppDbContextProvidersEnum, string> _noCaseCollation = new()
{
{ AppDbContextProvidersEnum.sqlite, "NOCASE" },
{ AppDbContextProvidersEnum.npgsql, "my_ci_collation" }
};
public AppDbContext(AppDbContextProvidersEnum provider, DbContextOptions<AppDbContext> options) : base(options)
{
_provider = provider;
ConfigureChangeTracker();
}
public AppDbContext(DbContextOptions<AppDbContext> options, ConnectionConfiguration connection) : base(options)
{
_provider = Enum.Parse<AppDbContextProvidersEnum>(connection.Provider, ignoreCase: true);
ConfigureChangeTracker();
}
private void ConfigureChangeTracker()
{
// Match historical repository behavior (manual EntityState updates).
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
ChangeTracker.AutoDetectChangesEnabled = false;
}
public DbSet<User> Users { get; set; } = null!;
public DbSet<UserExternal> UserClaims { get; set; } = null!;
public DbSet<CurrencyGlobal> CurrencyGlobals { get; set; } = null!;
public DbSet<Currency> Currencies { get; set; } = null!;
public DbSet<CurrencyRate> CurrencyRates { get; set; } = null!;
public DbSet<AccountCategory> AccountCategories { get; set; } = null!;
public DbSet<Account> Accounts { get; set; } = null!;
public DbSet<AccountAccountCategory> AccountAccountCategories { get; set; } = null!;
public DbSet<AccountAccess> AccountAccesses { get; set; } = null!;
public DbSet<AccountAccessInvite> AccountAccessInvites { get; set; } = null!;
public DbSet<ItemCategory> ItemCategories { get; set; } = null!;
public DbSet<ItemGlobal> ItemGlobals { get; set; } = null!;
public DbSet<Item> Items { get; set; } = null!;
public DbSet<Motion> Motions { get; set; } = null!;
public DbSet<VerificationCode> Verifications { get; set; } = null!;
public DbSet<EmailTemplate> EmailTemplates { get; set; } = null!;
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var noCaseCollation = _noCaseCollation[_provider];
if (_provider == AppDbContextProvidersEnum.npgsql)
{
modelBuilder.HasCollation("my_ci_collation", "en-u-ks-primary", "icu", false);
}
/* NOCASE PROPERTIES */
modelBuilder.Entity<User>()
.Property(x => x.UserName)
.UseCollation(noCaseCollation);
modelBuilder.Entity<User>()
.Property(x => x.Email)
.UseCollation(noCaseCollation);
modelBuilder.Entity<UserExternal>()
.Property(x => x.Provider)
.UseCollation(noCaseCollation);
modelBuilder.Entity<UserExternal>()
.Property(x => x.Email)
.UseCollation(noCaseCollation);
modelBuilder.Entity<UserExternal>()
.HasOne(x => x.User)
.WithMany(x => x.UserClaims)
.HasForeignKey(x => x.UserId);
UserCreating(modelBuilder);
CurrencyCreating(modelBuilder);
AccountCreating(modelBuilder);
MotionsCreating(modelBuilder);
VerificationsCreating(modelBuilder);
EmailTemplateCreating(modelBuilder);
modelBuilder.UseOpenIddict();
base.OnModelCreating(modelBuilder);
}
private void VerificationsCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<VerificationCode>()
.HasKey(x => x.Id);
modelBuilder.Entity<VerificationCode>()
.HasOne(x => x.User)
.WithMany()
.HasForeignKey(x => x.UserId);
}
private void EmailTemplateCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<EmailTemplate>()
.HasKey(x => x.Id);
}
private void UserCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasOne(x => x.Currency)
.WithMany()
.HasForeignKey(x => x.CurrencyId);
}
private void CurrencyCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<CurrencyGlobal>()
.HasKey(x => x.Id);
modelBuilder.Entity<Currency>()
.HasKey(x => x.Id);
modelBuilder.Entity<CurrencyRate>()
.HasKey(x => x.Id);
modelBuilder.Entity<Currency>()
.HasOne(x => x.CurrencyGlobal)
.WithMany(x => x.Currencies)
.HasForeignKey(x => x.CurrencyGlobalId);
modelBuilder.Entity<Currency>()
.HasOne(x => x.User)
.WithMany(x => x.Currencies)
.HasForeignKey(x => x.UserId);
modelBuilder.Entity<CurrencyRate>()
.HasOne(x => x.Currency)
.WithMany(x => x.Rates)
.HasForeignKey(x => x.CurrencyId);
modelBuilder.Entity<Currency>()
.HasOne(x => x.CurrentRate)
.WithMany(x => x.Currencies)
.HasForeignKey(x => x.CurrentRateId);
}
private void AccountCreating(ModelBuilder modelBuilder)
{
#region Account
modelBuilder.Entity<Account>()
.HasKey(x => x.Id);
modelBuilder.Entity<Account>()
.HasOne(x => x.CurrencyGlobal)
.WithMany(x => x.Accounts)
.HasForeignKey(x => x.CurrencyGlobalId);
modelBuilder.Entity<Account>()
.HasOne(x => x.Owner)
.WithMany(x => x.Accounts)
.HasForeignKey(x => x.OwnerId);
#endregion Account
#region AccountAccess
modelBuilder.Entity<AccountAccess>()
.HasKey(x => x.Id);
modelBuilder.Entity<AccountAccess>()
.HasOne(x => x.Account)
.WithMany(x => x.AccessRights)
.HasForeignKey(x => x.AccountId);
modelBuilder.Entity<AccountAccess>()
.HasOne(x => x.User)
.WithMany(x => x.AccountAccess)
.HasForeignKey(x => x.UserId);
modelBuilder.Entity<AccountAccess>()
.HasOne(x => x.Owner)
.WithMany(x => x.AccountAccessOwners)
.HasForeignKey(x => x.OwnerId);
modelBuilder
.Entity<AccountAccess>()
.Property(d => d.Type)
.HasConversion(new EnumToStringConverter<AccountAccessTypeEnum>());
modelBuilder.Entity<AccountAccess>()
.HasIndex(p => new { p.AccountId, p.UserId })
.IsUnique();
modelBuilder.Entity<AccountAccess>()
.HasIndex(p => new { p.AccountId, p.OwnerId })
.IsUnique();
#endregion AccountAccess
#region AccountAccessInvite
modelBuilder.Entity<AccountAccessInvite>()
.HasKey(x => x.Id);
modelBuilder.Entity<AccountAccessInvite>()
.HasOne(x => x.User)
.WithMany(x => x.AccountAccessInvites)
.HasForeignKey(x => x.UserId);
modelBuilder.Entity<AccountAccessInvite>()
.HasOne(x => x.Account)
.WithMany(x => x.Invites)
.HasForeignKey(x => x.AccountId);
#endregion AccountAccessInvite
#region Motion
modelBuilder.Entity<Motion>()
.HasKey(x => x.Id);
modelBuilder.Entity<Motion>()
.HasOne(x => x.Account)
.WithMany(x => x.Motions)
.HasForeignKey(x => x.AccountId);
#endregion Motion
#region AccountCategory
modelBuilder.Entity<AccountCategory>()
.HasKey(x => x.Id);
modelBuilder.Entity<AccountCategory>()
.HasOne(x => x.User)
.WithMany(x => x.AccountCategories)
.HasForeignKey(x => x.UserId);
#endregion AccountCategory
#region AccountAccountCategory
modelBuilder.Entity<AccountAccountCategory>()
.HasKey(x => x.Id);
modelBuilder.Entity<AccountAccountCategory>()
.HasOne(x => x.Account)
.WithMany(x => x.Categories)
.HasForeignKey(x => x.AccountId);
modelBuilder.Entity<AccountAccountCategory>()
.HasOne(x => x.Category)
.WithMany(x => x.Accounts)
.HasForeignKey(x => x.CategoryId);
modelBuilder.Entity<AccountAccountCategory>()
.HasIndex(p => new { p.AccountId, p.CategoryId })
.IsUnique();
modelBuilder.Entity<AccountAccountCategory>()
.HasOne(x => x.Category)
.WithMany(x => x.Accounts)
.HasForeignKey(x => x.CategoryId);
#endregion AccountAccountCategory
}
private void MotionsCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ItemGlobal>()
.HasKey(x => x.Id);
modelBuilder.Entity<ItemCategory>()
.HasKey(x => x.Id);
modelBuilder.Entity<Item>()
.HasKey(x => x.Id);
modelBuilder.Entity<Motion>()
.HasKey(x => x.Id);
modelBuilder.Entity<ItemCategory>()
.HasOne(x => x.User)
.WithMany(x => x.ItemCategories)
.HasForeignKey(x => x.UserId);
modelBuilder.Entity<Item>()
.HasOne(x => x.Category)
.WithMany(x => x.Items)
.HasForeignKey(x => x.CategoryId);
modelBuilder.Entity<Item>()
.HasOne(x => x.ItemGlobal)
.WithMany(x => x.Items)
.HasForeignKey(x => x.ItemGlobalId);
modelBuilder.Entity<Motion>()
.HasOne(x => x.Item)
.WithMany(x => x.Motions)
.HasForeignKey(x => x.ItemId);
modelBuilder.Entity<Motion>()
.HasOne(x => x.Account)
.WithMany(x => x.Motions)
.HasForeignKey(x => x.AccountId);
modelBuilder.Entity<Motion>()
.Property(x => x.AmountMinus)
.HasPrecision(18, 6);
modelBuilder.Entity<Motion>()
.Property(x => x.AmountPlus)
.HasPrecision(18, 6);
}
}
+37
View File
@@ -0,0 +1,37 @@
namespace MyOffice.DbContext;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
public class AppDbContextFactory : IDesignTimeDbContextFactory<AppDbContext>
{
public static AppDbContextFactory Instance = new();
public AppDbContext CreateDbContext()
{
return CreateDbContext(null);
}
public AppDbContext CreateDbContext(string[]? args)
{
var connection = RepositoryInitializer.ConnectionString;
if (connection is null)
{
connection = new ConnectionConfiguration(
args?[0] ?? "npgsql",
args?[1] ?? string.Empty);
}
var builder = new DbContextOptionsBuilder<AppDbContext>();
DbContextServiceCollectionExtensions.ConfigureDbContextOptions(builder, connection);
if (!Enum.TryParse<AppDbContextProvidersEnum>(connection?.Provider ?? args?[0] ?? "", ignoreCase: true, out var providerEnum))
throw new InvalidOperationException($"No such provider: [{connection?.Provider}]");
var db = new AppDbContext(providerEnum, builder.Options);
db.ChangeTracker.AutoDetectChangesEnabled = false;
db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
return db;
}
}
@@ -0,0 +1,67 @@
namespace MyOffice.DbContext;
using Data.Models.Currencies;
using Microsoft.EntityFrameworkCore;
/// <summary>
/// Migrate and seed using a DI-scoped <see cref="AppDbContext"/> (not the design-time factory).
/// </summary>
public static class DatabaseBootstrapper
{
public static async Task InitializeAsync(AppDbContext db, CancellationToken cancellationToken = default)
{
await db.Database.MigrateAsync(cancellationToken);
await PrefillAsync(db, cancellationToken);
await DemoDataSeeder.SeedIfEmptyAsync(db, cancellationToken);
await UpdateCurrentRatesAsync(db, cancellationToken);
}
private static async Task PrefillAsync(AppDbContext dbContext, CancellationToken cancellationToken)
{
var predefinedCurrencyGlobals = new List<CurrencyGlobal>
{
new() { Id = CurrencyGlobalIdEnum.UAH.ToString(), DefaultQuantity = 1, Symbol = "₴", Name = "Ukrainian hryvnias" },
new() { Id = CurrencyGlobalIdEnum.USD.ToString(), DefaultQuantity = 1, Symbol = "$", Name = "US Dollar" },
new() { Id = CurrencyGlobalIdEnum.EUR.ToString(), DefaultQuantity = 1, Symbol = "€", Name = "Euros" },
new() { Id = CurrencyGlobalIdEnum.GBP.ToString(), DefaultQuantity = 1, Symbol = "£", Name = "British pounds sterling" },
new() { Id = CurrencyGlobalIdEnum.RUB.ToString(), DefaultQuantity = 10, Symbol = "₽", Name = "Russia Ruble" },
new() { Id = CurrencyGlobalIdEnum.BTC.ToString(), DefaultQuantity = 10, Symbol = "btc", Name = "Bitcoin" },
new() { Id = CurrencyGlobalIdEnum.ETH.ToString(), DefaultQuantity = 10, Symbol = "eth", Name = "Ethereum" },
new() { Id = CurrencyGlobalIdEnum.TON.ToString(), DefaultQuantity = 10, Symbol = "ton", Name = "TON" },
new() { Id = CurrencyGlobalIdEnum.OTHER.ToString(), DefaultQuantity = 1, Symbol = "", Name = "Other" },
};
var currencyGlobals = await dbContext.CurrencyGlobals.ToListAsync(cancellationToken);
foreach (var predefined in predefinedCurrencyGlobals)
{
if (currencyGlobals.All(x => x.Id != predefined.Id))
{
dbContext.CurrencyGlobals.Add(predefined);
}
}
await dbContext.SaveChangesAsync(cancellationToken);
}
private static async Task UpdateCurrentRatesAsync(AppDbContext dbContext, CancellationToken cancellationToken)
{
var lastRates = await dbContext.CurrencyRates
.Include(x => x.Currency)
.GroupBy(x => new { x.CurrencyId },
(key, g) => g.Where(x => x.DateTime <= DateTime.UtcNow).OrderByDescending(x => x.DateTime).First())
.ToListAsync(cancellationToken);
var currencies = await dbContext.Currencies.ToListAsync(cancellationToken);
foreach (var currency in currencies)
{
var rate = lastRates.FirstOrDefault(x => x.CurrencyId == currency.Id);
if (rate != null)
{
currency.CurrentRateId = rate.Id;
dbContext.Attach(currency).State = EntityState.Modified;
}
}
await dbContext.SaveChangesAsync(cancellationToken);
}
}
@@ -0,0 +1,50 @@
namespace MyOffice.DbContext;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
public static class DbContextServiceCollectionExtensions
{
public static IServiceCollection AddAppDbContext(
this IServiceCollection services,
ConnectionConfiguration connection
)
{
services.AddSingleton(connection);
services.AddDbContext<AppDbContext>((_, options) =>
{
ConfigureDbContextOptions(options, connection);
});
return services;
}
public static void ConfigureDbContextOptions(
DbContextOptionsBuilder options,
ConnectionConfiguration connection
)
{
if (!Enum.TryParse<AppDbContextProvidersEnum>(connection.Provider, ignoreCase: true, out var provider))
throw new InvalidOperationException($"No such provider: [{connection.Provider}]");
switch (provider)
{
case AppDbContextProvidersEnum.npgsql:
options.UseNpgsql(connection.ConnectionString, x =>
x.MigrationsAssembly("MyOffice.Migrations.Postgres"));
break;
case AppDbContextProvidersEnum.sqlite:
options.UseSqlite(connection.ConnectionString, x =>
x.MigrationsAssembly("MyOffice.Migrations.Sqlite"));
break;
default:
throw new NotSupportedException($"No such provider: [{connection.Provider}]");
}
#if DEBUG
options.EnableSensitiveDataLogging();
options.EnableDetailedErrors();
#endif
}
}
+292
View File
@@ -0,0 +1,292 @@
namespace MyOffice.DbContext;
using Data.Models.Accounts;
using Data.Models.Currencies;
using Data.Models.Items;
using Data.Models.Users;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
/// <summary>
/// Fills an empty database with three demo users (UAH/USD/EUR) and sample catalog data.
/// </summary>
public static class DemoDataSeeder
{
private static readonly PasswordHasher<object> PasswordHasher = new();
private static readonly string[] CurrencyCodes = ["UAH", "USD", "EUR"];
private static readonly (string Code, string Email, string Password, string FirstName)[] Users =
[
("UAH", "user_UAH@user_UAH.userUAH", "user_UAH", "User UAH"),
("USD", "user_USD@user_USD.userUSD", "user_USD", "User USD"),
("EUR", "user_EUR@user_EUR.userEUR", "user_EUR", "User EUR"),
];
/// <summary>1 USD = 42 UAH, 1 EUR = 50 UAH.</summary>
private const decimal UsdInUah = 42m;
private const decimal EurInUah = 50m;
public static async Task SeedIfEmptyAsync(AppDbContext db, CancellationToken cancellationToken = default)
{
if (await db.Users.AnyAsync(cancellationToken))
{
return;
}
// AppDbContext defaults to NoTracking; seeding needs identity values and graph inserts.
var previousTracking = db.ChangeTracker.QueryTrackingBehavior;
var previousDetect = db.ChangeTracker.AutoDetectChangesEnabled;
db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.TrackAll;
db.ChangeTracker.AutoDetectChangesEnabled = true;
try
{
var yearStart = new DateTime(DateTime.UtcNow.Year, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var rng = new Random(2026);
foreach (var (code, email, password, firstName) in Users)
{
await SeedUserAsync(db, code, email, password, firstName, yearStart, rng, cancellationToken);
}
await db.SaveChangesAsync(cancellationToken);
}
finally
{
db.ChangeTracker.QueryTrackingBehavior = previousTracking;
db.ChangeTracker.AutoDetectChangesEnabled = previousDetect;
db.ChangeTracker.Clear();
}
}
private static async Task SeedUserAsync(
AppDbContext db,
string homeCurrency,
string email,
string password,
string firstName,
DateTime rateDate,
Random rng,
CancellationToken cancellationToken)
{
var ua = homeCurrency == "UAH";
var userId = Guid.NewGuid();
var user = new User
{
Id = userId,
UserName = email,
Email = email,
PasswordHash = PasswordHasher.HashPassword(new object(), password),
FirstName = firstName,
FullName = firstName,
IsEmailConfirmed = true,
CurrencyId = homeCurrency,
};
db.Users.Add(user);
var currencies = new Dictionary<string, Currency>(StringComparer.Ordinal);
foreach (var code in CurrencyCodes)
{
var currency = new Currency
{
Id = Guid.NewGuid(),
UserId = userId,
CurrencyGlobalId = code,
Name = CurrencyDisplayName(code, ua),
ShortName = code,
IsPrimary = code == homeCurrency,
};
db.Currencies.Add(currency);
db.CurrencyRates.Add(new CurrencyRate
{
CurrencyId = currency.Id,
DateTime = rateDate,
Quantity = 1,
Rate = RateInHome(code, homeCurrency),
});
currencies[code] = currency;
}
// UnCategorized convention: category Id == user Id
db.ItemCategories.Add(new ItemCategory
{
Id = userId,
UserId = userId,
Name = ua ? "Без категорії" : "UnCategorized",
Items = [],
IsInternal = true,
});
var accountCategoryDefs = ua
? new (string Key, string Name)[] { ("CASH", "Готівка"), ("BANK", "Банк"), ("DEPOSIT", "Депозит") }
: [("CASH", "CASH"), ("BANK", "BANK"), ("DEPOSIT", "DEPOSIT")];
var accounts = new List<Account>();
foreach (var (key, name) in accountCategoryDefs)
{
var category = new AccountCategory
{
Id = Guid.NewGuid(),
UserId = userId,
Name = name,
};
db.AccountCategories.Add(category);
foreach (var code in CurrencyCodes)
{
var account = new Account
{
Id = Guid.NewGuid(),
OwnerId = userId,
CurrencyGlobalId = code,
Name = $"{name} {code}",
};
db.Accounts.Add(account);
db.AccountAccountCategories.Add(new AccountAccountCategory
{
AccountId = account.Id,
CategoryId = category.Id,
});
db.AccountAccesses.Add(new AccountAccess
{
AccountId = account.Id,
UserId = userId,
OwnerId = userId,
IsAllowRead = true,
IsAllowWrite = true,
IsAllowManage = true,
Type = AccountAccessTypeEnum.balance,
});
accounts.Add(account);
}
}
var incomeCategory = new ItemCategory
{
Id = Guid.NewGuid(),
UserId = userId,
Name = ua ? "Доходи" : "INCOME",
Items = [],
};
var outcomeCategory = new ItemCategory
{
Id = Guid.NewGuid(),
UserId = userId,
Name = ua ? "Витрати" : "OUTCOME",
Items = [],
};
db.ItemCategories.AddRange(incomeCategory, outcomeCategory);
var incomeNames = ua
? new[] { "Готівка", "Офіс" }
: ["CASH", "OFFICE"];
var outcomeNames = ua
? new[]
{
"Товари", "Бензин", "Steam", "Продукти", "Кафе",
"Оренда", "Комунальні", "Інтернет", "Зв'язок", "Розваги",
}
: [
"Goods", "Petrol", "Steam", "Groceries", "Cafe",
"Rent", "Utilities", "Internet", "Mobile", "Entertainment",
];
var incomeItems = await AddItemsAsync(db, incomeCategory.Id, incomeNames, cancellationToken);
var outcomeItems = await AddItemsAsync(db, outcomeCategory.Id, outcomeNames, cancellationToken);
await db.SaveChangesAsync(cancellationToken);
SeedMotions(db, accounts, incomeItems, outcomeItems, rng, count: 100);
}
private static async Task<List<Item>> AddItemsAsync(
AppDbContext db,
Guid categoryId,
IEnumerable<string> names,
CancellationToken cancellationToken)
{
var items = new List<Item>();
foreach (var name in names)
{
var global = db.ItemGlobals.Local.FirstOrDefault(x => x.Name == name)
?? await db.ItemGlobals.FirstOrDefaultAsync(x => x.Name == name, cancellationToken);
if (global == null)
{
global = new ItemGlobal { Id = Guid.NewGuid(), Name = name };
db.ItemGlobals.Add(global);
}
var item = new Item
{
CategoryId = categoryId,
ItemGlobalId = global.Id,
};
db.Items.Add(item);
items.Add(item);
}
return items;
}
private static void SeedMotions(
AppDbContext db,
List<Account> accounts,
List<Item> incomeItems,
List<Item> outcomeItems,
Random rng,
int count)
{
var now = DateTime.UtcNow;
var from = now.AddMonths(-3);
for (var i = 0; i < count; i++)
{
var isIncome = rng.Next(2) == 0;
var item = isIncome
? incomeItems[rng.Next(incomeItems.Count)]
: outcomeItems[rng.Next(outcomeItems.Count)];
var account = accounts[rng.Next(accounts.Count)];
var days = (now - from).TotalDays;
var when = from.AddDays(rng.NextDouble() * days);
var amount = Math.Round((decimal)(rng.NextDouble() * (isIncome ? 4500 : 700) + (isIncome ? 200 : 20)), 2);
db.Motions.Add(new Motion
{
Id = Guid.NewGuid(),
AccountId = account.Id,
ItemId = item.Id,
DateTime = when,
CreatedOn = when,
Description = isIncome ? "Demo income" : "Demo expense",
AmountPlus = isIncome ? amount : 0,
AmountMinus = isIncome ? 0 : amount,
});
}
}
private static decimal RateInHome(string currencyCode, string homeCurrency)
{
static decimal InUah(string code) => code switch
{
"UAH" => 1m,
"USD" => UsdInUah,
"EUR" => EurInUah,
_ => 1m,
};
return InUah(currencyCode) / InUah(homeCurrency);
}
private static string CurrencyDisplayName(string code, bool ua) => (code, ua) switch
{
("UAH", true) => "Гривня",
("USD", true) => "Долар США",
("EUR", true) => "Євро",
("UAH", _) => "Ukrainian hryvnia",
("USD", _) => "US Dollar",
("EUR", _) => "Euro",
_ => code,
};
}
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.10" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="10.0.10" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.3" />
<PackageReference Include="OpenIddict.EntityFrameworkCore" Version="7.6.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyOffice.Data.Models\MyOffice.Data.Models.csproj" />
<ProjectReference Include="..\MyOffice.Shared\MyOffice.Shared.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,23 @@
namespace MyOffice.DbContext;
using Microsoft.Extensions.DependencyInjection;
public record ConnectionConfiguration(string Provider, string ConnectionString);
public static class RepositoryInitializer
{
/// <summary>
/// Registers DbContext DI. Migrate/seed runs via <c>DatabaseInitializerHostedService</c>.
/// <see cref="ConnectionString"/> remains for design-time <see cref="AppDbContextFactory"/>.
/// </summary>
public static void Initialize(
IServiceCollection services,
ConnectionConfiguration connectionString
)
{
ConnectionString = connectionString;
services.AddAppDbContext(connectionString);
}
public static ConnectionConfiguration ConnectionString { get; internal set; } = null!;
}
@@ -0,0 +1,27 @@
namespace MyOffice.Migrations.Postgres;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using MyOffice.DbContext;
using MyOffice.Shared;
public class AppDbContextFactoryPostgres : IDesignTimeDbContextFactory<AppDbContext>
{
public AppDbContext CreateDbContext(string[]? args)
{
var builder = new DbContextOptionsBuilder<AppDbContext>();
var sharedConfiguration = SharedConfiguration.Build();
var connectionString =
args?.FirstOrDefault()
?? sharedConfiguration.GetConnectionString("npgsql");
builder.UseNpgsql(connectionString, b => b.MigrationsAssembly("MyOffice.Migrations.Postgres"));
var db = new AppDbContext(AppDbContextProvidersEnum.npgsql, builder.Options);
db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
return db;
}
}
@@ -0,0 +1,608 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyOffice.DbContext;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20230621190024_Init")]
partial class Init
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
.HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.ToTable("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<bool>("IsAllowManage")
.HasColumnType("boolean");
b.Property<bool>("IsAllowRead")
.HasColumnType("boolean");
b.Property<bool>("IsAllowWrite")
.HasColumnType("boolean");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("UserId");
b.ToTable("AccountAccesses");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("CategoryId");
b.ToTable("AccountAccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<decimal>("AmountMinus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<decimal>("AmountPlus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<int>("ItemId")
.HasColumnType("integer");
b.Property<Guid?>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("ItemId");
b.HasIndex("UserId");
b.ToTable("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("UserId");
b.ToTable("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("DefaultQuantity")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CurrencyId")
.HasColumnType("uuid");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<int>("Quantity")
.HasColumnType("integer");
b.Property<decimal>("Rate")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("CurrencyRates");
});
modelBuilder.Entity("MyOffice.Data.Models.Motions.Item", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.Property<Guid>("ItemGlobalId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CategoryId");
b.HasIndex("ItemGlobalId");
b.ToTable("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Motions.ItemCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ItemCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Motions.ItemGlobal", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("ItemGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("FirstName")
.HasColumnType("text");
b.Property<string>("FullName")
.HasColumnType("text");
b.Property<bool>("IsEmailConfirmed")
.HasColumnType("boolean");
b.Property<string>("LastName")
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.Property<string>("UserName")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("Users");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", 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>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Provider")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("UserClaims");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Accounts")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("AccessRights")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountAccess")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Categories")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
.WithMany("Accounts")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("Category");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Motions")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Motions.Item", "Item")
.WithMany("Motions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", null)
.WithMany("AccountMotions")
.HasForeignKey("UserId");
b.Navigation("Account");
b.Navigation("Item");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Currencies")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("Currencies")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
.WithMany("Rates")
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Motions.Item", b =>
{
b.HasOne("MyOffice.Data.Models.Motions.ItemCategory", "Category")
.WithMany("Items")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Motions.ItemGlobal", "ItemGlobal")
.WithMany("Items")
.HasForeignKey("ItemGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Category");
b.Navigation("ItemGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Motions.ItemCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("ItemCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("UserClaims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Navigation("AccessRights");
b.Navigation("Categories");
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Navigation("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Navigation("Rates");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Navigation("Accounts");
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Motions.Item", b =>
{
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Motions.ItemCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Motions.ItemGlobal", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Navigation("AccountAccess");
b.Navigation("AccountCategories");
b.Navigation("AccountMotions");
b.Navigation("Currencies");
b.Navigation("ItemCategories");
b.Navigation("UserClaims");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,445 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
/// <inheritdoc />
public partial class Init : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterDatabase()
.Annotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False");
migrationBuilder.CreateTable(
name: "CurrencyGlobals",
columns: table => new
{
Id = table.Column<string>(type: "text", nullable: false),
Name = table.Column<string>(type: "text", nullable: false),
Symbol = table.Column<string>(type: "text", nullable: false),
DefaultQuantity = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_CurrencyGlobals", x => x.Id);
});
migrationBuilder.CreateTable(
name: "ItemGlobals",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
Name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ItemGlobals", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Accounts",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
CurrencyGlobalId = table.Column<string>(type: "text", nullable: false),
Name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Accounts", x => x.Id);
table.ForeignKey(
name: "FK_Accounts_CurrencyGlobals_CurrencyGlobalId",
column: x => x.CurrencyGlobalId,
principalTable: "CurrencyGlobals",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Users",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
UserName = table.Column<string>(type: "text", nullable: false, collation: "my_ci_collation"),
Email = table.Column<string>(type: "text", nullable: false, collation: "my_ci_collation"),
PasswordHash = table.Column<string>(type: "text", nullable: false),
FirstName = table.Column<string>(type: "text", nullable: true),
LastName = table.Column<string>(type: "text", nullable: true),
FullName = table.Column<string>(type: "text", nullable: true),
Phone = table.Column<string>(type: "text", nullable: true),
IsEmailConfirmed = table.Column<bool>(type: "boolean", nullable: false),
CurrencyId = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Users", x => x.Id);
table.ForeignKey(
name: "FK_Users_CurrencyGlobals_CurrencyId",
column: x => x.CurrencyId,
principalTable: "CurrencyGlobals",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AccountAccesses",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
AccountId = table.Column<Guid>(type: "uuid", nullable: false),
UserId = table.Column<Guid>(type: "uuid", nullable: false),
IsAllowRead = table.Column<bool>(type: "boolean", nullable: false),
IsAllowWrite = table.Column<bool>(type: "boolean", nullable: false),
IsAllowManage = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AccountAccesses", x => x.Id);
table.ForeignKey(
name: "FK_AccountAccesses_Accounts_AccountId",
column: x => x.AccountId,
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AccountAccesses_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AccountCategories",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
UserId = table.Column<Guid>(type: "uuid", nullable: false),
Name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AccountCategories", x => x.Id);
table.ForeignKey(
name: "FK_AccountCategories_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Currencies",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
CurrencyGlobalId = table.Column<string>(type: "text", nullable: false),
UserId = table.Column<Guid>(type: "uuid", nullable: false),
Name = table.Column<string>(type: "text", nullable: false),
ShortName = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Currencies", x => x.Id);
table.ForeignKey(
name: "FK_Currencies_CurrencyGlobals_CurrencyGlobalId",
column: x => x.CurrencyGlobalId,
principalTable: "CurrencyGlobals",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Currencies_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "ItemCategories",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
UserId = table.Column<Guid>(type: "uuid", nullable: false),
Name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ItemCategories", x => x.Id);
table.ForeignKey(
name: "FK_ItemCategories_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "UserClaims",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
UserId = table.Column<Guid>(type: "uuid", nullable: false),
ExternalId = table.Column<string>(type: "text", nullable: false),
Email = table.Column<string>(type: "text", nullable: false, collation: "my_ci_collation"),
Provider = table.Column<string>(type: "text", nullable: false, collation: "my_ci_collation")
},
constraints: table =>
{
table.PrimaryKey("PK_UserClaims", x => x.Id);
table.ForeignKey(
name: "FK_UserClaims_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AccountAccountCategories",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
AccountId = table.Column<Guid>(type: "uuid", nullable: false),
CategoryId = table.Column<Guid>(type: "uuid", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AccountAccountCategories", x => x.Id);
table.ForeignKey(
name: "FK_AccountAccountCategories_AccountCategories_CategoryId",
column: x => x.CategoryId,
principalTable: "AccountCategories",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AccountAccountCategories_Accounts_AccountId",
column: x => x.AccountId,
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "CurrencyRates",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
CurrencyId = table.Column<Guid>(type: "uuid", nullable: false),
DateTime = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
Quantity = table.Column<int>(type: "integer", nullable: false),
Rate = table.Column<decimal>(type: "numeric", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_CurrencyRates", x => x.Id);
table.ForeignKey(
name: "FK_CurrencyRates_Currencies_CurrencyId",
column: x => x.CurrencyId,
principalTable: "Currencies",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Items",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
CategoryId = table.Column<Guid>(type: "uuid", nullable: false),
ItemGlobalId = table.Column<Guid>(type: "uuid", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Items", x => x.Id);
table.ForeignKey(
name: "FK_Items_ItemCategories_CategoryId",
column: x => x.CategoryId,
principalTable: "ItemCategories",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Items_ItemGlobals_ItemGlobalId",
column: x => x.ItemGlobalId,
principalTable: "ItemGlobals",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Motions",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
DateTime = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
AccountId = table.Column<Guid>(type: "uuid", nullable: false),
ItemId = table.Column<int>(type: "integer", nullable: false),
Description = table.Column<string>(type: "text", nullable: true),
AmountPlus = table.Column<decimal>(type: "numeric(18,6)", precision: 18, scale: 6, nullable: false),
AmountMinus = table.Column<decimal>(type: "numeric(18,6)", precision: 18, scale: 6, nullable: false),
UserId = table.Column<Guid>(type: "uuid", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Motions", x => x.Id);
table.ForeignKey(
name: "FK_Motions_Accounts_AccountId",
column: x => x.AccountId,
principalTable: "Accounts",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Motions_Items_ItemId",
column: x => x.ItemId,
principalTable: "Items",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Motions_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id");
});
migrationBuilder.CreateIndex(
name: "IX_AccountAccesses_AccountId",
table: "AccountAccesses",
column: "AccountId");
migrationBuilder.CreateIndex(
name: "IX_AccountAccesses_UserId",
table: "AccountAccesses",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AccountAccountCategories_AccountId",
table: "AccountAccountCategories",
column: "AccountId");
migrationBuilder.CreateIndex(
name: "IX_AccountAccountCategories_CategoryId",
table: "AccountAccountCategories",
column: "CategoryId");
migrationBuilder.CreateIndex(
name: "IX_AccountCategories_UserId",
table: "AccountCategories",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Accounts_CurrencyGlobalId",
table: "Accounts",
column: "CurrencyGlobalId");
migrationBuilder.CreateIndex(
name: "IX_Currencies_CurrencyGlobalId",
table: "Currencies",
column: "CurrencyGlobalId");
migrationBuilder.CreateIndex(
name: "IX_Currencies_UserId",
table: "Currencies",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_CurrencyRates_CurrencyId",
table: "CurrencyRates",
column: "CurrencyId");
migrationBuilder.CreateIndex(
name: "IX_ItemCategories_UserId",
table: "ItemCategories",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Items_CategoryId",
table: "Items",
column: "CategoryId");
migrationBuilder.CreateIndex(
name: "IX_Items_ItemGlobalId",
table: "Items",
column: "ItemGlobalId");
migrationBuilder.CreateIndex(
name: "IX_Motions_AccountId",
table: "Motions",
column: "AccountId");
migrationBuilder.CreateIndex(
name: "IX_Motions_ItemId",
table: "Motions",
column: "ItemId");
migrationBuilder.CreateIndex(
name: "IX_Motions_UserId",
table: "Motions",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_UserClaims_UserId",
table: "UserClaims",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Users_CurrencyId",
table: "Users",
column: "CurrencyId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AccountAccesses");
migrationBuilder.DropTable(
name: "AccountAccountCategories");
migrationBuilder.DropTable(
name: "CurrencyRates");
migrationBuilder.DropTable(
name: "Motions");
migrationBuilder.DropTable(
name: "UserClaims");
migrationBuilder.DropTable(
name: "AccountCategories");
migrationBuilder.DropTable(
name: "Currencies");
migrationBuilder.DropTable(
name: "Accounts");
migrationBuilder.DropTable(
name: "Items");
migrationBuilder.DropTable(
name: "ItemCategories");
migrationBuilder.DropTable(
name: "ItemGlobals");
migrationBuilder.DropTable(
name: "Users");
migrationBuilder.DropTable(
name: "CurrencyGlobals");
}
}
}
@@ -0,0 +1,611 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyOffice.DbContext;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20230627044606_IsInternal")]
partial class IsInternal
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
.HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.ToTable("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<bool>("IsAllowManage")
.HasColumnType("boolean");
b.Property<bool>("IsAllowRead")
.HasColumnType("boolean");
b.Property<bool>("IsAllowWrite")
.HasColumnType("boolean");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("UserId");
b.ToTable("AccountAccesses");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("CategoryId");
b.ToTable("AccountAccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<decimal>("AmountMinus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<decimal>("AmountPlus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<int>("ItemId")
.HasColumnType("integer");
b.Property<Guid?>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("ItemId");
b.HasIndex("UserId");
b.ToTable("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("UserId");
b.ToTable("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("DefaultQuantity")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CurrencyId")
.HasColumnType("uuid");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<int>("Quantity")
.HasColumnType("integer");
b.Property<decimal>("Rate")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("CurrencyRates");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.Property<Guid>("ItemGlobalId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CategoryId");
b.HasIndex("ItemGlobalId");
b.ToTable("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("IsInternal")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ItemCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("ItemGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("FirstName")
.HasColumnType("text");
b.Property<string>("FullName")
.HasColumnType("text");
b.Property<bool>("IsEmailConfirmed")
.HasColumnType("boolean");
b.Property<string>("LastName")
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.Property<string>("UserName")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("Users");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", 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>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Provider")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("UserClaims");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Accounts")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("AccessRights")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountAccess")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Categories")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
.WithMany("Accounts")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("Category");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Motions")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
.WithMany("Motions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", null)
.WithMany("AccountMotions")
.HasForeignKey("UserId");
b.Navigation("Account");
b.Navigation("Item");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Currencies")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("Currencies")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
.WithMany("Rates")
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
.WithMany("Items")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
.WithMany("Items")
.HasForeignKey("ItemGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Category");
b.Navigation("ItemGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("ItemCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("UserClaims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Navigation("AccessRights");
b.Navigation("Categories");
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Navigation("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Navigation("Rates");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Navigation("Accounts");
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Navigation("AccountAccess");
b.Navigation("AccountCategories");
b.Navigation("AccountMotions");
b.Navigation("Currencies");
b.Navigation("ItemCategories");
b.Navigation("UserClaims");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
/// <inheritdoc />
public partial class IsInternal : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsInternal",
table: "ItemCategories",
type: "boolean",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsInternal",
table: "ItemCategories");
}
}
}
@@ -0,0 +1,617 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyOffice.DbContext;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20230720190103_PrimaryCurrencyDeletedMotion")]
partial class PrimaryCurrencyDeletedMotion
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
.HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.ToTable("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<bool>("IsAllowManage")
.HasColumnType("boolean");
b.Property<bool>("IsAllowRead")
.HasColumnType("boolean");
b.Property<bool>("IsAllowWrite")
.HasColumnType("boolean");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("UserId");
b.ToTable("AccountAccesses");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("CategoryId");
b.ToTable("AccountAccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<decimal>("AmountMinus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<decimal>("AmountPlus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<DateTime?>("DeletedOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<int>("ItemId")
.HasColumnType("integer");
b.Property<Guid?>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("ItemId");
b.HasIndex("UserId");
b.ToTable("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsPrimary")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("UserId");
b.ToTable("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("DefaultQuantity")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CurrencyId")
.HasColumnType("uuid");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<int>("Quantity")
.HasColumnType("integer");
b.Property<decimal>("Rate")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("CurrencyRates");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.Property<Guid>("ItemGlobalId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CategoryId");
b.HasIndex("ItemGlobalId");
b.ToTable("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("IsInternal")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ItemCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("ItemGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("FirstName")
.HasColumnType("text");
b.Property<string>("FullName")
.HasColumnType("text");
b.Property<bool>("IsEmailConfirmed")
.HasColumnType("boolean");
b.Property<string>("LastName")
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.Property<string>("UserName")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("Users");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", 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>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Provider")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("UserClaims");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Accounts")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("AccessRights")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountAccess")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Categories")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
.WithMany("Accounts")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("Category");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Motions")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
.WithMany("Motions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", null)
.WithMany("AccountMotions")
.HasForeignKey("UserId");
b.Navigation("Account");
b.Navigation("Item");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Currencies")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("Currencies")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
.WithMany("Rates")
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
.WithMany("Items")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
.WithMany("Items")
.HasForeignKey("ItemGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Category");
b.Navigation("ItemGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("ItemCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("UserClaims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Navigation("AccessRights");
b.Navigation("Categories");
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Navigation("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Navigation("Rates");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Navigation("Accounts");
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Navigation("AccountAccess");
b.Navigation("AccountCategories");
b.Navigation("AccountMotions");
b.Navigation("Currencies");
b.Navigation("ItemCategories");
b.Navigation("UserClaims");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,40 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
/// <inheritdoc />
public partial class PrimaryCurrencyDeletedMotion : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "DeletedOn",
table: "Motions",
type: "timestamp with time zone",
nullable: true);
migrationBuilder.AddColumn<bool>(
name: "IsPrimary",
table: "Currencies",
type: "boolean",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "DeletedOn",
table: "Motions");
migrationBuilder.DropColumn(
name: "IsPrimary",
table: "Currencies");
}
}
}
@@ -0,0 +1,631 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyOffice.DbContext;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20230721175243_CurrentRate")]
partial class CurrentRate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
.HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.ToTable("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<bool>("IsAllowManage")
.HasColumnType("boolean");
b.Property<bool>("IsAllowRead")
.HasColumnType("boolean");
b.Property<bool>("IsAllowWrite")
.HasColumnType("boolean");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("UserId");
b.ToTable("AccountAccesses");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("CategoryId");
b.ToTable("AccountAccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<decimal>("AmountMinus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<decimal>("AmountPlus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<DateTime?>("DeletedOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<int>("ItemId")
.HasColumnType("integer");
b.Property<Guid?>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("ItemId");
b.HasIndex("UserId");
b.ToTable("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("CurrentRateId")
.HasColumnType("integer");
b.Property<int?>("CurrentRateId1")
.HasColumnType("integer");
b.Property<bool>("IsPrimary")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("CurrentRateId1");
b.HasIndex("UserId");
b.ToTable("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("DefaultQuantity")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CurrencyId")
.HasColumnType("uuid");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<int>("Quantity")
.HasColumnType("integer");
b.Property<decimal>("Rate")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("CurrencyRates");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.Property<Guid>("ItemGlobalId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CategoryId");
b.HasIndex("ItemGlobalId");
b.ToTable("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("IsInternal")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ItemCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("ItemGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("FirstName")
.HasColumnType("text");
b.Property<string>("FullName")
.HasColumnType("text");
b.Property<bool>("IsEmailConfirmed")
.HasColumnType("boolean");
b.Property<string>("LastName")
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.Property<string>("UserName")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("Users");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", 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>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Provider")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("UserClaims");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Accounts")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("AccessRights")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountAccess")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Categories")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
.WithMany("Accounts")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("Category");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Motions")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
.WithMany("Motions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", null)
.WithMany("AccountMotions")
.HasForeignKey("UserId");
b.Navigation("Account");
b.Navigation("Item");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Currencies")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate")
.WithMany()
.HasForeignKey("CurrentRateId1");
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("Currencies")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
b.Navigation("CurrentRate");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
.WithMany("Rates")
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
.WithMany("Items")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
.WithMany("Items")
.HasForeignKey("ItemGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Category");
b.Navigation("ItemGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("ItemCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("UserClaims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Navigation("AccessRights");
b.Navigation("Categories");
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Navigation("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Navigation("Rates");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Navigation("Accounts");
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Navigation("AccountAccess");
b.Navigation("AccountCategories");
b.Navigation("AccountMotions");
b.Navigation("Currencies");
b.Navigation("ItemCategories");
b.Navigation("UserClaims");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,58 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
/// <inheritdoc />
public partial class CurrentRate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "CurrentRateId",
table: "Currencies",
type: "integer",
nullable: true);
migrationBuilder.AddColumn<int>(
name: "CurrentRateId1",
table: "Currencies",
type: "integer",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Currencies_CurrentRateId1",
table: "Currencies",
column: "CurrentRateId1");
migrationBuilder.AddForeignKey(
name: "FK_Currencies_CurrencyRates_CurrentRateId1",
table: "Currencies",
column: "CurrentRateId1",
principalTable: "CurrencyRates",
principalColumn: "Id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Currencies_CurrencyRates_CurrentRateId1",
table: "Currencies");
migrationBuilder.DropIndex(
name: "IX_Currencies_CurrentRateId1",
table: "Currencies");
migrationBuilder.DropColumn(
name: "CurrentRateId",
table: "Currencies");
migrationBuilder.DropColumn(
name: "CurrentRateId1",
table: "Currencies");
}
}
}
@@ -0,0 +1,617 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyOffice.DbContext;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20230721180304_CurrentRateRemove")]
partial class CurrentRateRemove
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
.HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.ToTable("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<bool>("IsAllowManage")
.HasColumnType("boolean");
b.Property<bool>("IsAllowRead")
.HasColumnType("boolean");
b.Property<bool>("IsAllowWrite")
.HasColumnType("boolean");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("UserId");
b.ToTable("AccountAccesses");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("CategoryId");
b.ToTable("AccountAccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<decimal>("AmountMinus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<decimal>("AmountPlus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<DateTime?>("DeletedOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<int>("ItemId")
.HasColumnType("integer");
b.Property<Guid?>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("ItemId");
b.HasIndex("UserId");
b.ToTable("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<bool>("IsPrimary")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("UserId");
b.ToTable("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("DefaultQuantity")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CurrencyId")
.HasColumnType("uuid");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<int>("Quantity")
.HasColumnType("integer");
b.Property<decimal>("Rate")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("CurrencyRates");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.Property<Guid>("ItemGlobalId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CategoryId");
b.HasIndex("ItemGlobalId");
b.ToTable("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("IsInternal")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ItemCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("ItemGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("FirstName")
.HasColumnType("text");
b.Property<string>("FullName")
.HasColumnType("text");
b.Property<bool>("IsEmailConfirmed")
.HasColumnType("boolean");
b.Property<string>("LastName")
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.Property<string>("UserName")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("Users");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", 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>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Provider")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("UserClaims");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Accounts")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("AccessRights")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountAccess")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Categories")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
.WithMany("Accounts")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("Category");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Motions")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
.WithMany("Motions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", null)
.WithMany("AccountMotions")
.HasForeignKey("UserId");
b.Navigation("Account");
b.Navigation("Item");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Currencies")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("Currencies")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
.WithMany("Rates")
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
.WithMany("Items")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
.WithMany("Items")
.HasForeignKey("ItemGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Category");
b.Navigation("ItemGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("ItemCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("UserClaims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Navigation("AccessRights");
b.Navigation("Categories");
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Navigation("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Navigation("Rates");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Navigation("Accounts");
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Navigation("AccountAccess");
b.Navigation("AccountCategories");
b.Navigation("AccountMotions");
b.Navigation("Currencies");
b.Navigation("ItemCategories");
b.Navigation("UserClaims");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,58 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
/// <inheritdoc />
public partial class CurrentRateRemove : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Currencies_CurrencyRates_CurrentRateId1",
table: "Currencies");
migrationBuilder.DropIndex(
name: "IX_Currencies_CurrentRateId1",
table: "Currencies");
migrationBuilder.DropColumn(
name: "CurrentRateId",
table: "Currencies");
migrationBuilder.DropColumn(
name: "CurrentRateId1",
table: "Currencies");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "CurrentRateId",
table: "Currencies",
type: "integer",
nullable: true);
migrationBuilder.AddColumn<int>(
name: "CurrentRateId1",
table: "Currencies",
type: "integer",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Currencies_CurrentRateId1",
table: "Currencies",
column: "CurrentRateId1");
migrationBuilder.AddForeignKey(
name: "FK_Currencies_CurrencyRates_CurrentRateId1",
table: "Currencies",
column: "CurrentRateId1",
principalTable: "CurrencyRates",
principalColumn: "Id");
}
}
}
@@ -0,0 +1,633 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyOffice.DbContext;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20230721180851_CurrentRateV2")]
partial class CurrentRateV2
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
.HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.ToTable("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<bool>("IsAllowManage")
.HasColumnType("boolean");
b.Property<bool>("IsAllowRead")
.HasColumnType("boolean");
b.Property<bool>("IsAllowWrite")
.HasColumnType("boolean");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("UserId");
b.ToTable("AccountAccesses");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("CategoryId");
b.ToTable("AccountAccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<decimal>("AmountMinus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<decimal>("AmountPlus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<DateTime?>("DeletedOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<int>("ItemId")
.HasColumnType("integer");
b.Property<Guid?>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("ItemId");
b.HasIndex("UserId");
b.ToTable("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("CurrentRateId")
.HasColumnType("integer");
b.Property<bool>("IsPrimary")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("CurrentRateId");
b.HasIndex("UserId");
b.ToTable("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("DefaultQuantity")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CurrencyId")
.HasColumnType("uuid");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<int>("Quantity")
.HasColumnType("integer");
b.Property<decimal>("Rate")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("CurrencyRates");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.Property<Guid>("ItemGlobalId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CategoryId");
b.HasIndex("ItemGlobalId");
b.ToTable("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("IsInternal")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ItemCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("ItemGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("FirstName")
.HasColumnType("text");
b.Property<string>("FullName")
.HasColumnType("text");
b.Property<bool>("IsEmailConfirmed")
.HasColumnType("boolean");
b.Property<string>("LastName")
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.Property<string>("UserName")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("Users");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", 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>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Provider")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("UserClaims");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Accounts")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("AccessRights")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountAccess")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Categories")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
.WithMany("Accounts")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("Category");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Motions")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
.WithMany("Motions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", null)
.WithMany("AccountMotions")
.HasForeignKey("UserId");
b.Navigation("Account");
b.Navigation("Item");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Currencies")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate")
.WithMany("Currencies")
.HasForeignKey("CurrentRateId");
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("Currencies")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
b.Navigation("CurrentRate");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
.WithMany("Rates")
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
.WithMany("Items")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
.WithMany("Items")
.HasForeignKey("ItemGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Category");
b.Navigation("ItemGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("ItemCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("UserClaims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Navigation("AccessRights");
b.Navigation("Categories");
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Navigation("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Navigation("Rates");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Navigation("Accounts");
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Navigation("AccountAccess");
b.Navigation("AccountCategories");
b.Navigation("AccountMotions");
b.Navigation("Currencies");
b.Navigation("ItemCategories");
b.Navigation("UserClaims");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,48 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
/// <inheritdoc />
public partial class CurrentRateV2 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "CurrentRateId",
table: "Currencies",
type: "integer",
nullable: true);
migrationBuilder.CreateIndex(
name: "IX_Currencies_CurrentRateId",
table: "Currencies",
column: "CurrentRateId");
migrationBuilder.AddForeignKey(
name: "FK_Currencies_CurrencyRates_CurrentRateId",
table: "Currencies",
column: "CurrentRateId",
principalTable: "CurrencyRates",
principalColumn: "Id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Currencies_CurrencyRates_CurrentRateId",
table: "Currencies");
migrationBuilder.DropIndex(
name: "IX_Currencies_CurrentRateId",
table: "Currencies");
migrationBuilder.DropColumn(
name: "CurrentRateId",
table: "Currencies");
}
}
}
@@ -0,0 +1,636 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyOffice.DbContext;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20230721200424_AccountType")]
partial class AccountType
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
.HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<int>("Type")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.ToTable("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<bool>("IsAllowManage")
.HasColumnType("boolean");
b.Property<bool>("IsAllowRead")
.HasColumnType("boolean");
b.Property<bool>("IsAllowWrite")
.HasColumnType("boolean");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("UserId");
b.ToTable("AccountAccesses");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("CategoryId");
b.ToTable("AccountAccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<decimal>("AmountMinus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<decimal>("AmountPlus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<DateTime?>("DeletedOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<int>("ItemId")
.HasColumnType("integer");
b.Property<Guid?>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("ItemId");
b.HasIndex("UserId");
b.ToTable("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("CurrentRateId")
.HasColumnType("integer");
b.Property<bool>("IsPrimary")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("CurrentRateId");
b.HasIndex("UserId");
b.ToTable("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("DefaultQuantity")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CurrencyId")
.HasColumnType("uuid");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<int>("Quantity")
.HasColumnType("integer");
b.Property<decimal>("Rate")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("CurrencyRates");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.Property<Guid>("ItemGlobalId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CategoryId");
b.HasIndex("ItemGlobalId");
b.ToTable("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("IsInternal")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ItemCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("ItemGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("FirstName")
.HasColumnType("text");
b.Property<string>("FullName")
.HasColumnType("text");
b.Property<bool>("IsEmailConfirmed")
.HasColumnType("boolean");
b.Property<string>("LastName")
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.Property<string>("UserName")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("Users");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", 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>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Provider")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("UserClaims");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Accounts")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("AccessRights")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountAccess")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Categories")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
.WithMany("Accounts")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("Category");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Motions")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
.WithMany("Motions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", null)
.WithMany("AccountMotions")
.HasForeignKey("UserId");
b.Navigation("Account");
b.Navigation("Item");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Currencies")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate")
.WithMany("Currencies")
.HasForeignKey("CurrentRateId");
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("Currencies")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
b.Navigation("CurrentRate");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
.WithMany("Rates")
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
.WithMany("Items")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
.WithMany("Items")
.HasForeignKey("ItemGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Category");
b.Navigation("ItemGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("ItemCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("UserClaims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Navigation("AccessRights");
b.Navigation("Categories");
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Navigation("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Navigation("Rates");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Navigation("Accounts");
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Navigation("AccountAccess");
b.Navigation("AccountCategories");
b.Navigation("AccountMotions");
b.Navigation("Currencies");
b.Navigation("ItemCategories");
b.Navigation("UserClaims");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
/// <inheritdoc />
public partial class AccountType : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "Type",
table: "Accounts",
type: "integer",
nullable: false,
defaultValue: 0);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Type",
table: "Accounts");
}
}
}
@@ -0,0 +1,637 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyOffice.DbContext;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20230722051335_AccountType2")]
partial class AccountType2
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
.HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.ToTable("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<bool>("IsAllowManage")
.HasColumnType("boolean");
b.Property<bool>("IsAllowRead")
.HasColumnType("boolean");
b.Property<bool>("IsAllowWrite")
.HasColumnType("boolean");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("UserId");
b.ToTable("AccountAccesses");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("CategoryId");
b.ToTable("AccountAccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<decimal>("AmountMinus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<decimal>("AmountPlus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<DateTime?>("DeletedOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<int>("ItemId")
.HasColumnType("integer");
b.Property<Guid?>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("ItemId");
b.HasIndex("UserId");
b.ToTable("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("CurrentRateId")
.HasColumnType("integer");
b.Property<bool>("IsPrimary")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("CurrentRateId");
b.HasIndex("UserId");
b.ToTable("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("DefaultQuantity")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CurrencyId")
.HasColumnType("uuid");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<int>("Quantity")
.HasColumnType("integer");
b.Property<decimal>("Rate")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("CurrencyRates");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.Property<Guid>("ItemGlobalId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CategoryId");
b.HasIndex("ItemGlobalId");
b.ToTable("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("IsInternal")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ItemCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("ItemGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("FirstName")
.HasColumnType("text");
b.Property<string>("FullName")
.HasColumnType("text");
b.Property<bool>("IsEmailConfirmed")
.HasColumnType("boolean");
b.Property<string>("LastName")
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.Property<string>("UserName")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("Users");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", 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>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Provider")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("UserClaims");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Accounts")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("AccessRights")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountAccess")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Categories")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
.WithMany("Accounts")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("Category");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Motions")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
.WithMany("Motions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", null)
.WithMany("AccountMotions")
.HasForeignKey("UserId");
b.Navigation("Account");
b.Navigation("Item");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Currencies")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate")
.WithMany("Currencies")
.HasForeignKey("CurrentRateId");
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("Currencies")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
b.Navigation("CurrentRate");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
.WithMany("Rates")
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
.WithMany("Items")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
.WithMany("Items")
.HasForeignKey("ItemGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Category");
b.Navigation("ItemGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("ItemCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("UserClaims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Navigation("AccessRights");
b.Navigation("Categories");
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Navigation("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Navigation("Rates");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Navigation("Accounts");
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Navigation("AccountAccess");
b.Navigation("AccountCategories");
b.Navigation("AccountMotions");
b.Navigation("Currencies");
b.Navigation("ItemCategories");
b.Navigation("UserClaims");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
/// <inheritdoc />
public partial class AccountType2 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Type",
table: "AccountAccesses",
type: "text",
nullable: false,
defaultValue: "");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Type",
table: "AccountAccesses");
}
}
}
@@ -0,0 +1,650 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyOffice.DbContext;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20230722052053_AccountOwner")]
partial class AccountOwner
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
.HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid?>("OwnerId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("OwnerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<bool>("IsAllowManage")
.HasColumnType("boolean");
b.Property<bool>("IsAllowRead")
.HasColumnType("boolean");
b.Property<bool>("IsAllowWrite")
.HasColumnType("boolean");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("UserId");
b.ToTable("AccountAccesses");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("CategoryId");
b.ToTable("AccountAccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<decimal>("AmountMinus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<decimal>("AmountPlus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<DateTime?>("DeletedOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<int>("ItemId")
.HasColumnType("integer");
b.Property<Guid?>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("ItemId");
b.HasIndex("UserId");
b.ToTable("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("CurrentRateId")
.HasColumnType("integer");
b.Property<bool>("IsPrimary")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("CurrentRateId");
b.HasIndex("UserId");
b.ToTable("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("DefaultQuantity")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CurrencyId")
.HasColumnType("uuid");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<int>("Quantity")
.HasColumnType("integer");
b.Property<decimal>("Rate")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("CurrencyRates");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.Property<Guid>("ItemGlobalId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CategoryId");
b.HasIndex("ItemGlobalId");
b.ToTable("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("IsInternal")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ItemCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("ItemGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("FirstName")
.HasColumnType("text");
b.Property<string>("FullName")
.HasColumnType("text");
b.Property<bool>("IsEmailConfirmed")
.HasColumnType("boolean");
b.Property<string>("LastName")
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.Property<string>("UserName")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("Users");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", 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>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Provider")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("UserClaims");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Accounts")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "Owner")
.WithMany("Accounts")
.HasForeignKey("OwnerId");
b.Navigation("CurrencyGlobal");
b.Navigation("Owner");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("AccessRights")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountAccess")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Categories")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
.WithMany("Accounts")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("Category");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Motions")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
.WithMany("Motions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", null)
.WithMany("AccountMotions")
.HasForeignKey("UserId");
b.Navigation("Account");
b.Navigation("Item");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Currencies")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate")
.WithMany("Currencies")
.HasForeignKey("CurrentRateId");
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("Currencies")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
b.Navigation("CurrentRate");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
.WithMany("Rates")
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
.WithMany("Items")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
.WithMany("Items")
.HasForeignKey("ItemGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Category");
b.Navigation("ItemGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("ItemCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("UserClaims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Navigation("AccessRights");
b.Navigation("Categories");
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Navigation("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Navigation("Rates");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Navigation("Accounts");
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Navigation("AccountAccess");
b.Navigation("AccountCategories");
b.Navigation("AccountMotions");
b.Navigation("Accounts");
b.Navigation("Currencies");
b.Navigation("ItemCategories");
b.Navigation("UserClaims");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,49 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
/// <inheritdoc />
public partial class AccountOwner : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "OwnerId",
table: "Accounts",
type: "uuid",
nullable: true);
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");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Accounts_Users_OwnerId",
table: "Accounts");
migrationBuilder.DropIndex(
name: "IX_Accounts_OwnerId",
table: "Accounts");
migrationBuilder.DropColumn(
name: "OwnerId",
table: "Accounts");
}
}
}
@@ -0,0 +1,652 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyOffice.DbContext;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20230725054028_Collation")]
partial class Collation
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
.HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<Guid?>("OwnerId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("OwnerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<bool>("IsAllowManage")
.HasColumnType("boolean");
b.Property<bool>("IsAllowRead")
.HasColumnType("boolean");
b.Property<bool>("IsAllowWrite")
.HasColumnType("boolean");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("UserId");
b.ToTable("AccountAccesses");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("CategoryId");
b.ToTable("AccountAccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<decimal>("AmountMinus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<decimal>("AmountPlus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<DateTime?>("DeletedOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<int>("ItemId")
.HasColumnType("integer");
b.Property<Guid?>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("ItemId");
b.HasIndex("UserId");
b.ToTable("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("CurrentRateId")
.HasColumnType("integer");
b.Property<bool>("IsPrimary")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("CurrentRateId");
b.HasIndex("UserId");
b.ToTable("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("DefaultQuantity")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CurrencyId")
.HasColumnType("uuid");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<int>("Quantity")
.HasColumnType("integer");
b.Property<decimal>("Rate")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("CurrencyRates");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.Property<Guid>("ItemGlobalId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CategoryId");
b.HasIndex("ItemGlobalId");
b.ToTable("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("IsInternal")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ItemCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.HasKey("Id");
b.ToTable("ItemGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("FirstName")
.HasColumnType("text");
b.Property<string>("FullName")
.HasColumnType("text");
b.Property<bool>("IsEmailConfirmed")
.HasColumnType("boolean");
b.Property<string>("LastName")
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.Property<string>("UserName")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("Users");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", 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>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Provider")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("UserClaims");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Accounts")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "Owner")
.WithMany("Accounts")
.HasForeignKey("OwnerId");
b.Navigation("CurrencyGlobal");
b.Navigation("Owner");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("AccessRights")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountAccess")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Categories")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
.WithMany("Accounts")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("Category");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Motions")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
.WithMany("Motions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", null)
.WithMany("AccountMotions")
.HasForeignKey("UserId");
b.Navigation("Account");
b.Navigation("Item");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Currencies")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate")
.WithMany("Currencies")
.HasForeignKey("CurrentRateId");
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("Currencies")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
b.Navigation("CurrentRate");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
.WithMany("Rates")
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
.WithMany("Items")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
.WithMany("Items")
.HasForeignKey("ItemGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Category");
b.Navigation("ItemGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("ItemCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("UserClaims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Navigation("AccessRights");
b.Navigation("Categories");
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Navigation("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Navigation("Rates");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Navigation("Accounts");
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Navigation("AccountAccess");
b.Navigation("AccountCategories");
b.Navigation("AccountMotions");
b.Navigation("Accounts");
b.Navigation("Currencies");
b.Navigation("ItemCategories");
b.Navigation("UserClaims");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,54 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
/// <inheritdoc />
public partial class Collation : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "ItemGlobals",
type: "text",
nullable: false,
collation: "my_ci_collation",
oldClrType: typeof(string),
oldType: "text");
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "Accounts",
type: "text",
nullable: false,
collation: "my_ci_collation",
oldClrType: typeof(string),
oldType: "text");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "ItemGlobals",
type: "text",
nullable: false,
oldClrType: typeof(string),
oldType: "text",
oldCollation: "my_ci_collation");
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "Accounts",
type: "text",
nullable: false,
oldClrType: typeof(string),
oldType: "text",
oldCollation: "my_ci_collation");
}
}
}
@@ -0,0 +1,651 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyOffice.DbContext;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20230725061203_CollationR")]
partial class CollationR
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
.HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid?>("OwnerId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("OwnerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<bool>("IsAllowManage")
.HasColumnType("boolean");
b.Property<bool>("IsAllowRead")
.HasColumnType("boolean");
b.Property<bool>("IsAllowWrite")
.HasColumnType("boolean");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("UserId");
b.ToTable("AccountAccesses");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("CategoryId");
b.ToTable("AccountAccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<decimal>("AmountMinus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<decimal>("AmountPlus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<DateTime?>("DeletedOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<int>("ItemId")
.HasColumnType("integer");
b.Property<Guid?>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("ItemId");
b.HasIndex("UserId");
b.ToTable("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("CurrentRateId")
.HasColumnType("integer");
b.Property<bool>("IsPrimary")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("CurrentRateId");
b.HasIndex("UserId");
b.ToTable("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("DefaultQuantity")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CurrencyId")
.HasColumnType("uuid");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<int>("Quantity")
.HasColumnType("integer");
b.Property<decimal>("Rate")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("CurrencyRates");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.Property<Guid>("ItemGlobalId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CategoryId");
b.HasIndex("ItemGlobalId");
b.ToTable("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("IsInternal")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ItemCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.HasKey("Id");
b.ToTable("ItemGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("FirstName")
.HasColumnType("text");
b.Property<string>("FullName")
.HasColumnType("text");
b.Property<bool>("IsEmailConfirmed")
.HasColumnType("boolean");
b.Property<string>("LastName")
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.Property<string>("UserName")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("Users");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", 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>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Provider")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("UserClaims");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Accounts")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "Owner")
.WithMany("Accounts")
.HasForeignKey("OwnerId");
b.Navigation("CurrencyGlobal");
b.Navigation("Owner");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("AccessRights")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountAccess")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Categories")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
.WithMany("Accounts")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("Category");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Motions")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
.WithMany("Motions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", null)
.WithMany("AccountMotions")
.HasForeignKey("UserId");
b.Navigation("Account");
b.Navigation("Item");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Currencies")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate")
.WithMany("Currencies")
.HasForeignKey("CurrentRateId");
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("Currencies")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
b.Navigation("CurrentRate");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
.WithMany("Rates")
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
.WithMany("Items")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
.WithMany("Items")
.HasForeignKey("ItemGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Category");
b.Navigation("ItemGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("ItemCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("UserClaims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Navigation("AccessRights");
b.Navigation("Categories");
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Navigation("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Navigation("Rates");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Navigation("Accounts");
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Navigation("AccountAccess");
b.Navigation("AccountCategories");
b.Navigation("AccountMotions");
b.Navigation("Accounts");
b.Navigation("Currencies");
b.Navigation("ItemCategories");
b.Navigation("UserClaims");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,36 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
/// <inheritdoc />
public partial class CollationR : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "Accounts",
type: "text",
nullable: false,
oldClrType: typeof(string),
oldType: "text",
oldCollation: "my_ci_collation");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "Accounts",
type: "text",
nullable: false,
collation: "my_ci_collation",
oldClrType: typeof(string),
oldType: "text");
}
}
}
@@ -0,0 +1,650 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyOffice.DbContext;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20230725061910_CollationR2")]
partial class CollationR2
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
.HasAnnotation("ProductVersion", "7.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid?>("OwnerId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("OwnerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<bool>("IsAllowManage")
.HasColumnType("boolean");
b.Property<bool>("IsAllowRead")
.HasColumnType("boolean");
b.Property<bool>("IsAllowWrite")
.HasColumnType("boolean");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("UserId");
b.ToTable("AccountAccesses");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("CategoryId");
b.ToTable("AccountAccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AccountCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<Guid>("AccountId")
.HasColumnType("uuid");
b.Property<decimal>("AmountMinus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<decimal>("AmountPlus")
.HasPrecision(18, 6)
.HasColumnType("numeric(18,6)");
b.Property<DateTime>("CreatedOn")
.HasColumnType("timestamp with time zone");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<DateTime?>("DeletedOn")
.HasColumnType("timestamp with time zone");
b.Property<string>("Description")
.HasColumnType("text");
b.Property<int>("ItemId")
.HasColumnType("integer");
b.Property<Guid?>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("AccountId");
b.HasIndex("ItemId");
b.HasIndex("UserId");
b.ToTable("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyGlobalId")
.IsRequired()
.HasColumnType("text");
b.Property<int?>("CurrentRateId")
.HasColumnType("integer");
b.Property<bool>("IsPrimary")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CurrencyGlobalId");
b.HasIndex("CurrentRateId");
b.HasIndex("UserId");
b.ToTable("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Property<string>("Id")
.HasColumnType("text");
b.Property<int>("DefaultQuantity")
.HasColumnType("integer");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Symbol")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("CurrencyGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CurrencyId")
.HasColumnType("uuid");
b.Property<DateTime>("DateTime")
.HasColumnType("timestamp with time zone");
b.Property<int>("Quantity")
.HasColumnType("integer");
b.Property<decimal>("Rate")
.HasColumnType("numeric");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("CurrencyRates");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<Guid>("CategoryId")
.HasColumnType("uuid");
b.Property<Guid>("ItemGlobalId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("CategoryId");
b.HasIndex("ItemGlobalId");
b.ToTable("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<bool>("IsInternal")
.HasColumnType("boolean");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ItemCategories");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("ItemGlobals");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
b.Property<string>("CurrencyId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("FirstName")
.HasColumnType("text");
b.Property<string>("FullName")
.HasColumnType("text");
b.Property<bool>("IsEmailConfirmed")
.HasColumnType("boolean");
b.Property<string>("LastName")
.HasColumnType("text");
b.Property<string>("PasswordHash")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Phone")
.HasColumnType("text");
b.Property<string>("UserName")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.HasKey("Id");
b.HasIndex("CurrencyId");
b.ToTable("Users");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", 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>("Email")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<string>("ExternalId")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Provider")
.IsRequired()
.HasColumnType("text")
.UseCollation("my_ci_collation");
b.Property<Guid>("UserId")
.HasColumnType("uuid");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("UserClaims");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Accounts")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "Owner")
.WithMany("Accounts")
.HasForeignKey("OwnerId");
b.Navigation("CurrencyGlobal");
b.Navigation("Owner");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("AccessRights")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountAccess")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Categories")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
.WithMany("Accounts")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
b.Navigation("Category");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("AccountCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
{
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
.WithMany("Motions")
.HasForeignKey("AccountId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
.WithMany("Motions")
.HasForeignKey("ItemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Users.User", null)
.WithMany("AccountMotions")
.HasForeignKey("UserId");
b.Navigation("Account");
b.Navigation("Item");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
.WithMany("Currencies")
.HasForeignKey("CurrencyGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate")
.WithMany("Currencies")
.HasForeignKey("CurrentRateId");
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("Currencies")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("CurrencyGlobal");
b.Navigation("CurrentRate");
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
.WithMany("Rates")
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
.WithMany("Items")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
.WithMany("Items")
.HasForeignKey("ItemGlobalId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Category");
b.Navigation("ItemGlobal");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("ItemCategories")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
.WithMany()
.HasForeignKey("CurrencyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Currency");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
{
b.HasOne("MyOffice.Data.Models.Users.User", "User")
.WithMany("UserClaims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
{
b.Navigation("AccessRights");
b.Navigation("Categories");
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
{
b.Navigation("Accounts");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
{
b.Navigation("Rates");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
{
b.Navigation("Accounts");
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
{
b.Navigation("Currencies");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
{
b.Navigation("Motions");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
{
b.Navigation("AccountAccess");
b.Navigation("AccountCategories");
b.Navigation("AccountMotions");
b.Navigation("Accounts");
b.Navigation("Currencies");
b.Navigation("ItemCategories");
b.Navigation("UserClaims");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,36 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace MyOffice.Migrations.Postgres.Migrations
{
/// <inheritdoc />
public partial class CollationR2 : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "ItemGlobals",
type: "text",
nullable: false,
oldClrType: typeof(string),
oldType: "text",
oldCollation: "my_ci_collation");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "ItemGlobals",
type: "text",
nullable: false,
collation: "my_ci_collation",
oldClrType: typeof(string),
oldType: "text");
}
}
}

Some files were not shown because too many files have changed in this diff Show More