fix
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
namespace MyOffice.Core.Attributes;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
|
||||||
|
public class LinkAttribute : Attribute
|
||||||
|
{
|
||||||
|
public LinkAttribute(Type type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
|
||||||
|
public class LinkFromAttribute : Attribute
|
||||||
|
{
|
||||||
|
public LinkFromAttribute(Type type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
|
||||||
|
public class LinkToAttribute : Attribute
|
||||||
|
{
|
||||||
|
public LinkToAttribute(Type type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
|
||||||
|
public class LinkWithAttribute : Attribute
|
||||||
|
{
|
||||||
|
public LinkWithAttribute(Type type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,26 @@ public static class StringExtensions
|
|||||||
return str != null && str.Equals(value, StringComparison.OrdinalIgnoreCase);
|
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)
|
public static bool AsBool(this string? str, bool defaultValue = false)
|
||||||
{
|
{
|
||||||
return true.ToString().Equals(str, StringComparison.OrdinalIgnoreCase) || defaultValue;
|
return true.ToString().Equals(str, StringComparison.OrdinalIgnoreCase) || defaultValue;
|
||||||
@@ -31,21 +51,11 @@ public static class StringExtensions
|
|||||||
|
|
||||||
public static Guid AsGuid(this string str)
|
public static Guid AsGuid(this string str)
|
||||||
{
|
{
|
||||||
/*str = str
|
|
||||||
.Replace("_", "/")
|
|
||||||
.Replace("-", "+");
|
|
||||||
byte[] buffer = Convert.FromBase64String(str + "==");
|
|
||||||
return new Guid(buffer);*/
|
|
||||||
return Guid.Parse(str);
|
return Guid.Parse(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Guid? AsGuidNull(this string str)
|
public static Guid? AsGuidNull(this string str)
|
||||||
{
|
{
|
||||||
/*str = str
|
|
||||||
.Replace("_", "/")
|
|
||||||
.Replace("-", "+");
|
|
||||||
byte[] buffer = Convert.FromBase64String(str + "==");
|
|
||||||
return new Guid(buffer);*/
|
|
||||||
if (Guid.TryParse(str, out var guid))
|
if (Guid.TryParse(str, out var guid))
|
||||||
{
|
{
|
||||||
return guid;
|
return guid;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public class Account
|
|||||||
public IEnumerable<AccountAccess>? AccessRights { get; set; }
|
public IEnumerable<AccountAccess>? AccessRights { get; set; }
|
||||||
public IEnumerable<Motion>? Motions { get; set; }
|
public IEnumerable<Motion>? Motions { get; set; }
|
||||||
public IEnumerable<AccountAccountCategory>? Categories { get; set; }
|
public IEnumerable<AccountAccountCategory>? Categories { get; set; }
|
||||||
|
public IEnumerable<AccountAccessInvite>? Invites { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AccountDetailed
|
public class AccountDetailed
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
namespace MyOffice.Data.Models.Accounts;
|
namespace MyOffice.Data.Models.Accounts;
|
||||||
|
|
||||||
|
using Core.Attributes;
|
||||||
using Users;
|
using Users;
|
||||||
|
|
||||||
public class AccountAccessInvite
|
public class AccountAccessInvite
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid UserId { get; set; }
|
public Guid UserId { get; set; }
|
||||||
public User User { get; set; }
|
public User? User { get; set; }
|
||||||
|
public Guid AccountId { get; set; }
|
||||||
|
public Account? Account { get; set; }
|
||||||
public DateTime CreatedOn { get; set; }
|
public DateTime CreatedOn { get; set; }
|
||||||
public DateTime? AcceptedOn { get; set; }
|
public DateTime? AcceptedOn { get; set; }
|
||||||
public DateTime? RejectedOn { get; set; }
|
public DateTime? RejectedOn { get; set; }
|
||||||
|
|||||||
@@ -6,4 +6,8 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\MyOffice.Core\MyOffice.Core.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
namespace MyOffice.Data.Repositories.Account;
|
namespace MyOffice.Data.Repositories.Account;
|
||||||
|
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Models.Accounts;
|
using Models.Accounts;
|
||||||
using MyOffice.Data.Repositories;
|
using MyOffice.Data.Repositories;
|
||||||
|
|
||||||
@@ -24,4 +25,18 @@ public class AccountAccessInviteRepository : AppRepository<AccountAccessInvite>,
|
|||||||
{
|
{
|
||||||
return UpdateBase(invite) > 0;
|
return UpdateBase(invite) > 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 AccountAccessInvite? Get(Guid id)
|
||||||
|
{
|
||||||
|
return _context.AccountAccessInvites.FirstOrDefault(x => x.Id == id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,10 @@ using MyOffice.Data.Repositories;
|
|||||||
|
|
||||||
public class AccountAccessRepository : AppRepository<AccountAccess>, IAccountAccessRepository
|
public class AccountAccessRepository : AppRepository<AccountAccess>, IAccountAccessRepository
|
||||||
{
|
{
|
||||||
|
public bool Add(AccountAccess accountAccess)
|
||||||
|
{
|
||||||
|
return AddBase(accountAccess) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Update(AccountAccess accountAccess)
|
public bool Update(AccountAccess accountAccess)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ public class AccountRepository : AppRepository<Account>, IAccountRepository
|
|||||||
public Account? Get(Guid userId, Guid id)
|
public Account? Get(Guid userId, Guid id)
|
||||||
{
|
{
|
||||||
return _context.Accounts!
|
return _context.Accounts!
|
||||||
.Include(x => x.Categories)!
|
.Include(x => x.Categories!.Where(c => c.Category.UserId == userId))!
|
||||||
.ThenInclude(x => x.Category)
|
.ThenInclude(x => x.Category)
|
||||||
.Include(x => x.AccessRights)!
|
.Include(x => x.AccessRights)!
|
||||||
.ThenInclude(x => x.User)
|
.ThenInclude(x => x.User)
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ using Models.Accounts;
|
|||||||
public interface IAccountAccessInviteRepository
|
public interface IAccountAccessInviteRepository
|
||||||
{
|
{
|
||||||
AccountAccessInvite? Get(Guid userId, string email);
|
AccountAccessInvite? Get(Guid userId, string email);
|
||||||
|
IEnumerable<AccountAccessInvite> GetActive(string email);
|
||||||
|
AccountAccessInvite? Get(Guid id);
|
||||||
bool Add(AccountAccessInvite invite);
|
bool Add(AccountAccessInvite invite);
|
||||||
bool Update(AccountAccessInvite invite);
|
bool Update(AccountAccessInvite invite);
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ using Models.Accounts;
|
|||||||
|
|
||||||
public interface IAccountAccessRepository
|
public interface IAccountAccessRepository
|
||||||
{
|
{
|
||||||
|
bool Add(AccountAccess accountAccess);
|
||||||
bool Update(AccountAccess accountAccess);
|
bool Update(AccountAccess accountAccess);
|
||||||
bool Delete(AccountAccess accountAccess);
|
bool Delete(AccountAccess accountAccess);
|
||||||
}
|
}
|
||||||
@@ -176,6 +176,11 @@ public class AppDbContext : DbContext
|
|||||||
.WithMany(x => x.AccountAccessInvites)
|
.WithMany(x => x.AccountAccessInvites)
|
||||||
.HasForeignKey(x => x.UserId);
|
.HasForeignKey(x => x.UserId);
|
||||||
|
|
||||||
|
modelBuilder.Entity<AccountAccessInvite>()
|
||||||
|
.HasOne(x => x.Account)
|
||||||
|
.WithMany(x => x.Invites)
|
||||||
|
.HasForeignKey(x => x.AccountId);
|
||||||
|
|
||||||
modelBuilder.Entity<Motion>()
|
modelBuilder.Entity<Motion>()
|
||||||
.HasOne(x => x.Account)
|
.HasOne(x => x.Account)
|
||||||
.WithMany(x => x.Motions)
|
.WithMany(x => x.Motions)
|
||||||
|
|||||||
+713
@@ -0,0 +1,713 @@
|
|||||||
|
// <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("20230728181916_AccountAccessInvites2")]
|
||||||
|
partial class AccountAccessInvites2
|
||||||
|
{
|
||||||
|
/// <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>("Name")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<Guid>("OwnerId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Type")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<Guid>("UserId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AccountId");
|
||||||
|
|
||||||
|
b.HasIndex("OwnerId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AccountAccesses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("AcceptedOn")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedOn")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("IsAllowWrite")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("RejectedOn")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<Guid>("UserId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AccountAccessInvites");
|
||||||
|
});
|
||||||
|
|
||||||
|
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", "Owner")
|
||||||
|
.WithMany("AccountAccessOwners")
|
||||||
|
.HasForeignKey("OwnerId")
|
||||||
|
.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("Owner");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||||
|
.WithMany("AccountAccessInvites")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
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("AccountAccessInvites");
|
||||||
|
|
||||||
|
b.Navigation("AccountAccessOwners");
|
||||||
|
|
||||||
|
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,51 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace MyOffice.Migrations.Postgres.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AccountAccessInvites2 : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<Guid>(
|
||||||
|
name: "UserId",
|
||||||
|
table: "AccountAccessInvites",
|
||||||
|
type: "uuid",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AccountAccessInvites_UserId",
|
||||||
|
table: "AccountAccessInvites",
|
||||||
|
column: "UserId");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_AccountAccessInvites_Users_UserId",
|
||||||
|
table: "AccountAccessInvites",
|
||||||
|
column: "UserId",
|
||||||
|
principalTable: "Users",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_AccountAccessInvites_Users_UserId",
|
||||||
|
table: "AccountAccessInvites");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_AccountAccessInvites_UserId",
|
||||||
|
table: "AccountAccessInvites");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "UserId",
|
||||||
|
table: "AccountAccessInvites");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+728
@@ -0,0 +1,728 @@
|
|||||||
|
// <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("20230728192017_AccountAccessInvites3")]
|
||||||
|
partial class AccountAccessInvites3
|
||||||
|
{
|
||||||
|
/// <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>("Name")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<Guid>("OwnerId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Type")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<Guid>("UserId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AccountId");
|
||||||
|
|
||||||
|
b.HasIndex("OwnerId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AccountAccesses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("AcceptedOn")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<Guid>("AccountId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedOn")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<bool>("IsAllowWrite")
|
||||||
|
.HasColumnType("boolean");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("RejectedOn")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<Guid>("UserId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AccountId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
|
b.ToTable("AccountAccessInvites");
|
||||||
|
});
|
||||||
|
|
||||||
|
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", "Owner")
|
||||||
|
.WithMany("AccountAccessOwners")
|
||||||
|
.HasForeignKey("OwnerId")
|
||||||
|
.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("Owner");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||||
|
.WithMany("Invites")
|
||||||
|
.HasForeignKey("AccountId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||||
|
.WithMany("AccountAccessInvites")
|
||||||
|
.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("Invites");
|
||||||
|
|
||||||
|
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("AccountAccessInvites");
|
||||||
|
|
||||||
|
b.Navigation("AccountAccessOwners");
|
||||||
|
|
||||||
|
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,51 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace MyOffice.Migrations.Postgres.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AccountAccessInvites3 : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<Guid>(
|
||||||
|
name: "AccountId",
|
||||||
|
table: "AccountAccessInvites",
|
||||||
|
type: "uuid",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AccountAccessInvites_AccountId",
|
||||||
|
table: "AccountAccessInvites",
|
||||||
|
column: "AccountId");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_AccountAccessInvites_Accounts_AccountId",
|
||||||
|
table: "AccountAccessInvites",
|
||||||
|
column: "AccountId",
|
||||||
|
principalTable: "Accounts",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_AccountAccessInvites_Accounts_AccountId",
|
||||||
|
table: "AccountAccessInvites");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_AccountAccessInvites_AccountId",
|
||||||
|
table: "AccountAccessInvites");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "AccountId",
|
||||||
|
table: "AccountAccessInvites");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -102,6 +102,9 @@ namespace MyOffice.Migrations.Postgres.Migrations
|
|||||||
b.Property<DateTime?>("AcceptedOn")
|
b.Property<DateTime?>("AcceptedOn")
|
||||||
.HasColumnType("timestamp with time zone");
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<Guid>("AccountId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
b.Property<DateTime>("CreatedOn")
|
b.Property<DateTime>("CreatedOn")
|
||||||
.HasColumnType("timestamp with time zone");
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
@@ -115,8 +118,15 @@ namespace MyOffice.Migrations.Postgres.Migrations
|
|||||||
b.Property<DateTime?>("RejectedOn")
|
b.Property<DateTime?>("RejectedOn")
|
||||||
.HasColumnType("timestamp with time zone");
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<Guid>("UserId")
|
||||||
|
.HasColumnType("uuid");
|
||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AccountId");
|
||||||
|
|
||||||
|
b.HasIndex("UserId");
|
||||||
|
|
||||||
b.ToTable("AccountAccessInvites");
|
b.ToTable("AccountAccessInvites");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -481,6 +491,25 @@ namespace MyOffice.Migrations.Postgres.Migrations
|
|||||||
b.Navigation("User");
|
b.Navigation("User");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||||
|
.WithMany("Invites")
|
||||||
|
.HasForeignKey("AccountId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||||
|
.WithMany("AccountAccessInvites")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Account");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
|
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||||
@@ -628,6 +657,8 @@ namespace MyOffice.Migrations.Postgres.Migrations
|
|||||||
|
|
||||||
b.Navigation("Categories");
|
b.Navigation("Categories");
|
||||||
|
|
||||||
|
b.Navigation("Invites");
|
||||||
|
|
||||||
b.Navigation("Motions");
|
b.Navigation("Motions");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -672,6 +703,8 @@ namespace MyOffice.Migrations.Postgres.Migrations
|
|||||||
{
|
{
|
||||||
b.Navigation("AccountAccess");
|
b.Navigation("AccountAccess");
|
||||||
|
|
||||||
|
b.Navigation("AccountAccessInvites");
|
||||||
|
|
||||||
b.Navigation("AccountAccessOwners");
|
b.Navigation("AccountAccessOwners");
|
||||||
|
|
||||||
b.Navigation("AccountCategories");
|
b.Navigation("AccountCategories");
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ export class ApiRoutes {
|
|||||||
static SettingsAccountAccesses = '/api/settings/accounts/:id/access';
|
static SettingsAccountAccesses = '/api/settings/accounts/:id/access';
|
||||||
static SettingsAccountAccess = '/api/settings/accounts/:id/access/:access';
|
static SettingsAccountAccess = '/api/settings/accounts/:id/access/:access';
|
||||||
static SettingsAccountAccountCategory = '/api/settings/accounts/:id/category/:categoryId';
|
static SettingsAccountAccountCategory = '/api/settings/accounts/:id/category/:categoryId';
|
||||||
|
static SettingsAccountInvites = '/api/settings/accounts/invites';
|
||||||
|
static SettingsAccountInviteAccept = '/api/settings/accounts/invites/:id/accept';
|
||||||
|
static SettingsAccountInviteReject = '/api/settings/accounts/invites/:id/reject';
|
||||||
|
|
||||||
static SettingsItemCategories = '/api/settings/item-categories';
|
static SettingsItemCategories = '/api/settings/item-categories';
|
||||||
static SettingsItemCategory = '/api/settings/item-categories/:id';
|
static SettingsItemCategory = '/api/settings/item-categories/:id';
|
||||||
|
|||||||
@@ -24,8 +24,12 @@ export class ErrorInterceptor implements HttpInterceptor {
|
|||||||
this.authenticationService.logout();
|
this.authenticationService.logout();
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
console.log(err);
|
let error = err.message || err.statusText;
|
||||||
const error = err.message || err.error.message || err.statusText;
|
error = !err.error ? error : err.error.message || err.error.title;
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
console.log('not parsed error', err);
|
||||||
|
}
|
||||||
return throwError(error);
|
return throwError(error);
|
||||||
//return throwError(err.error || err);
|
//return throwError(err.error || err);
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export interface AccountInviteModel {
|
||||||
|
id?: string,
|
||||||
|
account?: string,
|
||||||
|
allowWrite: boolean,
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ import { NgxCurrencyModule } from "ngx-currency";
|
|||||||
import { MatExpansionModule } from '@angular/material/expansion';
|
import { MatExpansionModule } from '@angular/material/expansion';
|
||||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
|
|
||||||
// app
|
// app
|
||||||
import { PagesRoutingModule } from './pages-routing.module';
|
import { PagesRoutingModule } from './pages-routing.module';
|
||||||
@@ -88,6 +89,7 @@ import { SettingsItemCategoryEditComponent } from './settings/item/edit.item.cat
|
|||||||
NgxMaskModule,
|
NgxMaskModule,
|
||||||
NgxCurrencyModule,
|
NgxCurrencyModule,
|
||||||
MatCheckboxModule,
|
MatCheckboxModule,
|
||||||
|
MatMenuModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: MAT_DATE_LOCALE, useValue: 'en-GB' },
|
{ provide: MAT_DATE_LOCALE, useValue: 'en-GB' },
|
||||||
|
|||||||
@@ -17,13 +17,19 @@
|
|||||||
</mat-card-subtitle>
|
</mat-card-subtitle>
|
||||||
</mat-card-title-group>
|
</mat-card-title-group>
|
||||||
<div fxFlex></div>
|
<div fxFlex></div>
|
||||||
|
<div *ngIf="invites && invites.length > 0" class="m-r-10">
|
||||||
|
<button mat-raised-button color="warn" [matMenuTriggerFor]="menu">Invites</button>
|
||||||
|
<mat-menu #menu="matMenu">
|
||||||
|
<button *ngFor="let invite of invites" mat-menu-item (click)="startInvite(invite)">{{invite.account}}</button>
|
||||||
|
</mat-menu>
|
||||||
|
</div>
|
||||||
<button class="btn-space " (click)="add()" mat-raised-button color="primary">
|
<button class="btn-space " (click)="add()" mat-raised-button color="primary">
|
||||||
Add
|
Add
|
||||||
</button>
|
</button>
|
||||||
</mat-card-header>
|
</mat-card-header>
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<div class="body table-responsive">
|
<div class="body table-responsive">
|
||||||
<mat-tab-group mat-stretch-tabs="false" mat-align-tabs="start">
|
<mat-tab-group mat-stretch-tabs="false" mat-align-tabs="start" [(selectedIndex)]="tabIndex">
|
||||||
<mat-tab *ngFor="let category of accountCategories" label="{{category.name}}">
|
<mat-tab *ngFor="let category of accountCategories" label="{{category.name}}">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { MatDialog } from '@angular/material/dialog';
|
|||||||
import { ApiRoutes } from '../../../api-routes';
|
import { ApiRoutes } from '../../../api-routes';
|
||||||
import { AccountModel } from '../../../model/account.model';
|
import { AccountModel } from '../../../model/account.model';
|
||||||
import { AccountCategoryModel } from '../../../model/account.category.model';
|
import { AccountCategoryModel } from '../../../model/account.category.model';
|
||||||
|
import { AccountInviteModel } from '../../../model/account.invite.model';
|
||||||
import { SettingsAccountAddComponent } from './add.account.component';
|
import { SettingsAccountAddComponent } from './add.account.component';
|
||||||
import { SettingsAccountEditComponent } from './edit.account.component';
|
import { SettingsAccountEditComponent } from './edit.account.component';
|
||||||
import { SettingsAccountAccessComponent } from './access.account.component';
|
import { SettingsAccountAccessComponent } from './access.account.component';
|
||||||
@@ -22,6 +23,8 @@ import { AccountCategoryService } from '../../../services/account.category.servi
|
|||||||
export class SettingsAccountComponent {
|
export class SettingsAccountComponent {
|
||||||
public accountCategories?: AccountCategoryModel[];
|
public accountCategories?: AccountCategoryModel[];
|
||||||
public accounts?: AccountModel[];
|
public accounts?: AccountModel[];
|
||||||
|
public invites?: AccountInviteModel[];
|
||||||
|
public tabIndex = 0;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private httpClient: HttpClient,
|
private httpClient: HttpClient,
|
||||||
@@ -32,13 +35,35 @@ export class SettingsAccountComponent {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.loadCategories();
|
this.loadCategories();
|
||||||
|
this.loadInvites();
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadAccounts() {
|
private loadAccounts(accountToShow?: string) {
|
||||||
this.httpClient
|
this.httpClient
|
||||||
.get<AccountModel[]>(ApiRoutes.SettingsAccounts)
|
.get<AccountModel[]>(ApiRoutes.SettingsAccounts)
|
||||||
.subscribe(data => {
|
.subscribe(data => {
|
||||||
this.accounts = data;
|
this.accounts = data;
|
||||||
|
if (accountToShow) {
|
||||||
|
var idx = -1;
|
||||||
|
var account = this.accounts.find(x => x.id === accountToShow);
|
||||||
|
if (account && account.categories && account.categories.length > 0) {
|
||||||
|
for (var i = 0; i < this.accountCategories!.length; i++) {
|
||||||
|
if (account!.categories!.find(c => c.id === this.accountCategories![i].id)) {
|
||||||
|
idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.tabIndex = idx === -1 ? this.accountCategories!.length : idx;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadInvites() {
|
||||||
|
return this.httpClient
|
||||||
|
.get<AccountInviteModel[]>(ApiRoutes.SettingsAccountInvites)
|
||||||
|
.subscribe(response => {
|
||||||
|
this.invites = response;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +143,57 @@ export class SettingsAccountComponent {
|
|||||||
this.loadAccounts();
|
this.loadAccounts();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public startInvite(invite: AccountInviteModel) {
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Accept to invite the account "' + invite.account + '"',
|
||||||
|
input: 'text',
|
||||||
|
inputLabel: 'Accept with name',
|
||||||
|
inputValue: invite.account,
|
||||||
|
showDenyButton: true,
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: 'Accept',
|
||||||
|
denyButtonText: 'Reject',
|
||||||
|
showLoaderOnConfirm: true,
|
||||||
|
preConfirm: (input) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.httpClient.post(ApiRoutes.SettingsAccountInviteAccept.replace(':id', invite.id!), { name: input })
|
||||||
|
.subscribe(data => {
|
||||||
|
resolve(data);
|
||||||
|
}, error => {
|
||||||
|
Swal.showValidationMessage(error);
|
||||||
|
reject();
|
||||||
|
});
|
||||||
|
|
||||||
|
}).catch(x => {
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
preDeny: (x) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.httpClient.post(ApiRoutes.SettingsAccountInviteReject.replace(':id', invite.id!), null)
|
||||||
|
.subscribe(data => {
|
||||||
|
resolve(data);
|
||||||
|
}, error => {
|
||||||
|
Swal.showValidationMessage(error.detail);
|
||||||
|
reject();
|
||||||
|
});
|
||||||
|
|
||||||
|
}).catch(x => {
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
allowOutsideClick: () => !Swal.isLoading(),
|
||||||
|
}).then((result) => {
|
||||||
|
var id;
|
||||||
|
if (result.value) {
|
||||||
|
var account = result.value as AccountModel;
|
||||||
|
id = account.id;
|
||||||
|
}
|
||||||
|
this.loadInvites();
|
||||||
|
this.loadAccounts(id);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MyOffice.Services.Account.Domain;
|
using MyOffice.Services.Account.Domain;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Identity;
|
||||||
|
|
||||||
public class AccountService
|
public class AccountService
|
||||||
{
|
{
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
private readonly IItemRepository _itemRepository;
|
private readonly IItemRepository _itemRepository;
|
||||||
private readonly IItemGlobalRepository _itemGlobalRepository;
|
private readonly IItemGlobalRepository _itemGlobalRepository;
|
||||||
private readonly ItemService _itemService;
|
private readonly ItemService _itemService;
|
||||||
|
private readonly IContextProvider _contextProvider;
|
||||||
|
|
||||||
public AccountService(
|
public AccountService(
|
||||||
ILogger<AccountService> logger,
|
ILogger<AccountService> logger,
|
||||||
@@ -42,7 +44,8 @@
|
|||||||
IMotionRepository motionRepository,
|
IMotionRepository motionRepository,
|
||||||
IItemRepository itemRepository,
|
IItemRepository itemRepository,
|
||||||
IItemGlobalRepository itemGlobalRepository,
|
IItemGlobalRepository itemGlobalRepository,
|
||||||
ItemService itemService
|
ItemService itemService,
|
||||||
|
IContextProvider contextProvider
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
@@ -57,6 +60,7 @@
|
|||||||
_itemRepository = itemRepository;
|
_itemRepository = itemRepository;
|
||||||
_itemGlobalRepository = itemGlobalRepository;
|
_itemGlobalRepository = itemGlobalRepository;
|
||||||
_itemService = itemService;
|
_itemService = itemService;
|
||||||
|
_contextProvider = contextProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AccountCategoryDto> GetAllCategories(Guid userId)
|
public List<AccountCategoryDto> GetAllCategories(Guid userId)
|
||||||
@@ -528,13 +532,13 @@
|
|||||||
|
|
||||||
if (account.AccessRights!.Any(x => x.User!.Email.EqualsIgnoreCase(email)))
|
if (account.AccessRights!.Any(x => x.User!.Email.EqualsIgnoreCase(email)))
|
||||||
{
|
{
|
||||||
return result.Set(AccessInviteStatus.account_not_found);
|
return result.Set(AccessInviteStatus.access_exists);
|
||||||
}
|
}
|
||||||
|
|
||||||
var access = _accountAccessInviteRepository.Get(userId, email);
|
var access = _accountAccessInviteRepository.Get(userId, email);
|
||||||
if (access != null)
|
if (access != null)
|
||||||
{
|
{
|
||||||
return result.Set(AccessInviteStatus.access_exists);
|
return result.Set(AccessInviteStatus.invite_exists);
|
||||||
}
|
}
|
||||||
|
|
||||||
var invite = new AccountAccessInvite
|
var invite = new AccountAccessInvite
|
||||||
@@ -542,7 +546,8 @@
|
|||||||
Id = Guid.NewGuid(),
|
Id = Guid.NewGuid(),
|
||||||
CreatedOn = DateTime.UtcNow,
|
CreatedOn = DateTime.UtcNow,
|
||||||
UserId = userId,
|
UserId = userId,
|
||||||
Email = email,
|
AccountId = account.Id,
|
||||||
|
Email = email.SafeTrim()!,
|
||||||
IsAllowWrite = isAllowWrite,
|
IsAllowWrite = isAllowWrite,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -606,5 +611,75 @@
|
|||||||
return result.Set(_mapper.Map<AccountDto>(account));
|
return result.Set(_mapper.Map<AccountDto>(account));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<AccountAccessInviteDto> InvitesGet(string email)
|
||||||
|
{
|
||||||
|
return _mapper.Map<List<AccountAccessInviteDto>>(_accountAccessInviteRepository.GetActive(email).ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Exec<AccountDto, InviteAcceptStatus> InviteAccept(Guid userId, Guid id, string name)
|
||||||
|
{
|
||||||
|
var result = new Exec<AccountDto, InviteAcceptStatus>(InviteAcceptStatus.success);
|
||||||
|
|
||||||
|
var invite = _accountAccessInviteRepository.Get(id);
|
||||||
|
if (invite == null
|
||||||
|
|| !invite.Email.EqualsIgnoreCase(_contextProvider.User.Email)
|
||||||
|
|| invite.AcceptedOn.HasValue
|
||||||
|
|| invite.RejectedOn.HasValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return result.Set(InviteAcceptStatus.invite_not_found);
|
||||||
|
}
|
||||||
|
|
||||||
|
var account = _accountRepository.Get(invite.UserId, invite.AccountId);
|
||||||
|
if (account == null)
|
||||||
|
{
|
||||||
|
return result.Set(InviteAcceptStatus.account_not_found);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account.AccessRights!.Any(x => x.UserId == userId))
|
||||||
|
{
|
||||||
|
result.Set(InviteAcceptStatus.already_accepted);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_accountAccessRepository.Add(new AccountAccess
|
||||||
|
{
|
||||||
|
UserId = userId,
|
||||||
|
AccountId = account.Id,
|
||||||
|
OwnerId = invite.UserId,
|
||||||
|
Name = name,
|
||||||
|
IsAllowWrite = invite.IsAllowWrite,
|
||||||
|
Type = AccountAccessTypeEnum.external,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
invite.AcceptedOn = DateTime.UtcNow;
|
||||||
|
_accountAccessInviteRepository.Update(invite);
|
||||||
|
|
||||||
|
account = _accountRepository.Get(userId, account.Id);
|
||||||
|
|
||||||
|
return result.Set(_mapper.Map<AccountDto>(account));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Exec<AccountAccessInviteDto, GeneralExecStatus> InviteReject(Guid id)
|
||||||
|
{
|
||||||
|
var result = new Exec<AccountAccessInviteDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||||
|
|
||||||
|
var invite = _accountAccessInviteRepository.Get(id);
|
||||||
|
if (invite == null
|
||||||
|
|| !invite.Email.EqualsIgnoreCase(_contextProvider.User.Email)
|
||||||
|
|| invite.AcceptedOn.HasValue
|
||||||
|
|| invite.RejectedOn.HasValue
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return result.Set(GeneralExecStatus.not_found);
|
||||||
|
}
|
||||||
|
|
||||||
|
invite.RejectedOn = DateTime.UtcNow;
|
||||||
|
_accountAccessInviteRepository.Update(invite);
|
||||||
|
|
||||||
|
return result.Set(_mapper.Map<AccountAccessInviteDto>(invite));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
namespace MyOffice.Services.Account.Domain;
|
namespace MyOffice.Services.Account.Domain;
|
||||||
|
|
||||||
|
using Core.Attributes;
|
||||||
using Data.Models.Accounts;
|
using Data.Models.Accounts;
|
||||||
using Data.Models.Users;
|
using Data.Models.Users;
|
||||||
|
using Mapper;
|
||||||
|
|
||||||
|
[Link(typeof(AccountAccess))]
|
||||||
|
[Link(typeof(AccountServiceProfile))]
|
||||||
public class AccountAccessDto
|
public class AccountAccessDto
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
namespace MyOffice.Services.Account.Domain;
|
||||||
|
|
||||||
|
using Core.Attributes;
|
||||||
|
using Data.Models.Accounts;
|
||||||
|
|
||||||
|
[Link(typeof(AccountAccessInvite))]
|
||||||
|
public class AccountAccessInviteDto
|
||||||
|
{
|
||||||
|
public string Id { get; set; } = null!;
|
||||||
|
public string Account { get; set; } = null!;
|
||||||
|
public bool IsAllowWrite { get; set; }
|
||||||
|
}
|
||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
using MyOffice.Data.Models.Currencies;
|
using MyOffice.Data.Models.Currencies;
|
||||||
using System;
|
using System;
|
||||||
|
using Data.Models.Accounts;
|
||||||
|
|
||||||
public class AccountDto
|
public class AccountDto
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid CurrentUserId { get; set; }
|
|
||||||
public string CurrencyGlobalId { get; set; } = null!;
|
public string CurrencyGlobalId { get; set; } = null!;
|
||||||
public CurrencyGlobal? CurrencyGlobal { get; set; }
|
public CurrencyGlobal? CurrencyGlobal { get; set; }
|
||||||
public Guid CurrencyId { get; set; }
|
public Guid CurrencyId { get; set; }
|
||||||
@@ -20,4 +20,8 @@ public class AccountDto
|
|||||||
public string Type { get; set; } = null!;
|
public string Type { get; set; } = null!;
|
||||||
public List<AccountAccessDto>? AccessRights { get; set; }
|
public List<AccountAccessDto>? AccessRights { get; set; }
|
||||||
public List<AccountAccountCategoryDto>? Categories { get; set; }
|
public List<AccountAccountCategoryDto>? Categories { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public Guid CurrentUserId { get; set; }
|
||||||
|
public AccountAccess? AccountAccess { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace MyOffice.Services.Account.Domain
|
||||||
|
{
|
||||||
|
public enum InviteAcceptStatus
|
||||||
|
{
|
||||||
|
success,
|
||||||
|
invite_not_found,
|
||||||
|
account_not_found,
|
||||||
|
already_accepted,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,20 @@ public class AccountServiceProfile : Profile
|
|||||||
CreateMap<Account, AccountDto>()
|
CreateMap<Account, AccountDto>()
|
||||||
.ForMember(x => x.HasMotions, o => o.MapFrom(x => x.Motions!.Any()))
|
.ForMember(x => x.HasMotions, o => o.MapFrom(x => x.Motions!.Any()))
|
||||||
.ForMember(x => x.CurrentUserId, o => o.MapFrom<UserIdResolver>())
|
.ForMember(x => x.CurrentUserId, o => o.MapFrom<UserIdResolver>())
|
||||||
.ForMember(x => x.Type, o => o.MapFrom((src, dst) => src.AccessRights!.FirstOrDefault(x => x.UserId == dst.CurrentUserId)!.Type.ToString()))
|
.ForMember(x => x.AccountAccess, o =>
|
||||||
|
{
|
||||||
|
o.MapFrom((src, dst) => src.AccessRights!.FirstOrDefault(x => x.UserId == dst.CurrentUserId));
|
||||||
|
})
|
||||||
|
.ForMember(x => x.Type, o =>
|
||||||
|
{
|
||||||
|
o.SetMappingOrder(1);
|
||||||
|
o.MapFrom((src, dst) => dst.AccountAccess?.Type.ToString());
|
||||||
|
})
|
||||||
|
.ForMember(x => x.Name, o =>
|
||||||
|
{
|
||||||
|
o.SetMappingOrder(1);
|
||||||
|
o.MapFrom((src, dst) => dst.AccountAccess?.Name ?? src.Name);
|
||||||
|
})
|
||||||
;
|
;
|
||||||
|
|
||||||
CreateMap<AccountDetailed, AccountDetailedDto>();
|
CreateMap<AccountDetailed, AccountDetailedDto>();
|
||||||
@@ -27,5 +40,9 @@ public class AccountServiceProfile : Profile
|
|||||||
.ForMember(x => x.Id, o => o.MapFrom(x => x.Id))
|
.ForMember(x => x.Id, o => o.MapFrom(x => x.Id))
|
||||||
.ForMember(x => x.AllowDelete, o => o.MapFrom(x => !x.Accounts!.Any()))
|
.ForMember(x => x.AllowDelete, o => o.MapFrom(x => !x.Accounts!.Any()))
|
||||||
;
|
;
|
||||||
|
|
||||||
|
CreateMap<AccountAccessInvite, AccountAccessInviteDto>()
|
||||||
|
.ForMember(x => x.Account, o => o.MapFrom(x => x.Account!.Name))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@ using Models.Account;
|
|||||||
using Services.Account;
|
using Services.Account;
|
||||||
using Services.Account.Domain;
|
using Services.Account.Domain;
|
||||||
using MyOffice.Web.Infrastructure.Attributes;
|
using MyOffice.Web.Infrastructure.Attributes;
|
||||||
|
using Services.Identity;
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
@@ -19,16 +20,19 @@ public class SettingsAccountController : BaseApiController
|
|||||||
private readonly ILogger<SettingsAccountController> _logger;
|
private readonly ILogger<SettingsAccountController> _logger;
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
private readonly AccountService _accountService;
|
private readonly AccountService _accountService;
|
||||||
|
private readonly IContextProvider _contextProvider;
|
||||||
|
|
||||||
public SettingsAccountController(
|
public SettingsAccountController(
|
||||||
ILogger<SettingsAccountController> logger,
|
ILogger<SettingsAccountController> logger,
|
||||||
IMapper mapper,
|
IMapper mapper,
|
||||||
AccountService accountService
|
AccountService accountService,
|
||||||
|
IContextProvider contextProvider
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_mapper = mapper;
|
_mapper = mapper;
|
||||||
_accountService = accountService;
|
_accountService = accountService;
|
||||||
|
_contextProvider = contextProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("~/api/settings/account-categories")]
|
[HttpGet("~/api/settings/account-categories")]
|
||||||
@@ -251,8 +255,6 @@ public class SettingsAccountController : BaseApiController
|
|||||||
return ProblemBadRequest("Account not found.");
|
return ProblemBadRequest("Account not found.");
|
||||||
|
|
||||||
case AccessInviteStatus.access_exists:
|
case AccessInviteStatus.access_exists:
|
||||||
return ProblemBadRequest("Access allowed.");
|
|
||||||
|
|
||||||
case AccessInviteStatus.invite_exists:
|
case AccessInviteStatus.invite_exists:
|
||||||
case AccessInviteStatus.success:
|
case AccessInviteStatus.success:
|
||||||
return exec.Result!;
|
return exec.Result!;
|
||||||
@@ -279,6 +281,53 @@ public class SettingsAccountController : BaseApiController
|
|||||||
default:
|
default:
|
||||||
throw new NotSupportedException(exec.Status.ToString());
|
throw new NotSupportedException(exec.Status.ToString());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("~/api/settings/accounts/invites")]
|
||||||
|
public List<AccountAccessInviteViewModel> AccountInvites()
|
||||||
|
{
|
||||||
|
var invites = _accountService.InvitesGet(_contextProvider.User.Email);
|
||||||
|
|
||||||
|
return _mapper.Map<List<AccountAccessInviteViewModel>>(invites);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("~/api/settings/accounts/invites/{id}/accept")]
|
||||||
|
public object AccountInviteAccept([AsGuid]string id, AccountInviteAcceptRequest request)
|
||||||
|
{
|
||||||
|
var exec = _accountService.InviteAccept(UserId, id.AsGuid(), request.Name);
|
||||||
|
|
||||||
|
switch (exec.Status)
|
||||||
|
{
|
||||||
|
case InviteAcceptStatus.invite_not_found:
|
||||||
|
return ProblemBadRequest("Invite not found.");
|
||||||
|
case InviteAcceptStatus.account_not_found:
|
||||||
|
return ProblemBadRequest("Account not found.");
|
||||||
|
|
||||||
|
case InviteAcceptStatus.already_accepted:
|
||||||
|
case InviteAcceptStatus.success:
|
||||||
|
return _mapper.Map<AccountViewModel>(exec.Result!);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException(exec.Status.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("~/api/settings/accounts/invites/{id}/reject")]
|
||||||
|
public object AccountInviteReject([AsGuid] string id)
|
||||||
|
{
|
||||||
|
var exec = _accountService.InviteReject(id.AsGuid());
|
||||||
|
|
||||||
|
switch (exec.Status)
|
||||||
|
{
|
||||||
|
case GeneralExecStatus.not_found:
|
||||||
|
case GeneralExecStatus.failure:
|
||||||
|
return ProblemBadRequest("Invite not found.");
|
||||||
|
|
||||||
|
case GeneralExecStatus.success:
|
||||||
|
return _mapper.Map<AccountAccessInviteViewModel>(exec.Result!);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException(exec.Status.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
namespace MyOffice.Web.Models.Account;
|
||||||
|
|
||||||
|
using Core.Attributes;
|
||||||
|
using Services.Account.Domain;
|
||||||
|
|
||||||
|
[LinkFrom(typeof(AccountAccessInviteDto))]
|
||||||
|
[LinkWith(typeof(AccountViewModelProfile))]
|
||||||
|
public class AccountAccessInviteViewModel
|
||||||
|
{
|
||||||
|
public string? Id { get; set; }
|
||||||
|
public string? Account { get; set; }
|
||||||
|
public bool? AllowWrite { get; set; }
|
||||||
|
}
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
namespace MyOffice.Web.Models.Account
|
namespace MyOffice.Web.Models.Account;
|
||||||
{
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using Core.Extensions;
|
|
||||||
using Data.Models.Accounts;
|
|
||||||
|
|
||||||
|
using MyOffice.Core.Attributes;
|
||||||
|
using MyOffice.Services.Account.Domain;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
[Link(typeof(AccountCategoryDto))]
|
||||||
public class AccountCategoryViewModel
|
public class AccountCategoryViewModel
|
||||||
{
|
{
|
||||||
public string? Id { get; set; }
|
public string? Id { get; set; }
|
||||||
@@ -13,17 +14,3 @@
|
|||||||
|
|
||||||
public bool? AllowDelete { get; set; }
|
public bool? AllowDelete { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AccountCategoryViewModelExtensions
|
|
||||||
{
|
|
||||||
public static AccountCategoryViewModel ToModel(this AccountCategory input)
|
|
||||||
{
|
|
||||||
return new AccountCategoryViewModel
|
|
||||||
{
|
|
||||||
Id = input.Id.ToShort(),
|
|
||||||
Name = input.Name,
|
|
||||||
AllowDelete = !input.Accounts?.Any(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace MyOffice.Web.Models.Account;
|
||||||
|
|
||||||
|
public class AccountInviteAcceptRequest
|
||||||
|
{
|
||||||
|
public string Name { get; set; } = null!;
|
||||||
|
}
|
||||||
@@ -3,11 +3,7 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using MyOffice.Services.Identity;
|
using MyOffice.Services.Identity;
|
||||||
using Services.Account.Domain;
|
using Services.Account.Domain;
|
||||||
using Services.Mapper;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using Core.Extensions;
|
|
||||||
using User;
|
using User;
|
||||||
using static MyOffice.Web.Models.Account.AccountAccessViewModel;
|
|
||||||
|
|
||||||
public class CustomResolver : IValueResolver<AccountAccessDto, AccessRightsViewModel, bool>
|
public class CustomResolver : IValueResolver<AccountAccessDto, AccessRightsViewModel, bool>
|
||||||
{
|
{
|
||||||
@@ -61,11 +57,15 @@ public class AccountViewModelProfile : Profile
|
|||||||
(src, dst) => src.OwnerId == src.UserId))
|
(src, dst) => src.OwnerId == src.UserId))
|
||||||
;
|
;
|
||||||
|
|
||||||
CreateMap<AccountAccessItemViewModel, AccountAccessDto>()
|
CreateMap<AccountAccessViewModel.AccountAccessItemViewModel, AccountAccessDto>()
|
||||||
.ForMember(x => x.IsAllowWrite, o => o.MapFrom(x => x.AllowWrite))
|
.ForMember(x => x.IsAllowWrite, o => o.MapFrom(x => x.AllowWrite))
|
||||||
;
|
;
|
||||||
|
|
||||||
CreateMap<AccountCategoryDto, AccountCategoryViewModel>()
|
CreateMap<AccountCategoryDto, AccountCategoryViewModel>()
|
||||||
;
|
;
|
||||||
|
|
||||||
|
CreateMap<AccountAccessInviteDto, AccountAccessInviteViewModel>()
|
||||||
|
.ForMember(x => x.AllowWrite, o => o.MapFrom(x => x.IsAllowWrite))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,6 +64,13 @@ using MyOffice.Services.Mapper;
|
|||||||
//TODO: Response model from base type
|
//TODO: Response model from base type
|
||||||
//TODO: XXXResult -> XXXStatus
|
//TODO: XXXResult -> XXXStatus
|
||||||
//TODO: SPA isAllowDelete -> allowDelete (remove is)
|
//TODO: SPA isAllowDelete -> allowDelete (remove is)
|
||||||
|
//TODO: Repository auto registration
|
||||||
|
//TODO: Services auto registration
|
||||||
|
//TODO: openid-configuration failed - lock login
|
||||||
|
//TODO: BUG some times after login redirect to dashboard but exists return url
|
||||||
|
//TODO: email confirmation
|
||||||
|
//TODO: email password reset
|
||||||
|
//TODO: automapper -> Extension ToModel() ToDbo() FromModel() FromDbo()
|
||||||
|
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
@@ -262,6 +269,7 @@ public class Program
|
|||||||
builder.Services.AddScoped<IAccountCategoryRepository, AccountCategoryRepository>();
|
builder.Services.AddScoped<IAccountCategoryRepository, AccountCategoryRepository>();
|
||||||
builder.Services.AddScoped<IAccountRepository, AccountRepository>();
|
builder.Services.AddScoped<IAccountRepository, AccountRepository>();
|
||||||
builder.Services.AddScoped<IAccountAccessRepository, AccountAccessRepository>();
|
builder.Services.AddScoped<IAccountAccessRepository, AccountAccessRepository>();
|
||||||
|
builder.Services.AddScoped<IAccountAccessInviteRepository, AccountAccessInviteRepository>();
|
||||||
builder.Services.AddScoped<IAccountAccountCategoryRepository, AccountAccountCategoryRepository>();
|
builder.Services.AddScoped<IAccountAccountCategoryRepository, AccountAccountCategoryRepository>();
|
||||||
|
|
||||||
builder.Services.AddScoped<IItemCategoryRepository, ItemCategoryRepository>();
|
builder.Services.AddScoped<IItemCategoryRepository, ItemCategoryRepository>();
|
||||||
|
|||||||
Reference in New Issue
Block a user