fix
This commit is contained in:
@@ -1,22 +1,16 @@
|
||||
namespace MyOffice.Data.Models.Accounts;
|
||||
|
||||
using Currencies;
|
||||
|
||||
public enum AccountTypeEnum
|
||||
{
|
||||
debit,
|
||||
credit,
|
||||
transit,
|
||||
other,
|
||||
}
|
||||
using MyOffice.Data.Models.Users;
|
||||
|
||||
public class Account
|
||||
{
|
||||
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 AccountTypeEnum Type { get; set; }
|
||||
public IEnumerable<AccountAccess>? AccessRights { get; set; }
|
||||
public IEnumerable<Motion>? Motions { get; set; }
|
||||
public IEnumerable<AccountAccountCategory>? Categories { get; set; }
|
||||
@@ -34,8 +28,9 @@ public struct AccountSimple
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string? CurrencyName { get; set; }
|
||||
public string? CurrencyShortName { get; set; }
|
||||
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; }
|
||||
|
||||
@@ -2,6 +2,14 @@
|
||||
|
||||
using MyOffice.Data.Models.Users;
|
||||
|
||||
public enum AccountAccessTypeEnum
|
||||
{
|
||||
balance,
|
||||
credit,
|
||||
external,
|
||||
other,
|
||||
}
|
||||
|
||||
public class AccountAccess
|
||||
{
|
||||
public int Id { get; set; }
|
||||
@@ -13,4 +21,5 @@ public class AccountAccess
|
||||
public bool IsAllowRead { get; set; }
|
||||
public bool IsAllowWrite { get; set; }
|
||||
public bool IsAllowManage { get; set; }
|
||||
public AccountAccessTypeEnum Type { get; set; }
|
||||
}
|
||||
@@ -2,6 +2,19 @@
|
||||
|
||||
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!;
|
||||
|
||||
@@ -29,4 +29,5 @@ public class User
|
||||
public IEnumerable<Motion>? AccountMotions { get; set; }
|
||||
public IEnumerable<AccountCategory>? AccountCategories { get; set; }
|
||||
public IEnumerable<ItemCategory>? ItemCategories { get; set; }
|
||||
public IEnumerable<Account>? Accounts { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace MyOffice.Data.Repositories.Account;
|
||||
|
||||
using Models.Accounts;
|
||||
using MyOffice.Data.Repositories;
|
||||
|
||||
public class AccountAccessRepository : AppRepository<AccountAccess>, IAccountAccessRepository
|
||||
{
|
||||
|
||||
public bool Update(AccountAccess accountAccess)
|
||||
{
|
||||
return UpdateBase(accountAccess) > 0;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
namespace MyOffice.Data.Repositories.Account;
|
||||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
using Models.Accounts;
|
||||
using MyOffice.Data.Models.Currencies;
|
||||
using MyOffice.Data.Repositories;
|
||||
|
||||
public class AccountRepository : AppRepository<Account>, IAccountRepository
|
||||
@@ -16,6 +14,7 @@ public class AccountRepository : AppRepository<Account>, IAccountRepository
|
||||
.ThenInclude(x => x.Category)
|
||||
.Include(x => x.AccessRights)!
|
||||
.ThenInclude(x => x.User)
|
||||
.Include(x => x.Motions)!
|
||||
.Where(x => x.AccessRights!.Any(a => a.UserId == userId))
|
||||
.ToList();
|
||||
}
|
||||
@@ -28,6 +27,7 @@ public class AccountRepository : AppRepository<Account>, IAccountRepository
|
||||
.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();
|
||||
}
|
||||
@@ -73,6 +73,11 @@ public class AccountRepository : AppRepository<Account>, IAccountRepository
|
||||
return AddBase(account) > 0;
|
||||
}
|
||||
|
||||
public bool Delete(Account account)
|
||||
{
|
||||
return RemoveBase(account) > 0;
|
||||
}
|
||||
|
||||
public Account? Get(Guid userId, Guid id)
|
||||
{
|
||||
return _context.Accounts!
|
||||
@@ -80,6 +85,7 @@ public class AccountRepository : AppRepository<Account>, IAccountRepository
|
||||
.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));
|
||||
}
|
||||
|
||||
@@ -141,27 +147,42 @@ public class AccountRepository : AppRepository<Account>, IAccountRepository
|
||||
|
||||
public List<AccountSimple> GetRestAtDate(Guid userId, DateTime date)
|
||||
{
|
||||
return _context.Accounts
|
||||
.Include(x => x.CurrencyGlobal!)
|
||||
return _context.AccountAccesses!
|
||||
.Where(x => x.UserId == userId)
|
||||
.Include(x => x.Account!)
|
||||
.ThenInclude(x => x.CurrencyGlobal!)
|
||||
.ThenInclude(x => x.Currencies!)
|
||||
.ThenInclude(x => x.CurrentRate!)
|
||||
.Where(x => x.AccessRights!.Any(u => u.UserId == userId))
|
||||
.Select(x => new {
|
||||
Id = x.Id,
|
||||
Name = x.Name,
|
||||
Currency = x.CurrencyGlobal!.Currencies!.FirstOrDefault(x => x.UserId == userId),
|
||||
Rest = x.Motions!.Sum(m => (m.AmountPlus - m.AmountMinus))
|
||||
.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,
|
||||
Balance = x.Rest,
|
||||
CurrencyName = x.Currency?.Name,
|
||||
CurrencyShortName = x.Currency?.ShortName,
|
||||
CurrencyRate = x.Currency?.CurrentRate?.Rate,
|
||||
CurrencyQuantity = x.Currency?.CurrentRate?.Quantity,
|
||||
}).ToList();
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace MyOffice.Data.Repositories.Account;
|
||||
|
||||
using Models.Accounts;
|
||||
|
||||
public interface IAccountAccessRepository
|
||||
{
|
||||
bool Update(AccountAccess accountAccess);
|
||||
}
|
||||
@@ -9,6 +9,7 @@ public interface IAccountRepository
|
||||
List<AccountDetailed> GetByCategoryDetailed(Guid userId, Guid categoryId);
|
||||
AccountDetailed? GetByIdDetailed(Guid userId, Guid id);
|
||||
bool Add(Account account);
|
||||
bool Delete(Account account);
|
||||
Account? Get(Guid userId, Guid id);
|
||||
bool Update(Account account);
|
||||
bool Remove(Account account);
|
||||
|
||||
@@ -11,7 +11,7 @@ public class ItemRepository : AppRepository<Item>, IItemRepository
|
||||
.Include(x => x.Motions)
|
||||
.Include(x => x.Category)
|
||||
.Include(x => x.ItemGlobal)
|
||||
.Where(x => x.Category.UserId == userId)
|
||||
.Where(x => x.Category!.UserId == userId)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public class ItemRepository : AppRepository<Item>, IItemRepository
|
||||
.Include(x => x.Motions)
|
||||
.Include(x => x.Category)
|
||||
.Include(x => x.ItemGlobal)
|
||||
.Where(x => x.Category.UserId == userId && x.CategoryId == categoryId)
|
||||
.Where(x => x.Category!.UserId == userId && x.CategoryId == categoryId)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public class ItemRepository : AppRepository<Item>, IItemRepository
|
||||
.Items
|
||||
.Include(x => x.ItemGlobal)
|
||||
.Where(x => x.Category!.UserId == userId && x.ItemGlobal.Name.Contains(term))
|
||||
.OrderByDescending(x => x.Motions.Count())
|
||||
.OrderByDescending(x => x!.Motions!.Count())
|
||||
.Take(limit)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
@@ -44,6 +44,11 @@ public class RepositoryBase<TEntity> where TEntity : class
|
||||
return await _context.Set<TEntity>().FindAsync(id);
|
||||
}
|
||||
|
||||
protected TEntity? GetBase(Guid id)
|
||||
{
|
||||
return _context.Set<TEntity>().Find(id);
|
||||
}
|
||||
|
||||
protected async Task<int> AddBaseAsync(TEntity entity)
|
||||
{
|
||||
//await _context.Set<TEntity>().AddAsync(entity);
|
||||
|
||||
@@ -5,6 +5,7 @@ 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);
|
||||
|
||||
@@ -11,6 +11,11 @@ public class UserRepository : AppRepository<User>, IUserRepository
|
||||
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);
|
||||
|
||||
@@ -5,6 +5,7 @@ using Data.Models.Currencies;
|
||||
using Data.Models.Items;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Data.Models.Users;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
public enum AppDbContextProvidersEnum
|
||||
{
|
||||
@@ -144,6 +145,11 @@ public class AppDbContext : DbContext
|
||||
.WithMany(x => x.Accounts)
|
||||
.HasForeignKey(x => x.CurrencyGlobalId);
|
||||
|
||||
modelBuilder.Entity<Account>()
|
||||
.HasOne(x => x.Owner)
|
||||
.WithMany(x => x.Accounts)
|
||||
.HasForeignKey(x => x.OwnerId);
|
||||
|
||||
modelBuilder.Entity<AccountAccess>()
|
||||
.HasOne(x => x.Account)
|
||||
.WithMany(x => x.AccessRights)
|
||||
@@ -173,6 +179,11 @@ public class AppDbContext : DbContext
|
||||
.HasOne(x => x.Category)
|
||||
.WithMany(x => x.Accounts)
|
||||
.HasForeignKey(x => x.CategoryId);
|
||||
|
||||
modelBuilder
|
||||
.Entity<AccountAccess>()
|
||||
.Property(d => d.Type)
|
||||
.HasConversion(new EnumToStringConverter<AccountAccessTypeEnum>());
|
||||
}
|
||||
|
||||
private void MotionsCreating(ModelBuilder modelBuilder)
|
||||
|
||||
@@ -32,15 +32,15 @@ public class RepositoryInitializer
|
||||
// CurrencyGlobals
|
||||
var predefinedCurrencyGlobals = new List<CurrencyGlobal>()
|
||||
{
|
||||
new() { Id = "UAH", DefaultQuantity = 1, Symbol = "₴", Name = "Ukrainian hryvnias" },
|
||||
new() { Id = "USD", DefaultQuantity = 1, Symbol = "$", Name = "US Dollar" },
|
||||
new() { Id = "EUR", DefaultQuantity = 1, Symbol = "€", Name = "Euros" },
|
||||
new() { Id = "GBP", DefaultQuantity = 1, Symbol = "£", Name = "British pounds sterling" },
|
||||
new() { Id = "RUB", DefaultQuantity = 10, Symbol = "₽", Name = "Russia Ruble" },
|
||||
new() { Id = "BTC", DefaultQuantity = 10, Symbol = "btc", Name = "Bitcoin" },
|
||||
new() { Id = "ETH", DefaultQuantity = 10, Symbol = "eth", Name = "Ethereum" },
|
||||
new() { Id = "TON", DefaultQuantity = 10, Symbol = "ton", Name = "TON" },
|
||||
new() { Id = "OTHER", DefaultQuantity = 1, Symbol = "", Name = "Other" },
|
||||
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 = dbContext.CurrencyGlobals.ToList();
|
||||
|
||||
+636
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
+637
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
+650
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,10 +37,15 @@ namespace MyOffice.Migrations.Postgres.Migrations
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid?>("OwnerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyGlobalId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Accounts");
|
||||
});
|
||||
|
||||
@@ -64,6 +69,10 @@ namespace MyOffice.Migrations.Postgres.Migrations
|
||||
b.Property<bool>("IsAllowWrite")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
@@ -401,7 +410,13 @@ namespace MyOffice.Migrations.Postgres.Migrations
|
||||
.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 =>
|
||||
@@ -618,6 +633,8 @@ namespace MyOffice.Migrations.Postgres.Migrations
|
||||
|
||||
b.Navigation("AccountMotions");
|
||||
|
||||
b.Navigation("Accounts");
|
||||
|
||||
b.Navigation("Currencies");
|
||||
|
||||
b.Navigation("ItemCategories");
|
||||
|
||||
@@ -23,6 +23,7 @@ import { AuthCodeFlowConfig, AuthModuleConfig } from '../config.oidc';
|
||||
import { SubjectExtensions } from './extensions/general.extensions';
|
||||
import { ExternalLoginConfig } from '../config.external-login';
|
||||
import { AccountCategoryService } from '../services/account.category.service';
|
||||
import { AccountService } from '../services/account.service';
|
||||
|
||||
export function storageFactory(): OAuthStorage {
|
||||
return localStorage;
|
||||
@@ -49,6 +50,7 @@ export function storageFactory(): OAuthStorage {
|
||||
OidcHelperService,
|
||||
SubjectExtensions,
|
||||
AccountCategoryService,
|
||||
AccountService,
|
||||
],
|
||||
schemas: [
|
||||
CUSTOM_ELEMENTS_SCHEMA
|
||||
|
||||
@@ -5,7 +5,7 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class LanguageService {
|
||||
languages: string[] = ['en', 'es', 'de'];
|
||||
languages: string[] = ['en', 'es', 'de', 'ua'];
|
||||
|
||||
constructor(public translate: TranslateService) {
|
||||
let browserLang: string;
|
||||
@@ -16,7 +16,8 @@ export class LanguageService {
|
||||
} else {
|
||||
browserLang = translate.getBrowserLang() as string;
|
||||
}
|
||||
translate.use(browserLang.match(/en|es|de/) ? browserLang : 'en');
|
||||
console.log(browserLang.match(/en|es|de|ua/));
|
||||
translate.use(browserLang.match(/en|es|de|ua/) ? browserLang : 'en');
|
||||
}
|
||||
|
||||
setLanguage(lang: string) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// angular
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { DecimalPipe } from '@angular/common';
|
||||
|
||||
import { DashboardRoutingModule } from './dashboard-routing.module';
|
||||
import { Dashboard1Component } from './dashboard1/dashboard1.component';
|
||||
import { Dashboard2Component } from './dashboard2/dashboard2.component';
|
||||
// libs
|
||||
import { NgScrollbarModule } from 'ngx-scrollbar';
|
||||
import { NgChartsModule } from 'ng2-charts';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
@@ -14,6 +14,12 @@ import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { NgApexchartsModule } from 'ng-apexcharts';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
// app
|
||||
import { DashboardRoutingModule } from './dashboard-routing.module';
|
||||
import { Dashboard1Component } from './dashboard1/dashboard1.component';
|
||||
import { Dashboard2Component } from './dashboard2/dashboard2.component';
|
||||
import { ComponentsModule } from 'src/app/shared/components/components.module';
|
||||
import { SharedModule } from '../shared/shared.module';
|
||||
|
||||
@@ -34,7 +40,11 @@ import { SharedModule } from '../shared/shared.module';
|
||||
MatProgressBarModule,
|
||||
ComponentsModule,
|
||||
SharedModule,
|
||||
TranslateModule,
|
||||
],
|
||||
providers: [
|
||||
DecimalPipe,
|
||||
]
|
||||
})
|
||||
export class DashboardModule {
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="content-block">
|
||||
<div class="block-header">
|
||||
<!-- breadcrumb -->
|
||||
<app-breadcrumb [title]="'Dashboad 2'" [items]="['Home']" [active_item]="'Dashboad 2'"></app-breadcrumb>
|
||||
<app-breadcrumb [title]="'MENUITEMS.DASHBOARD.LIST.DASHBOARD1'" [items]="['HOME']" [active_item]="'MENUITEMS.DASHBOARD.LIST.DASHBOARD1'"></app-breadcrumb>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<h5>Balance</h5>
|
||||
<h5>{{'BALANCE' | translate}}</h5>
|
||||
</div>
|
||||
<h3 class="text-danger">{{dashboardModel?.balance | number: '0.2-2'}}</h3>
|
||||
</div>
|
||||
@@ -25,7 +25,7 @@
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<h5>Debit balance</h5>
|
||||
<h5>{{'DEBIT.BALANCE' | translate}}</h5>
|
||||
<p class="text-muted"></p>
|
||||
</div>
|
||||
<h3 class="text-success">{{dashboardModel?.balanceDebit | number: '0.2-2'}}</h3>
|
||||
@@ -39,7 +39,7 @@
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<h5>Credit balance</h5>
|
||||
<h5>{{'CREDIT.BALANCE' | translate}}</h5>
|
||||
</div>
|
||||
<h3 class="text-danger">{{dashboardModel?.balanceCredit | number: '0.2-2'}}</h3>
|
||||
</div>
|
||||
@@ -53,7 +53,7 @@
|
||||
<div class="col-xl-12 col-lg-12 col-md-12 col-sm-12">
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<h2>Current rest</h2>
|
||||
<h2>{{'CURRENT.BALANCE' | translate}}</h2>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menu" class="header-dropdown">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
@@ -65,491 +65,32 @@
|
||||
</div>
|
||||
<div class="body">
|
||||
<div id="chart">
|
||||
<apx-chart [series]="pieChartOptions.series2!" [chart]="pieChartOptions.chart!"
|
||||
[labels]="pieChartOptions.labels!" [responsive]="pieChartOptions.responsive!"
|
||||
[dataLabels]="pieChartOptions.dataLabels!" [legend]="pieChartOptions.legend!" class="apex-pie-center">
|
||||
<apx-chart #chart *ngIf="pieChartOptions" class="apex-pie-center"
|
||||
[series]="pieChartOptions.series2!"
|
||||
[chart]="pieChartOptions.chart!"
|
||||
[labels]="pieChartOptions.labels!"
|
||||
[responsive]="pieChartOptions.responsive!"
|
||||
[tooltip]="pieChartOptions.tooltip!"
|
||||
>
|
||||
</apx-chart>
|
||||
</div>
|
||||
<div class="table-responsive m-t-15">
|
||||
<table class="table align-items-center">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><i class="fa fa-circle col-cyan msr-2"></i> India</td>
|
||||
<td>23</td>
|
||||
<td class="col-green">+32%</td>
|
||||
<tr *ngFor="let item of top10Balance">
|
||||
<td><i class="fa fa-circle col-cyan msr-2"></i> {{item.name}}</td>
|
||||
<td class="col-green" style="text-align: right;">{{item.balance | number: '1.2'}} ({{item.currencyShortName}})</td>
|
||||
<td class="col-green" style="text-align: right;">{{item.balanceAtRate | number: '1.2'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-circle col-blue msr-2"></i>USA</td>
|
||||
<td>32</td>
|
||||
<td class="col-green">+12%</td>
|
||||
<td><i class="fa fa-circle col-green msr-2"></i> {{'OTHER' | translate}}</td>
|
||||
<td></td>
|
||||
<td class="col-green" style="text-align: right;">{{top10BalanceOther | number: '1.2'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-circle col-orange msr-2"></i>Shrilanka</td>
|
||||
<td>12</td>
|
||||
<td class="col-orange">-12%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="fa fa-circle col-green msr-2"></i>Australia</td>
|
||||
<td>32</td>
|
||||
<td class="col-green">+3%</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row clearfix">
|
||||
<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4">
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<h2>Notice Board</h2>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menu" class="header-dropdown">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item>Action</button>
|
||||
<button mat-menu-item>Another action</button>
|
||||
<button mat-menu-item>Something else here</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
<div class="body">
|
||||
<ng-scrollbar style="height: 380px" visibility="hover">
|
||||
<div class="recent-comment">
|
||||
<div class="notice-board">
|
||||
<div class="table-img">
|
||||
<img class="notice-object" src="assets/images/user/user6.jpg" alt="...">
|
||||
</div>
|
||||
<div class="notice-body">
|
||||
<h6 class="notice-heading col-green">Airi Satou</h6>
|
||||
<p>Lorem ipsum dolor sit amet, id quo eruditi eloquentiam.</p>
|
||||
<small class="text-muted">7 hours ago</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notice-board">
|
||||
<div class="table-img">
|
||||
<img class="notice-object" src="assets/images/user/user4.jpg" alt="...">
|
||||
</div>
|
||||
<div class="notice-body">
|
||||
<h6 class="notice-heading color-primary col-indigo">Sarah Smith</h6>
|
||||
<p>Lorem ipsum dolor sit amet, id quo eruditi eloquentiam.</p>
|
||||
<p class="comment-date">1 hour ago</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notice-board">
|
||||
<div class="table-img">
|
||||
<img class="notice-object" src="assets/images/user/user3.jpg" alt="...">
|
||||
</div>
|
||||
<div class="notice-body">
|
||||
<h6 class="notice-heading color-danger col-cyan">Cara Stevens</h6>
|
||||
<p>Lorem ipsum dolor sit amet, id quo eruditi eloquentiam.</p>
|
||||
<div class="comment-date">Yesterday</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notice-board no-border">
|
||||
<div class="table-img">
|
||||
<img class="notice-object" src="assets/images/user/user7.jpg" alt="...">
|
||||
</div>
|
||||
<div class="notice-body">
|
||||
<h6 class="notice-heading color-info col-orange">Ashton Cox</h6>
|
||||
<p>Lorem ipsum dolor sit amet, id quo eruditi eloquentiam.</p>
|
||||
<div class="comment-date">Yesterday</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notice-board">
|
||||
<div class="table-img">
|
||||
<img class="notice-object" src="assets/images/user/user9.jpg" alt="...">
|
||||
</div>
|
||||
<div class="notice-body">
|
||||
<h6 class="notice-heading color-primary col-red">Mark Hay</h6>
|
||||
<p>Lorem ipsum dolor sit amet, id quo eruditi eloquentiam.</p>
|
||||
<p class="comment-date">1 hour ago</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notice-board">
|
||||
<div class="table-img">
|
||||
<img class="notice-object" src="assets/images/user/user8.jpg" alt="...">
|
||||
</div>
|
||||
<div class="notice-body">
|
||||
<h6 class="notice-heading color-primary col-green">Jay Pandya</h6>
|
||||
<p>Lorem ipsum dolor sit amet, id quo eruditi eloquentiam.</p>
|
||||
<p class="comment-date">3 hour ago</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-4 col-lg-4 col-md-12 col-sm-12">
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<h2>Project Status</h2>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menu" class="header-dropdown">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item>Action</button>
|
||||
<button mat-menu-item>Another action</button>
|
||||
<button mat-menu-item>Something else here</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
<ng-scrollbar style="height: 410px" visibility="hover">
|
||||
<div class="tableBody">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Project Name</th>
|
||||
<th>Progress</th>
|
||||
<th>Duration</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Project A</td>
|
||||
<td>
|
||||
30%
|
||||
<mat-progress-bar mode="determinate" value="30" color="warn" class="progress-round">
|
||||
</mat-progress-bar>
|
||||
</td>
|
||||
<td>2 Months</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Project B</td>
|
||||
<td>
|
||||
55%
|
||||
<mat-progress-bar mode="determinate" class="progress-round" value="55">
|
||||
</mat-progress-bar>
|
||||
</td>
|
||||
<td>3 Months</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Project C</td>
|
||||
<td>
|
||||
67%
|
||||
<mat-progress-bar mode="determinate" class="progress-round orange-progress" value="67">
|
||||
</mat-progress-bar>
|
||||
</td>
|
||||
<td>1 Months</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Project D</td>
|
||||
<td>
|
||||
70%
|
||||
<mat-progress-bar mode="determinate" class="progress-round green-progress" value="70">
|
||||
</mat-progress-bar>
|
||||
</td>
|
||||
<td>2 Months</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Project E</td>
|
||||
<td>
|
||||
24%
|
||||
<mat-progress-bar mode="determinate" value="24" class="progress-round l-red-progress">
|
||||
</mat-progress-bar>
|
||||
</td>
|
||||
<td>3 Months</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Project F</td>
|
||||
<td>
|
||||
77%
|
||||
<mat-progress-bar mode="determinate" class="progress-round l-green-progress" value="77">
|
||||
</mat-progress-bar>
|
||||
</td>
|
||||
<td>4 Months</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Project G</td>
|
||||
<td>
|
||||
41%
|
||||
<mat-progress-bar mode="determinate" value="41" class="progress-round l-cyan-progress">
|
||||
</mat-progress-bar>
|
||||
</td>
|
||||
<td>2 Months</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Project H</td>
|
||||
<td>
|
||||
41%
|
||||
<mat-progress-bar mode="determinate" value="41" class="progress-round l-orange-progress">
|
||||
</mat-progress-bar>
|
||||
</td>
|
||||
<td>2 Months</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</ng-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4">
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<h2>Earning Source</h2>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menu" class="header-dropdown">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item>Action</button>
|
||||
<button mat-menu-item>Another action</button>
|
||||
<button mat-menu-item>Something else here</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div class="totalEarning">
|
||||
<h2>$90,808</h2>
|
||||
</div>
|
||||
<div class="tab-pane body" id="skills">
|
||||
<ul class="list-unstyled">
|
||||
<li>
|
||||
<div class="mb-2">
|
||||
<span class="progress-label">envato.com</span>
|
||||
<span class="float-end progress-percent label label-info m-b-5">17%</span>
|
||||
</div>
|
||||
<div class="progress skill-progress m-b-20 w-100">
|
||||
<div class="progress-bar l-bg-green width-per-45" role="progressbar" aria-valuenow="45"
|
||||
aria-valuemin="0" aria-valuemax="100">
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="mb-2">
|
||||
<span class="float-start progress-label">google.com</span>
|
||||
<span class="float-end progress-percent label label-danger m-b-5">27%</span>
|
||||
</div>
|
||||
<div class="progress skill-progress m-b-20 w-100">
|
||||
<div class="progress-bar l-bg-purple width-per-27" role="progressbar" aria-valuenow="27"
|
||||
aria-valuemin="0" aria-valuemax="100">
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="mb-2">
|
||||
<span class="float-start progress-label">yahoo.com</span>
|
||||
<span class="float-end progress-percent label label-primary m-b-5">25%</span>
|
||||
</div>
|
||||
<div class="progress skill-progress m-b-20 w-100">
|
||||
<div class="progress-bar l-bg-orange width-per-25" role="progressbar" aria-valuenow="25"
|
||||
aria-valuemin="0" aria-valuemax="100">
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="mb-2">
|
||||
<span class="float-start progress-label">store</span>
|
||||
<span class="float-end progress-percent label label-success m-b-5">18%</span>
|
||||
</div>
|
||||
<div class="progress skill-progress m-b-20 w-100">
|
||||
<div class="progress-bar l-bg-cyan width-per-18" role="progressbar" aria-valuenow="18"
|
||||
aria-valuemin="0" aria-valuemax="100">
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="mb-2">
|
||||
<span class="float-start progress-label">Others</span>
|
||||
<span class="float-end progress-percent label label-warning m-b-5">13%</span>
|
||||
</div>
|
||||
<div class="progress skill-progress m-b-20 w-100">
|
||||
<div class="progress-bar l-bg-red width-per-13" role="progressbar" aria-valuenow="13"
|
||||
aria-valuemin="0" aria-valuemax="100">
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row clearfix">
|
||||
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
|
||||
<div class="card">
|
||||
<div class="header">
|
||||
<h2>Recent Orders</h2>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menu" class="header-dropdown">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item>Action</button>
|
||||
<button mat-menu-item>Another action</button>
|
||||
<button mat-menu-item>Something else here</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
<div class="tableBody">
|
||||
<div class="table-responsive">
|
||||
<table class="table display product-overview mb-30" id="support_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Order ID</th>
|
||||
<th>Customer Name</th>
|
||||
<th>Item</th>
|
||||
<th>Order Date</th>
|
||||
<th>Quantity</th>
|
||||
<th>Payment</th>
|
||||
<th>Status</th>
|
||||
<th>Invoice</th>
|
||||
<th>Details</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>ID7865</td>
|
||||
<td>
|
||||
<img src="assets/images/user/user1.jpg" alt="" class="tbl-user-img-small">Jens
|
||||
Brincker
|
||||
</td>
|
||||
<td>iPhone X</td>
|
||||
<td>22/05/2021</td>
|
||||
<td>2</td>
|
||||
<td>Credit Card</td>
|
||||
<td>
|
||||
<div class="badge badge-solid-green">Paid</div>
|
||||
</td>
|
||||
<td>
|
||||
<i class="far fa-file-pdf tbl-pdf"></i>
|
||||
</td>
|
||||
<td>
|
||||
<button mat-stroked-button color="primary">Details</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ID9357</td>
|
||||
<td>
|
||||
<img src="assets/images/user/user2.jpg" alt="" class="tbl-user-img-small">Mark Harry
|
||||
</td>
|
||||
<td> Pixel 2</td>
|
||||
<td>12/06/2021</td>
|
||||
<td>1</td>
|
||||
<td>COD</td>
|
||||
<td>
|
||||
<div class="badge badge-solid-orange">Unpaid</div>
|
||||
</td>
|
||||
<td>
|
||||
<i class="far fa-file-pdf tbl-pdf"></i>
|
||||
</td>
|
||||
<td>
|
||||
<button mat-stroked-button color="primary">Details</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ID3987</td>
|
||||
<td>
|
||||
<img src="assets/images/user/user3.jpg" alt="" class="tbl-user-img-small">Anthony
|
||||
Davie
|
||||
</td>
|
||||
<td>OnePlus</td>
|
||||
<td>02/02/2021</td>
|
||||
<td>5</td>
|
||||
<td>Debit Card</td>
|
||||
<td>
|
||||
<div class="badge badge-solid-blue">Pending</div>
|
||||
</td>
|
||||
<td>
|
||||
<i class="far fa-file-pdf tbl-pdf"></i>
|
||||
</td>
|
||||
<td>
|
||||
<button mat-stroked-button color="primary">Details</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ID2483</td>
|
||||
<td>
|
||||
<img src="assets/images/user/user4.jpg" alt="" class="tbl-user-img-small">David Perry
|
||||
</td>
|
||||
<td>Moto Z2</td>
|
||||
<td>10/01/2021</td>
|
||||
<td>2</td>
|
||||
<td>Credit Card</td>
|
||||
<td>
|
||||
<div class="badge badge-solid-green">Paid</div>
|
||||
</td>
|
||||
<td>
|
||||
<i class="far fa-file-pdf tbl-pdf"></i>
|
||||
</td>
|
||||
<td>
|
||||
<button mat-stroked-button color="primary">Details</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ID2986</td>
|
||||
<td>
|
||||
<img src="assets/images/user/user5.jpg" alt="" class="tbl-user-img-small">John Doe
|
||||
</td>
|
||||
<td>Samsung F62</td>
|
||||
<td>20/05/2021</td>
|
||||
<td>3</td>
|
||||
<td>Net Banking</td>
|
||||
<td>
|
||||
<div class="badge badge-solid-orange">Unpaid</div>
|
||||
</td>
|
||||
<td>
|
||||
<i class="far fa-file-pdf tbl-pdf"></i>
|
||||
</td>
|
||||
<td>
|
||||
<button mat-stroked-button color="primary">Details</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ID1267</td>
|
||||
<td>
|
||||
<img src="assets/images/user/user6.jpg" alt="" class="tbl-user-img-small">Sarah Smith
|
||||
</td>
|
||||
<td>iPhone 12</td>
|
||||
<td>10/07/2021</td>
|
||||
<td>1</td>
|
||||
<td>COD</td>
|
||||
<td>
|
||||
<div class="badge badge-solid-green">Paid</div>
|
||||
</td>
|
||||
<td>
|
||||
<i class="far fa-file-pdf tbl-pdf"></i>
|
||||
</td>
|
||||
<td>
|
||||
<button mat-stroked-button color="primary">Details</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ID3398</td>
|
||||
<td>
|
||||
<img src="assets/images/user/user7.jpg" alt="" class="tbl-user-img-small">Cara Stevens
|
||||
</td>
|
||||
<td>Moto Gs5</td>
|
||||
<td>11/04/2021</td>
|
||||
<td>2</td>
|
||||
<td>UPI Payment</td>
|
||||
<td>
|
||||
<div class="badge badge-solid-blue">Pending</div>
|
||||
</td>
|
||||
<td>
|
||||
<i class="far fa-file-pdf tbl-pdf"></i>
|
||||
</td>
|
||||
<td>
|
||||
<button mat-stroked-button color="primary">Details</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ID9965</td>
|
||||
<td>
|
||||
<img src="assets/images/user/user8.jpg" alt="" class="tbl-user-img-small">Ashton Cox
|
||||
</td>
|
||||
<td>Pixel 2</td>
|
||||
<td>14/05/2021</td>
|
||||
<td>4</td>
|
||||
<td>Credit Card</td>
|
||||
<td>
|
||||
<div class="badge badge-solid-green">Paid</div>
|
||||
</td>
|
||||
<td>
|
||||
<i class="far fa-file-pdf tbl-pdf"></i>
|
||||
</td>
|
||||
<td>
|
||||
<button mat-stroked-button color="primary">Details</button>
|
||||
</td>
|
||||
<td style="text-align: right; font-size: 16px;"><i class="fa fa-circle col-orange msr-2"></i> {{'TOTAL' | translate}}</td>
|
||||
<td></td>
|
||||
<td class="col-green" style="text-align: right; font-size: 16px;">{{top10BalanceTotal | number: '1.2'}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
// angular
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component } from '@angular/core';
|
||||
import { OnInit } from '@angular/core';
|
||||
import { ViewChild } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { DecimalPipe } from '@angular/common';
|
||||
|
||||
// libs
|
||||
import {
|
||||
@@ -19,10 +22,12 @@ import {
|
||||
ApexResponsive,
|
||||
ApexNonAxisChartSeries,
|
||||
} from 'ng-apexcharts';
|
||||
import { ChartComponent } from "ng-apexcharts";
|
||||
|
||||
// app
|
||||
import { ApiRoutes } from '../../api-routes';
|
||||
import { DashboardModel } from '../../model/dashboard.model';
|
||||
import { DashboardRestModel } from '../../model/dashboard.model';
|
||||
|
||||
export type ChartOptions = {
|
||||
series: ApexAxisChartSeries;
|
||||
@@ -49,24 +54,48 @@ export type ChartOptions = {
|
||||
styleUrls: ['./dashboard2.component.scss'],
|
||||
})
|
||||
export class Dashboard2Component implements OnInit {
|
||||
lineChartOptions!: Partial<ChartOptions>;
|
||||
pieChartOptions!: Partial<ChartOptions>;
|
||||
|
||||
@ViewChild("chart") chart!: ChartComponent;
|
||||
public pieChartOptions!: Partial<ChartOptions>;
|
||||
top10Balance?: DashboardRestModel[];
|
||||
top10BalanceOther?: number;
|
||||
top10BalanceTotal?: number;
|
||||
dashboardModel?: DashboardModel;
|
||||
|
||||
// color: ["#3FA7DC", "#F6A025", "#9BC311"],
|
||||
constructor(private httpClient: HttpClient) {
|
||||
|
||||
constructor(
|
||||
private httpClient: HttpClient,
|
||||
private _decimalPipe: DecimalPipe
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.chart1();
|
||||
this.chart2();
|
||||
|
||||
this.httpClient
|
||||
.get<DashboardModel>(ApiRoutes.Dashboard)
|
||||
.subscribe(data => {
|
||||
data.incomeChange = this.calcChanges(data.incomeLast, data.incomePrevious);
|
||||
data.outcomeChange = this.calcChanges(data.outcomeLast, data.outcomePrevious);
|
||||
|
||||
var labels = [];
|
||||
var series2: number[] = [];
|
||||
for (var i = 0; i < data.balanceRests.length; i++) {
|
||||
let item = data.balanceRests[i];
|
||||
labels.push(item.name);
|
||||
series2.push(item.balanceAtRate);
|
||||
}
|
||||
|
||||
this.balanceChart(labels, series2);
|
||||
|
||||
this.top10Balance = data.balanceRests
|
||||
.filter(x => x.balanceAtRate > 0)
|
||||
.sort(x => x.balanceAtRate)
|
||||
.slice(0, 10);
|
||||
|
||||
this.top10BalanceTotal = data.balanceRests.reduce((sum, current) => sum + current.balanceAtRate, 0);
|
||||
this.top10BalanceOther = this.top10Balance.reduce((sum, current) => sum + current.balanceAtRate, 0);
|
||||
this.top10BalanceOther = this.top10BalanceTotal - this.top10BalanceOther;
|
||||
|
||||
this.dashboardModel = data;
|
||||
});
|
||||
}
|
||||
@@ -82,101 +111,41 @@ export class Dashboard2Component implements OnInit {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private chart1() {
|
||||
this.lineChartOptions = {
|
||||
series: [
|
||||
{
|
||||
name: 'Product 1',
|
||||
data: [70, 200, 80, 180, 170, 105, 210],
|
||||
},
|
||||
{
|
||||
name: 'Product 2',
|
||||
data: [80, 250, 30, 120, 260, 100, 180],
|
||||
},
|
||||
{
|
||||
name: 'Product 3',
|
||||
data: [85, 130, 85, 225, 80, 190, 120],
|
||||
},
|
||||
],
|
||||
chart: {
|
||||
height: 350,
|
||||
type: 'line',
|
||||
foreColor: '#9aa0ac',
|
||||
dropShadow: {
|
||||
enabled: true,
|
||||
color: '#000',
|
||||
top: 18,
|
||||
left: 7,
|
||||
blur: 10,
|
||||
opacity: 0.2,
|
||||
},
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
colors: ['#00E396', '#775DD0', '#FEB019'],
|
||||
stroke: {
|
||||
curve: 'smooth',
|
||||
},
|
||||
grid: {
|
||||
show: true,
|
||||
borderColor: '#9aa0ac',
|
||||
strokeDashArray: 1,
|
||||
},
|
||||
markers: {
|
||||
size: 3,
|
||||
},
|
||||
xaxis: {
|
||||
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'],
|
||||
title: {
|
||||
text: 'Month',
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
// opposite: true,
|
||||
title: {
|
||||
text: 'Sales',
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
position: 'top',
|
||||
horizontalAlign: 'right',
|
||||
floating: true,
|
||||
offsetY: -25,
|
||||
offsetX: -5,
|
||||
},
|
||||
tooltip: {
|
||||
theme: 'dark',
|
||||
marker: {
|
||||
show: true,
|
||||
},
|
||||
x: {
|
||||
show: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
private balanceChart(labels: string[], series2: number[]) {
|
||||
var self = this;
|
||||
|
||||
private chart2() {
|
||||
this.pieChartOptions = {
|
||||
series2: [44, 55, 13, 43, 22],
|
||||
labels: labels,
|
||||
series2: series2,
|
||||
chart: {
|
||||
type: 'donut',
|
||||
width: 225,
|
||||
width: 600,
|
||||
height: 600,
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
show: true,
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
},
|
||||
labels: ['Science', 'Mathes', 'Economics', 'History', 'Music'],
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 480,
|
||||
options: {},
|
||||
responsive: [{
|
||||
breakpoint: 480,
|
||||
options: {
|
||||
legend: {
|
||||
position: 'bottom'
|
||||
}
|
||||
},
|
||||
],
|
||||
}],
|
||||
tooltip: {
|
||||
x: {
|
||||
show: false,
|
||||
},
|
||||
y: {
|
||||
formatter: function (value, series) {
|
||||
return self._decimalPipe.transform(value, '1.2-2') || "";
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ export class HeaderComponent extends UnsubscribeOnDestroyAdapter implements OnIn
|
||||
{ text: 'English', flag: 'assets/images/flags/us.jpg', lang: 'en' },
|
||||
{ text: 'Spanish', flag: 'assets/images/flags/spain.jpg', lang: 'es' },
|
||||
{ text: 'German', flag: 'assets/images/flags/germany.jpg', lang: 'de' },
|
||||
{ text: 'Ukraine', flag: 'assets/images/flags/ukraine.png', lang: 'ua' },
|
||||
];
|
||||
notifications: Notifications[] = [
|
||||
{
|
||||
|
||||
@@ -22,20 +22,9 @@ export const ROUTES: RouteInfo[] = [
|
||||
badge: '',
|
||||
badgeClass: '',
|
||||
submenu: [
|
||||
{
|
||||
path: 'dashboard/dashboard1',
|
||||
title: 'MENUITEMS.DASHBOARD.LIST.DASHBOARD1',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu',
|
||||
groupTitle: false,
|
||||
badge: '',
|
||||
badgeClass: '',
|
||||
submenu: [],
|
||||
},
|
||||
{
|
||||
path: 'dashboard/dashboard2',
|
||||
title: 'MENUITEMS.DASHBOARD.LIST.DASHBOARD2',
|
||||
title: 'MENUITEMS.DASHBOARD.LIST.DASHBOARD1',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu',
|
||||
@@ -48,66 +37,10 @@ export const ROUTES: RouteInfo[] = [
|
||||
},
|
||||
|
||||
// Common Modules
|
||||
{
|
||||
path: '',
|
||||
title: 'Authentication',
|
||||
iconType: 'feather',
|
||||
icon: 'user-check',
|
||||
class: 'menu-toggle',
|
||||
groupTitle: false,
|
||||
badge: '',
|
||||
badgeClass: '',
|
||||
submenu: [
|
||||
{
|
||||
path: '/authentication/forgot-password',
|
||||
title: 'Forgot Password',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu',
|
||||
groupTitle: false,
|
||||
badge: '',
|
||||
badgeClass: '',
|
||||
submenu: [],
|
||||
},
|
||||
{
|
||||
path: '/authentication/locked',
|
||||
title: 'Locked',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu',
|
||||
groupTitle: false,
|
||||
badge: '',
|
||||
badgeClass: '',
|
||||
submenu: [],
|
||||
},
|
||||
{
|
||||
path: '/authentication/page404',
|
||||
title: '404 - Not Found',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu',
|
||||
groupTitle: false,
|
||||
badge: '',
|
||||
badgeClass: '',
|
||||
submenu: [],
|
||||
},
|
||||
{
|
||||
path: '/authentication/page500',
|
||||
title: '500 - Server Error',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu',
|
||||
groupTitle: false,
|
||||
badge: '',
|
||||
badgeClass: '',
|
||||
submenu: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'accounts',
|
||||
path: '',
|
||||
title: 'Accounts',
|
||||
title: 'MENUITEMS.ACCOUNTS.TEXT',
|
||||
iconType: 'feather',
|
||||
icon: 'chevrons-down',
|
||||
class: 'menu-toggle',
|
||||
@@ -115,79 +48,11 @@ export const ROUTES: RouteInfo[] = [
|
||||
badge: '',
|
||||
badgeClass: '',
|
||||
submenu: [
|
||||
/*{
|
||||
path: '/multilevel/first1',
|
||||
title: 'First',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu',
|
||||
groupTitle: false,
|
||||
badge: '',
|
||||
badgeClass: '',
|
||||
submenu: [],
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
title: 'Second',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-sub-menu',
|
||||
groupTitle: false,
|
||||
badge: '',
|
||||
badgeClass: '',
|
||||
submenu: [
|
||||
{
|
||||
path: '/multilevel/secondlevel/second1',
|
||||
title: 'Second 1',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu2',
|
||||
groupTitle: false,
|
||||
badge: '',
|
||||
badgeClass: '',
|
||||
submenu: [],
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
title: 'Second 2',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-sub-menu2',
|
||||
groupTitle: false,
|
||||
badge: '',
|
||||
badgeClass: '',
|
||||
submenu: [
|
||||
{
|
||||
path: '/multilevel/thirdlevel/third1',
|
||||
title: 'third 1',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu3',
|
||||
groupTitle: false,
|
||||
badge: '',
|
||||
badgeClass: '',
|
||||
submenu: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/multilevel/first3',
|
||||
title: 'Third',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu',
|
||||
groupTitle: false,
|
||||
badge: '',
|
||||
badgeClass: '',
|
||||
submenu: [],
|
||||
},*/
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
title: 'Settings',
|
||||
title: 'MENUITEMS.SETTINGS.TEXT',
|
||||
iconType: 'feather',
|
||||
icon: 'settings',
|
||||
class: 'menu-toggle',
|
||||
@@ -197,7 +62,7 @@ export const ROUTES: RouteInfo[] = [
|
||||
submenu: [
|
||||
{
|
||||
path: '/settings/currencies',
|
||||
title: 'Currencies',
|
||||
title: 'MENUITEMS.SETTINGS.LIST.CURRENCIES',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu',
|
||||
@@ -208,7 +73,7 @@ export const ROUTES: RouteInfo[] = [
|
||||
},
|
||||
{
|
||||
path: '/settings/account-categories',
|
||||
title: 'Account categories',
|
||||
title: 'MENUITEMS.SETTINGS.LIST.ACCOUNTCATEGORIES',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu',
|
||||
@@ -219,7 +84,7 @@ export const ROUTES: RouteInfo[] = [
|
||||
},
|
||||
{
|
||||
path: '/settings/accounts',
|
||||
title: 'Accounts',
|
||||
title: 'MENUITEMS.SETTINGS.LIST.ACCOUNTS',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu',
|
||||
@@ -230,7 +95,7 @@ export const ROUTES: RouteInfo[] = [
|
||||
},
|
||||
{
|
||||
path: '/settings/item-categories',
|
||||
title: 'Item categories',
|
||||
title: '',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu',
|
||||
@@ -241,7 +106,7 @@ export const ROUTES: RouteInfo[] = [
|
||||
},
|
||||
{
|
||||
path: '/settings/items',
|
||||
title: 'Items',
|
||||
title: 'MENUITEMS.SETTINGS.LIST.ITEMS',
|
||||
iconType: '',
|
||||
icon: '',
|
||||
class: 'ml-menu',
|
||||
|
||||
@@ -6,6 +6,8 @@ export interface AccountModel {
|
||||
name?: string,
|
||||
currencyId?: string,
|
||||
currencyName?: string,
|
||||
type?: string,
|
||||
allowDelete: boolean,
|
||||
categories?: AccountCategoryModel[],
|
||||
accessRights?: AccountAccessRightModel[],
|
||||
}
|
||||
|
||||
@@ -5,7 +5,21 @@ export interface DashboardModel {
|
||||
outcomeLast: number;
|
||||
outcomePrevious: number;
|
||||
outcomeChange: number;
|
||||
|
||||
balance: number;
|
||||
balanceDebit: number;
|
||||
balanceCredit: number;
|
||||
|
||||
balanceRests: DashboardRestModel[];
|
||||
}
|
||||
|
||||
export interface DashboardRestModel {
|
||||
id: string;
|
||||
name: string;
|
||||
currencyName: string;
|
||||
currencyShortName: string;
|
||||
balance: number;
|
||||
currencyRate: number;
|
||||
currencyQuantity: number;
|
||||
balanceAtRate: number;
|
||||
}
|
||||
|
||||
@@ -30,11 +30,12 @@
|
||||
<tr *ngFor="let account of accountInCategory(category)">
|
||||
<td>{{account.name}}</td>
|
||||
<td>{{account.currencyId}}</td>
|
||||
<td>{{account.type}}</td>
|
||||
<td>
|
||||
<button class="btn-space " (click)="edit(account)" mat-raised-button color="primary">
|
||||
<button class="btn-space" (click)="edit(account)" mat-raised-button color="primary">
|
||||
Edit
|
||||
</button>
|
||||
<button class="btn-space " (click)="remove(account)" mat-raised-button color="primary">
|
||||
<button class="btn-space" *ngIf="account.allowDelete" (click)="remove(account)" mat-raised-button color="primary">
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
@@ -48,11 +49,12 @@
|
||||
<tr *ngFor="let account of accountInCategory()">
|
||||
<td>{{account.name}}</td>
|
||||
<td>{{account.currencyId}}</td>
|
||||
<td>{{account.type}}</td>
|
||||
<td>
|
||||
<button class="btn-space " (click)="edit(account)" mat-raised-button color="primary">
|
||||
<button class="btn-space" (click)="edit(account)" mat-raised-button color="primary">
|
||||
Edit
|
||||
</button>
|
||||
<button class="btn-space " (click)="remove(account)" mat-raised-button color="primary">
|
||||
<button class="btn-space" *ngIf="account.allowDelete" (click)="remove(account)" mat-raised-button color="primary">
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
@@ -67,10 +69,10 @@
|
||||
<td>{{account.name}}</td>
|
||||
<td>{{account.currencyId}}</td>
|
||||
<td>
|
||||
<button class="btn-space " (click)="edit(account)" mat-raised-button color="primary">
|
||||
<button class="btn-space" (click)="edit(account)" mat-raised-button color="primary">
|
||||
Edit
|
||||
</button>
|
||||
<button class="btn-space " (click)="remove(account)" mat-raised-button color="primary">
|
||||
<button class="btn-space" *ngIf="account.allowDelete" (click)="remove(account)" mat-raised-button color="primary">
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
|
||||
@@ -81,15 +81,15 @@ export class SettingsAccountComponent {
|
||||
});
|
||||
}
|
||||
|
||||
public remove(category: AccountModel) {
|
||||
/*Swal.fire({
|
||||
title: 'Remove account category ' + category.name,
|
||||
public remove(account: AccountModel) {
|
||||
Swal.fire({
|
||||
title: 'Remove account ' + account.name,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Add',
|
||||
confirmButtonText: 'Delete',
|
||||
showLoaderOnConfirm: true,
|
||||
preConfirm: (name) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.httpClient.delete(ApiRoutes.SettingsAccountCategory.replace(':id', category.id!))
|
||||
this.httpClient.delete(ApiRoutes.SettingsAccount.replace(':id', account.id!))
|
||||
.subscribe(data => {
|
||||
resolve(data);
|
||||
}, error => {
|
||||
@@ -103,7 +103,7 @@ export class SettingsAccountComponent {
|
||||
},
|
||||
allowOutsideClick: () => !Swal.isLoading(),
|
||||
}).then((result) => {
|
||||
this.load();
|
||||
});*/
|
||||
this.loadAccounts();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,22 @@
|
||||
</h2>
|
||||
<div mat-dialog-content>
|
||||
<form [formGroup]="editForm!" (ngSubmit)="onSubmitClick()">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="text-inside">
|
||||
<mat-form-field class="example-full-width">
|
||||
<mat-label>Type</mat-label>
|
||||
<mat-select formControlName="type">
|
||||
<mat-option *ngFor="let type of types | keyvalue" [value]="type.key">
|
||||
{{type.key}} ({{type.value}})
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="text-inside">
|
||||
|
||||
@@ -19,6 +19,7 @@ import { CurrencyModel } from '../../../model/currency.model';
|
||||
import { AccountCategoryService } from '../../../services/account.category.service';
|
||||
import { AccountCategoryModel } from '../../../model/account.category.model';
|
||||
import { AuthService } from '../../../core/service/auth.service';
|
||||
import { AccountService } from '../../../services/account.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: './add.account.component.html',
|
||||
@@ -30,6 +31,7 @@ export class SettingsAccountAddComponent {
|
||||
public currencies?: CurrencyModel[];
|
||||
public categories?: AccountCategoryModel[];
|
||||
public username: string;
|
||||
public types = new Map<string, string>();
|
||||
|
||||
constructor(
|
||||
private fb: UntypedFormBuilder,
|
||||
@@ -38,9 +40,11 @@ export class SettingsAccountAddComponent {
|
||||
private currencyService: CurrencyService,
|
||||
private accountCategoryService: AccountCategoryService,
|
||||
private authService: AuthService,
|
||||
private accountService: AccountService,
|
||||
@Inject(MAT_DIALOG_DATA) public account: AccountModel
|
||||
) {
|
||||
this.username = authService.currentUserValue.userName;
|
||||
this.types = this.accountService.getTypes();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -60,6 +64,9 @@ export class SettingsAccountAddComponent {
|
||||
'',
|
||||
[Validators.required],
|
||||
],
|
||||
type: [
|
||||
this.account.type
|
||||
]
|
||||
});
|
||||
|
||||
this.currencyService
|
||||
|
||||
@@ -4,6 +4,22 @@
|
||||
</h2>
|
||||
<div mat-dialog-content>
|
||||
<form [formGroup]="editForm!" (ngSubmit)="onSubmitClick()">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="text-inside">
|
||||
<mat-form-field class="example-full-width">
|
||||
<mat-label>Type</mat-label>
|
||||
<mat-select formControlName="type">
|
||||
<mat-option *ngFor="let type of types | keyvalue" [value]="type.key">
|
||||
{{type.key}} ({{type.value}})
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="text-inside">
|
||||
@@ -26,7 +42,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-6">
|
||||
<label>Categories</label>
|
||||
<div class="col-md-12">
|
||||
@@ -42,20 +60,21 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<table class="table">
|
||||
<table class="table" style="table-layout: fixed;">
|
||||
<tbody>
|
||||
<tr *ngFor="let category of account.categories">
|
||||
<td>{{category.name}}</td>
|
||||
<td>
|
||||
<button class="btn-space" (click)="removeCategory(category)" mat-raised-button color="primary">
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr *ngFor="let category of account.categories">
|
||||
<td style="width: 100%;">{{category.name}}</td>
|
||||
<td style="width: 100px;">
|
||||
<button class="btn-space" (click)="removeCategory(category)" mat-raised-button color="primary">
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label>Users</label>
|
||||
<div class="col-md-12">
|
||||
@@ -70,20 +89,24 @@
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<div class="col-md-12">
|
||||
<table class="table" style="table-layout: fixed;">
|
||||
<tbody>
|
||||
<tr *ngFor="let accessRight of account.accessRights">
|
||||
<td>{{accessRight.user.email}}</td>
|
||||
<td>
|
||||
<td style="width: 100%;">{{accessRight.user.email}}</td>
|
||||
<td style="width: 100px;">
|
||||
<button class="btn-space" [disabled]="account.accessRights!.length <= 1" click="removeAccessRight(accessRight)" mat-raised-button color="primary">
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<mat-dialog-actions class="mat-dialog-actions">
|
||||
<div class="mat-dialog-left">
|
||||
<div class="alert alert-danger mat-dialog-error" *ngIf="errorMessage">
|
||||
|
||||
@@ -19,6 +19,7 @@ import { CurrencyModel } from '../../../model/currency.model';
|
||||
import { AccountCategoryService } from '../../../services/account.category.service';
|
||||
import { AccountCategoryModel } from '../../../model/account.category.model';
|
||||
import { AccountAccessRightModel } from '../../../model/account.accessRight.model';
|
||||
import { AccountService } from '../../../services/account.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: './edit.account.component.html',
|
||||
@@ -29,6 +30,7 @@ export class SettingsAccountEditComponent {
|
||||
public errorMessage?: string;
|
||||
public currencies?: CurrencyModel[];
|
||||
public categories?: AccountCategoryModel[];
|
||||
public types = new Map<string, string>();
|
||||
|
||||
constructor(
|
||||
private fb: UntypedFormBuilder,
|
||||
@@ -36,8 +38,10 @@ export class SettingsAccountEditComponent {
|
||||
private dialogRef: MatDialogRef<SettingsAccountEditComponent>,
|
||||
private currencyService: CurrencyService,
|
||||
private accountCategoryService: AccountCategoryService,
|
||||
private accountService: AccountService,
|
||||
@Inject(MAT_DIALOG_DATA) public account: AccountModel
|
||||
) {
|
||||
this.types = this.accountService.getTypes();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -56,6 +60,9 @@ export class SettingsAccountEditComponent {
|
||||
categoryId: [
|
||||
'',
|
||||
],
|
||||
type: [
|
||||
this.account.type,
|
||||
],
|
||||
});
|
||||
|
||||
this.currencyService
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// angular
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
|
||||
// libs
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
// app
|
||||
import { ApiRoutes } from '../api-routes';
|
||||
import { AccountCategoryModel } from '../model/account.category.model';
|
||||
|
||||
@Injectable()
|
||||
export class AccountService {
|
||||
private types = new Map<string, string>();
|
||||
|
||||
constructor(
|
||||
private httpClient: HttpClient,
|
||||
) {
|
||||
this.types.set('balance', 'Account with balance');
|
||||
this.types.set('credit', 'Account with loan funds');
|
||||
this.types.set('external', 'External account');
|
||||
this.types.set('other', 'Other account');
|
||||
}
|
||||
|
||||
public getTypes(): Map<string, string> {
|
||||
return this.types;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<div class="breadcrumb-title">
|
||||
<h4 class="page-title">{{title}}</h4>
|
||||
<h4 class="page-title">{{title | translate}}</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
@@ -12,8 +12,8 @@
|
||||
<app-feather-icons [icon]="'home'" [class]="'breadcrumb-icon'"></app-feather-icons>
|
||||
</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item" *ngFor="let item of items">{{item}}</li>
|
||||
<li class="breadcrumb-item active">{{active_item}}</li>
|
||||
<li class="breadcrumb-item" *ngFor="let item of items">{{item | translate}}</li>
|
||||
<li class="breadcrumb-item active">{{active_item | translate}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
// angular
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
// libs
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { FileUploadComponent } from './file-upload/file-upload.component';
|
||||
import { BreadcrumbComponent } from './breadcrumb/breadcrumb.component';
|
||||
import { SharedModule } from '../shared.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [FileUploadComponent, BreadcrumbComponent],
|
||||
imports: [SharedModule],
|
||||
exports: [FileUploadComponent, BreadcrumbComponent],
|
||||
declarations: [
|
||||
FileUploadComponent,
|
||||
BreadcrumbComponent
|
||||
],
|
||||
imports: [
|
||||
SharedModule,
|
||||
TranslateModule,
|
||||
],
|
||||
exports: [
|
||||
FileUploadComponent,
|
||||
BreadcrumbComponent
|
||||
],
|
||||
})
|
||||
export class ComponentsModule {
|
||||
}
|
||||
|
||||
@@ -14,11 +14,23 @@
|
||||
"DASHBOARD": {
|
||||
"TEXT": "Dashboard",
|
||||
"LIST": {
|
||||
"DASHBOARD1": "Dashboard 1",
|
||||
"DASHBOARD2": "Dashboard 2",
|
||||
"DASHBOARD3": "Dashboard 3"
|
||||
"DASHBOARD1": "Dashboard"
|
||||
}
|
||||
},
|
||||
"ACCOUNTS": {
|
||||
"TEXT": "Accounts"
|
||||
},
|
||||
"SETTINGS": {
|
||||
"TEXT": "Settings",
|
||||
"LIST": {
|
||||
"CURRENCIES": "Currencies",
|
||||
"ACCOUNTCATEGORIES": "Account categories",
|
||||
"ACCOUNTS": "Accounts",
|
||||
"ITEMCATEGORIES": "Item categories",
|
||||
"ITEMS": "Items"
|
||||
}
|
||||
},
|
||||
|
||||
"ADVANCE-TABLE": {
|
||||
"TEXT": "Advance Table"
|
||||
},
|
||||
@@ -80,5 +92,13 @@
|
||||
"NGX-DATATABLE": "NGX-Datatable"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"BALANCE": "Balance",
|
||||
"DEBIT.BALANCE": "Debit balance",
|
||||
"CREDIT.BALANCE": "Credit balance",
|
||||
"CURRENT.BALANCE": "Current balance",
|
||||
"HOME": "Home",
|
||||
"OTHER": "Other",
|
||||
"TOTAL": "Total"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
{
|
||||
"HEADER": {
|
||||
"SEARCH": {
|
||||
"TEXT": "Шукати.."
|
||||
}
|
||||
},
|
||||
"MENUITEMS": {
|
||||
"USER": {
|
||||
"POST": "Manager"
|
||||
},
|
||||
"MAIN": {
|
||||
"TEXT": "Головне"
|
||||
},
|
||||
"DASHBOARD": {
|
||||
"TEXT": "Панелі",
|
||||
"LIST": {
|
||||
"DASHBOARD1": "Панель"
|
||||
}
|
||||
},
|
||||
"ACCOUNTS": {
|
||||
"TEXT": "Рахунки"
|
||||
},
|
||||
"SETTINGS": {
|
||||
"TEXT": "Налаштування",
|
||||
"LIST": {
|
||||
"CURRENCIES": "Валюти",
|
||||
"ACCOUNTCATEGORIES": "Категорії рахунків",
|
||||
"ACCOUNTS": "Рахунки",
|
||||
"ITEMCATEGORIES": "Категорії статей",
|
||||
"ITEMS": "Статті"
|
||||
}
|
||||
},
|
||||
|
||||
"ADVANCE-TABLE": {
|
||||
"TEXT": "Advance Table"
|
||||
},
|
||||
"APPS": {
|
||||
"TEXT": "Apps"
|
||||
},
|
||||
"CALENDAR": {
|
||||
"TEXT": "Calendar"
|
||||
},
|
||||
"TASK": {
|
||||
"TEXT": "Task"
|
||||
},
|
||||
"CONTACTS": {
|
||||
"TEXT": "Contacts"
|
||||
},
|
||||
"EMAIL": {
|
||||
"TEXT": "Email",
|
||||
"LIST": {
|
||||
"INBOX": "Inbox",
|
||||
"COMPOSE": "Compose",
|
||||
"READ": "Read Email"
|
||||
}
|
||||
},
|
||||
"MORE-APPS": {
|
||||
"TEXT": "More Apps",
|
||||
"LIST": {
|
||||
"CHAT": "Chat",
|
||||
"SUPPORT": "Support",
|
||||
"DRAG-DROP": "Drag & Drop",
|
||||
"CONTACT-GRID": "Contact Grid"
|
||||
}
|
||||
},
|
||||
"COMPONENTS": {
|
||||
"TEXT": "Components"
|
||||
},
|
||||
"WIDGETS": {
|
||||
"TEXT": "Widgets",
|
||||
"LIST": {
|
||||
"CHART-WIDGET": "Chart-Widget",
|
||||
"DATA-WIDGET": "Data-Widget"
|
||||
}
|
||||
},
|
||||
"FORMS": {
|
||||
"TEXT": "Forms",
|
||||
"LIST": {
|
||||
"CONTROLS": "Form Controls",
|
||||
"ADVANCE": "Advance Control",
|
||||
"EXAMPLE": "Form Examples",
|
||||
"VALIDATION": "Form Validation",
|
||||
"WIZARD": "Wizard",
|
||||
"EDITORS": "Editors"
|
||||
}
|
||||
},
|
||||
"TABLES": {
|
||||
"TEXT": "Tables",
|
||||
"LIST": {
|
||||
"BASIC": "Basic Tables",
|
||||
"MATERIAL": "Material Tables",
|
||||
"NGX-DATATABLE": "NGX-Datatable"
|
||||
}
|
||||
}
|
||||
},
|
||||
"BALANCE": "Баланс",
|
||||
"DEBIT.BALANCE": "Остаток",
|
||||
"CREDIT.BALANCE": "Кредиты",
|
||||
"CURRENT.BALANCE": "Поточний баланс",
|
||||
"HOME": "Головна",
|
||||
"OTHER": "Інші",
|
||||
"TOTAL": "Всього"
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 324 B |
@@ -1,5 +1,6 @@
|
||||
namespace MyOffice.Services.Account
|
||||
{
|
||||
using AutoMapper;
|
||||
using Core;
|
||||
using Core.Extensions;
|
||||
using Core.Helpers;
|
||||
@@ -16,7 +17,9 @@
|
||||
public class AccountService
|
||||
{
|
||||
private ILogger<AccountService> _logger;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly IAccountCategoryRepository _accountCategoryRepository;
|
||||
private readonly IAccountAccessRepository _accountAccessRepository;
|
||||
private readonly IAccountRepository _accountRepository;
|
||||
private readonly ICurrencyRepository _currencyRepository;
|
||||
private readonly IAccountAccountCategoryRepository _accountAccountCategoryRepository;
|
||||
@@ -27,7 +30,9 @@
|
||||
|
||||
public AccountService(
|
||||
ILogger<AccountService> logger,
|
||||
IMapper mapper,
|
||||
IAccountCategoryRepository accountCategoryRepository,
|
||||
IAccountAccessRepository accountAccessRepository,
|
||||
IAccountRepository accountRepository,
|
||||
ICurrencyRepository currencyRepository,
|
||||
IAccountAccountCategoryRepository accountAccountCategoryRepository,
|
||||
@@ -38,7 +43,9 @@
|
||||
)
|
||||
{
|
||||
_logger = logger;
|
||||
_mapper = mapper;
|
||||
_accountCategoryRepository = accountCategoryRepository;
|
||||
_accountAccessRepository = accountAccessRepository;
|
||||
_accountRepository = accountRepository;
|
||||
_currencyRepository = currencyRepository;
|
||||
_accountAccountCategoryRepository = accountAccountCategoryRepository;
|
||||
@@ -130,24 +137,24 @@
|
||||
return result.Set(exists);
|
||||
}
|
||||
|
||||
public List<Account> GetAllAccounts(Guid userId)
|
||||
public List<AccountDto> GetAllAccounts(Guid userId)
|
||||
{
|
||||
return _accountRepository.GetAll(userId);
|
||||
return _mapper.Map<List<AccountDto>>(_accountRepository.GetAll(userId));
|
||||
}
|
||||
|
||||
public List<Account> GetByCategory(Guid userId, Guid categoryId)
|
||||
public List<AccountDto> GetByCategory(Guid userId, Guid categoryId)
|
||||
{
|
||||
return _accountRepository.GetByCategory(userId, categoryId);
|
||||
return _mapper.Map<List<AccountDto>>(_accountRepository.GetByCategory(userId, categoryId));
|
||||
}
|
||||
|
||||
public List<AccountDetailed> GetByCategoryDetailed(Guid userId, Guid categoryId)
|
||||
public List<AccountDetailedDto> GetByCategoryDetailed(Guid userId, Guid categoryId)
|
||||
{
|
||||
return _accountRepository.GetByCategoryDetailed(userId, categoryId);
|
||||
return _mapper.Map<List<AccountDetailedDto>>(_accountRepository.GetByCategoryDetailed(userId, categoryId));
|
||||
}
|
||||
|
||||
public Exec<AccountDetailed, GeneralExecStatus> GetByIdDetailed(Guid userId, Guid id)
|
||||
public Exec<AccountDetailedDto, GeneralExecStatus> GetByIdDetailed(Guid userId, Guid id)
|
||||
{
|
||||
var result = new Exec<AccountDetailed, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
var result = new Exec<AccountDetailedDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var account = _accountRepository.GetByIdDetailed(userId, id);
|
||||
if (account == null)
|
||||
@@ -155,7 +162,7 @@
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
return result.Set(account);
|
||||
return result.Set(_mapper.Map<AccountDetailedDto>(account));
|
||||
}
|
||||
|
||||
public Exec<Account, AccountAddResult> AccountAdd(Guid userId, AccountAdd input)
|
||||
@@ -208,9 +215,40 @@
|
||||
return result.Set(AccountAddResult.failure);
|
||||
}
|
||||
|
||||
var access = account.AccessRights!.FirstOrDefault(x => x.UserId == userId);
|
||||
if (access != null && access.Type.ToString() != input.Type)
|
||||
{
|
||||
if (Enum.TryParse<AccountAccessTypeEnum>(input.Type, out var enumType))
|
||||
{
|
||||
access.Type = enumType;
|
||||
_accountAccessRepository.Update(access);
|
||||
}
|
||||
}
|
||||
|
||||
return result.Set(account);
|
||||
}
|
||||
|
||||
public Exec<Account, GeneralExecStatus> AccountDelete(Guid userId, string id)
|
||||
{
|
||||
var result = new Exec<Account, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var account = _accountRepository.Get(userId, id.AsGuid());
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
if (account.Motions!.Any())
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
_accountRepository.Delete(account);
|
||||
result.Set(account);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Exec<Account, AccountEditResult> AccountUpdate(Guid userId, Guid accountId, AccountEdit input)
|
||||
{
|
||||
if (input == null)
|
||||
@@ -263,6 +301,16 @@
|
||||
return result.Set(AccountEditResult.failure);
|
||||
}
|
||||
|
||||
var access = account.AccessRights!.FirstOrDefault(x => x.UserId == userId);
|
||||
if (access != null && access.Type.ToString() != input.Type)
|
||||
{
|
||||
if (Enum.TryParse<AccountAccessTypeEnum>(input.Type, out var enumType))
|
||||
{
|
||||
access.Type = enumType;
|
||||
_accountAccessRepository.Update(access);
|
||||
}
|
||||
}
|
||||
|
||||
return result.Set(account);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,5 +5,6 @@
|
||||
public string Name { get; set; } = null!;
|
||||
public string CurrencyId { get; set; } = null!;
|
||||
public Guid CategoryId { get; set; }
|
||||
public string Type { get; set; } = null!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
|
||||
public class AccountDetailedDto
|
||||
{
|
||||
public AccountDto Account { get; set; } = null!;
|
||||
public decimal TotalPlus { get; set; }
|
||||
public decimal TotalMinus { get; set; }
|
||||
public decimal Rest => TotalPlus - TotalMinus;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
using MyOffice.Data.Models.Accounts;
|
||||
using MyOffice.Data.Models.Users;
|
||||
using MyOffice.Services.Account.Domain;
|
||||
|
||||
namespace MyOffice.Services.Account.Domain
|
||||
{
|
||||
using AutoMapper;
|
||||
using MyOffice.Data.Models.Accounts;
|
||||
using MyOffice.Data.Models.Currencies;
|
||||
using MyOffice.Data.Models.Users;
|
||||
using System;
|
||||
|
||||
public class AccountDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string CurrencyGlobalId { get; set; } = null!;
|
||||
public CurrencyGlobal? CurrencyGlobal { get; set; }
|
||||
public Guid CurrencyId { get; set; }
|
||||
public Currency? Currency { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public UserDto? User { get; set; }
|
||||
public Guid OwnerId { get; set; }
|
||||
public UserDto? Owner { get; set; }
|
||||
public string Name { get; set; } = null!;
|
||||
public bool HasMotions { get; set; }
|
||||
public List<AccountAccessDto>? AccessRights { get; set; }
|
||||
public List<AccountAccountCategoryDto>? Categories { get; set; }
|
||||
}
|
||||
|
||||
public class AccountAccessDto
|
||||
{
|
||||
public Guid AccountId { get; set; }
|
||||
public AccountDto? Account { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public User? User { get; set; }
|
||||
|
||||
public bool IsAllowRead { get; set; }
|
||||
public bool IsAllowWrite { get; set; }
|
||||
public bool IsAllowManage { get; set; }
|
||||
public AccountAccessTypeEnum Type { get; set; }
|
||||
}
|
||||
|
||||
public class AccountAccountCategoryDto
|
||||
{
|
||||
public Guid CategoryId { get; set; }
|
||||
public AccountCategoryDto? Category { get; set; } = null!;
|
||||
}
|
||||
|
||||
public class AccountMappingProfile : Profile
|
||||
{
|
||||
public AccountMappingProfile()
|
||||
{
|
||||
CreateMap<User, UserDto>();
|
||||
|
||||
CreateMap<Account, AccountDto>()
|
||||
.ForMember(x => x.HasMotions, o => o.MapFrom(x => x.Motions.Any()))
|
||||
;
|
||||
|
||||
CreateMap<AccountDetailed, AccountDetailedDto>();
|
||||
|
||||
CreateMap<AccountAccess, AccountAccessDto>();
|
||||
|
||||
CreateMap<AccountAccountCategory, AccountAccountCategoryDto>();
|
||||
|
||||
CreateMap<AccountCategory, AccountCategoryDto>()
|
||||
.ForMember(x => x.Id, o => o.MapFrom(x => x.Id))
|
||||
.ForMember(x => x.Id, o => o.MapFrom(x => x.Id))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
public class UserDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string UserName { get; set; } = null!;
|
||||
public string Email { get; set; } = null!;
|
||||
public string? FirstName { get; set; }
|
||||
public string? LastName { get; set; }
|
||||
public string? FullName { get; set; }
|
||||
public string? Phone { get; set; }
|
||||
|
||||
public string CurrencyId { get; set; }
|
||||
public CurrencyGlobal? Currency { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
public class AccountCategoryDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public string Name { get; set; } = null!;
|
||||
}
|
||||
@@ -6,4 +6,5 @@ public class AccountEdit
|
||||
public string CurrencyId { get; set; } = null!;
|
||||
public Guid? CategoryId { get; set; }
|
||||
public Guid? UserId { get; set; }
|
||||
public string? Type { get; set; }
|
||||
}
|
||||
@@ -27,21 +27,37 @@ public class DashboardService
|
||||
|
||||
public DashboardData GetDashboardRestData(Guid userId)
|
||||
{
|
||||
/*var lastDaysStart = DateTime.UtcNow.AddMonths(-3).StartOfDay();
|
||||
var lastDaysEnd = lastDaysStart.AddMonths(3).EndOfDay();
|
||||
var previousDaysStart = lastDaysStart.AddMonths(-3).StartOfDay();
|
||||
var previousDaysEnd = previousDaysStart.AddMonths(3).EndOfDay();*/
|
||||
var rests = _accountRepository.GetRestAtDate(userId, DateTime.UtcNow);
|
||||
|
||||
var result = new DashboardData
|
||||
{
|
||||
//IncomeLast = _accountRepository.GetPeriodIncome(userId, lastDaysStart, lastDaysEnd),
|
||||
//IncomePrevious = _accountRepository.GetPeriodIncome(userId, previousDaysStart, previousDaysEnd),
|
||||
//OutcomeLast = _accountRepository.GetPeriodOutcome(userId, lastDaysStart, lastDaysEnd),
|
||||
//OutcomePrevious = _accountRepository.GetPeriodOutcome(userId, previousDaysStart, previousDaysEnd),
|
||||
Balance = rests.Sum(x => x.Balance * (x.CurrencyRate * x.CurrencyQuantity)),
|
||||
BalanceDebit = rests.Where(x => x.Balance > 0).Sum(x => x.Balance * (x.CurrencyRate * x.CurrencyQuantity)),
|
||||
BalanceCredit = rests.Where(x => x.Balance < 0).Sum(x => x.Balance * (x.CurrencyRate * x.CurrencyQuantity)),
|
||||
Balance = rests
|
||||
.Where(x => (x.Type == AccountAccessTypeEnum.balance || x.Type == AccountAccessTypeEnum.credit) && x.CurrencyRate.HasValue)
|
||||
.Sum(x => x.Balance * (x.CurrencyRate * x.CurrencyQuantity)),
|
||||
|
||||
BalanceDebit = rests
|
||||
.Where(x => x.Type == AccountAccessTypeEnum.balance && x.CurrencyRate.HasValue)
|
||||
.Sum(x => x.Balance * (x.CurrencyRate * x.CurrencyQuantity)),
|
||||
|
||||
BalanceCredit = rests
|
||||
.Where(x => x.Type == AccountAccessTypeEnum.credit && x.CurrencyRate.HasValue)
|
||||
.Sum(x => x.Balance * (x.CurrencyRate * x.CurrencyQuantity)),
|
||||
|
||||
BalanceRests = rests
|
||||
.Where(x => x.Type == AccountAccessTypeEnum.balance)
|
||||
.Where(x => x.CurrencyRate.HasValue && x.Balance.HasValue && x.Balance != 0)
|
||||
.Select(x => new DashboardRestData
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name,
|
||||
Balance = x.Balance,
|
||||
CurrencyName = x.CurrencyName,
|
||||
CurrencyShortName = x.CurrencyShortName,
|
||||
CurrencyRate = x.CurrencyRate,
|
||||
CurrencyQuantity = x.CurrencyQuantity,
|
||||
})
|
||||
.OrderByDescending(x => x.BalanceAtRate)
|
||||
.ToList(),
|
||||
};
|
||||
|
||||
return result;
|
||||
|
||||
@@ -13,13 +13,18 @@ public class DashboardData
|
||||
public decimal? Balance { get; set; }
|
||||
public decimal? BalanceDebit { get; set; }
|
||||
public decimal? BalanceCredit { get; set; }
|
||||
public List<DashboardRestData> BalanceRests { get; set; }
|
||||
}
|
||||
|
||||
public class DashboardRestData
|
||||
{
|
||||
public AccountSimple AccountSimple { get; set; }
|
||||
public decimal? Balance => AccountSimple.Balance;
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; } = null!;
|
||||
public string CurrencyName { get; set; } = null!;
|
||||
public string CurrencyShortName { get; set; } = null!;
|
||||
public decimal? Balance { get; set; }
|
||||
public decimal? CurrencyRate { get; set; }
|
||||
public decimal? CurrencyQuantity { get; set; }
|
||||
|
||||
public decimal? BalanceAtRate =>
|
||||
AccountSimple.Balance * (AccountSimple.CurrencyRate * AccountSimple.CurrencyQuantity);
|
||||
public decimal? BalanceAtRate => Balance * (CurrencyRate * CurrencyQuantity);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace MyOffice.Services.Identity;
|
||||
|
||||
using Data.Models.Users;
|
||||
|
||||
public interface IContextProvider
|
||||
{
|
||||
User User { get; }
|
||||
Guid UserId { get; }
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="12.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MyOffice.Core\MyOffice.Core.csproj" />
|
||||
<ProjectReference Include="..\MyOffice.Data.Repositories\MyOffice.Data.Repositories.csproj" />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
namespace MyOffice.Web.Controllers;
|
||||
|
||||
using AutoMapper;
|
||||
using Core;
|
||||
using Core.Extensions;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
@@ -18,28 +19,29 @@ using Services.Item;
|
||||
public class AccountController : BaseApiController
|
||||
{
|
||||
private readonly ILogger<AccountController> _logger;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly AccountService _accountService;
|
||||
private readonly ItemService _itemService;
|
||||
|
||||
public AccountController(
|
||||
ILogger<AccountController> logger,
|
||||
IMapper mapper,
|
||||
AccountService accountService,
|
||||
ItemService itemService
|
||||
)
|
||||
{
|
||||
_logger = logger;
|
||||
_mapper = mapper;
|
||||
_accountService = accountService;
|
||||
_itemService = itemService;
|
||||
}
|
||||
|
||||
[HttpGet("~/api/accounts")]
|
||||
public object AccountsGet(string category)
|
||||
public List<AccountDetailedViewModel> AccountsGet(string category)
|
||||
{
|
||||
var list = _accountService.GetByCategoryDetailed(UserId, category!.AsGuid());
|
||||
|
||||
return list
|
||||
.OrderBy(x => x.Account.Name)
|
||||
.Select(x => x.ToModel());
|
||||
return _mapper.Map<List<AccountDetailedViewModel>>(list.OrderBy(x => x.Account.Name).ToList());
|
||||
}
|
||||
|
||||
[HttpGet("~/api/accounts/{id}")]
|
||||
@@ -54,7 +56,8 @@ public class AccountController : BaseApiController
|
||||
return ProblemBadRequest("Account not found.");
|
||||
|
||||
case GeneralExecStatus.success:
|
||||
return exec.Result!.ToModel();
|
||||
return _mapper.Map<AccountDetailedViewModel>(exec.Result);
|
||||
//return exec.Result!.ToModel();
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
namespace MyOffice.Web.Controllers;
|
||||
|
||||
using AutoMapper;
|
||||
using Core;
|
||||
using Core.Extensions;
|
||||
using Data.Models.Accounts;
|
||||
@@ -15,14 +16,17 @@ using Services.Account.Domain;
|
||||
public class SettingsAccountController : BaseApiController
|
||||
{
|
||||
private readonly ILogger<SettingsAccountController> _logger;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly AccountService _accountService;
|
||||
|
||||
public SettingsAccountController(
|
||||
ILogger<SettingsAccountController> logger,
|
||||
IMapper mapper,
|
||||
AccountService accountService
|
||||
)
|
||||
{
|
||||
_logger = logger;
|
||||
_mapper = mapper;
|
||||
_accountService = accountService;
|
||||
}
|
||||
|
||||
@@ -111,15 +115,13 @@ public class SettingsAccountController : BaseApiController
|
||||
}
|
||||
|
||||
[HttpGet("~/api/settings/accounts")]
|
||||
public object AccountsGet(string? category)
|
||||
public List<AccountViewModel> AccountsGet(string? category)
|
||||
{
|
||||
var list = category.IsPresent()
|
||||
? _accountService.GetByCategory(UserId, category!.AsGuid())
|
||||
: _accountService.GetAllAccounts(UserId);
|
||||
|
||||
return list
|
||||
.OrderBy(x => x.Name)
|
||||
.Select(x => x.ToModel());
|
||||
return _mapper.Map<List<AccountViewModel>>(list.OrderBy(x => x.Name));
|
||||
}
|
||||
|
||||
[HttpPost("~/api/settings/accounts")]
|
||||
@@ -130,6 +132,7 @@ public class SettingsAccountController : BaseApiController
|
||||
Name = request.Name,
|
||||
CurrencyId = request.CurrencyId,
|
||||
CategoryId = request.CategoryId.AsGuid(),
|
||||
Type = request.Type,
|
||||
});
|
||||
|
||||
switch (exec.Status)
|
||||
@@ -158,6 +161,7 @@ public class SettingsAccountController : BaseApiController
|
||||
CurrencyId = request.CurrencyId,
|
||||
CategoryId = request.CategoryId?.AsGuidNull(),
|
||||
UserId = request.UserId?.AsGuidNull(),
|
||||
Type = request.Type,
|
||||
});
|
||||
|
||||
switch (exec.Status)
|
||||
@@ -177,7 +181,23 @@ public class SettingsAccountController : BaseApiController
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpDelete("~/api/settings/accounts/{id}")]
|
||||
public object AccountsDelete(string id)
|
||||
{
|
||||
var exec = _accountService.AccountDelete(UserId, id);
|
||||
switch (exec.Status)
|
||||
{
|
||||
case GeneralExecStatus.not_found:
|
||||
return ProblemBadRequest("Account not found.");
|
||||
case GeneralExecStatus.success:
|
||||
return exec.Result!;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("~/api/settings/accounts/{id}/category/{categoryId}")]
|
||||
public object AccountsCategoryRemove(string id, string categoryId)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@ using MyOffice.Core.Identity;
|
||||
using Core;
|
||||
using Services.Users;
|
||||
using Services.Users.Domain;
|
||||
using MyOffice.Data.Models.Currencies;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
@@ -40,7 +41,8 @@ public class UserController : BaseApiController
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
UserName = request.UserName,
|
||||
Email = request.UserName
|
||||
Email = request.UserName,
|
||||
CurrencyId = CurrencyGlobalIdEnum.USD.ToString(),
|
||||
};
|
||||
|
||||
var result = await _userManager.CreateAsync(user, request.Password);
|
||||
|
||||
@@ -20,7 +20,6 @@ public class ConfigureIdentityServerOptions : IConfigureNamedOptions<IdentitySer
|
||||
|
||||
public void Configure(string? name, IdentityServerAuthenticationOptions options)
|
||||
{
|
||||
//_logger.LogError($"Configure: {_globalSettings.Host}");
|
||||
if (name == IdentityServerAuthenticationDefaults.AuthenticationScheme)
|
||||
{
|
||||
options.RequireHttpsMetadata = false;
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
namespace MyOffice.Web.Identity;
|
||||
|
||||
using Data.Repositories.Users;
|
||||
using MyOffice.Data.Models.Users;
|
||||
using MyOffice.Services.Identity;
|
||||
|
||||
public class ContextProvider : IContextProvider
|
||||
{
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IUserRepository _userRepository;
|
||||
|
||||
public ContextProvider(
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
IUserRepository userRepository
|
||||
)
|
||||
{
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_userRepository = userRepository;
|
||||
}
|
||||
|
||||
private User? _user = null;
|
||||
public User User
|
||||
{
|
||||
get
|
||||
{
|
||||
_user ??= _userRepository.GetUser(UserId);
|
||||
|
||||
return _user!;
|
||||
}
|
||||
}
|
||||
|
||||
public Guid UserId
|
||||
{
|
||||
get
|
||||
{
|
||||
return Guid.Parse(_httpContextAccessor!.HttpContext!.User!.Claims!.FirstOrDefault(x => x.Type == "sub")!.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
namespace MyOffice.Web.Models.Account
|
||||
{
|
||||
using Data.Models.Accounts;
|
||||
using Services.Account.Domain;
|
||||
using User;
|
||||
|
||||
public class AccessRightsViewModel
|
||||
@@ -13,7 +14,7 @@
|
||||
|
||||
public static class AccessRightsViewModelExtensions
|
||||
{
|
||||
public static AccessRightsViewModel ToModel(this AccountAccess accountAccess)
|
||||
public static AccessRightsViewModel ToModel(this AccountAccessDto accountAccess)
|
||||
{
|
||||
return new AccessRightsViewModel
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
namespace MyOffice.Web.Models.Account;
|
||||
|
||||
using Data.Models.Accounts;
|
||||
using Services.Account.Domain;
|
||||
|
||||
public class AccountDetailedViewModel
|
||||
{
|
||||
@@ -8,9 +9,9 @@ public class AccountDetailedViewModel
|
||||
public decimal Rest { get; set; }
|
||||
}
|
||||
|
||||
public static class AccountDetailedViewModelExtensions
|
||||
/*public static class AccountDetailedViewModelExtensions
|
||||
{
|
||||
public static AccountDetailedViewModel ToModel(this AccountDetailed input)
|
||||
public static AccountDetailedViewModel ToModel(this AccountDetailedDto input)
|
||||
{
|
||||
return new AccountDetailedViewModel
|
||||
{
|
||||
@@ -18,4 +19,4 @@ public static class AccountDetailedViewModelExtensions
|
||||
Rest = input.Rest,
|
||||
};
|
||||
}
|
||||
}
|
||||
}*/
|
||||
@@ -8,6 +8,7 @@ public class AccountEditRequestModel
|
||||
public string Name { get; set; } = null!;
|
||||
[Required]
|
||||
public string CurrencyId { get; set; } = null!;
|
||||
public string? CategoryId { get; set; } = null!;
|
||||
public string? UserId { get; set; } = null!;
|
||||
public string? CategoryId { get; set; }
|
||||
public string? UserId { get; set; }
|
||||
public string? Type { get; set; }
|
||||
}
|
||||
@@ -1,19 +1,25 @@
|
||||
namespace MyOffice.Web.Models.Account
|
||||
{
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using AutoMapper;
|
||||
using Core.Extensions;
|
||||
using Data.Models.Accounts;
|
||||
using Services.Account.Domain;
|
||||
using Services.Identity;
|
||||
using User;
|
||||
|
||||
public class AccountViewModel
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
|
||||
[Required]
|
||||
[Required]
|
||||
public string Name { get; set; } = null!;
|
||||
public string Type { get; set; } = null!;
|
||||
|
||||
[Required]
|
||||
[Required]
|
||||
public string CurrencyId { get; set; } = null!;
|
||||
public string? CurrencyName { get; set; }
|
||||
public bool AllowDelete { get; set; }
|
||||
|
||||
public List<AccountCategoryViewModel>? Categories { get; set; }
|
||||
|
||||
@@ -23,9 +29,48 @@
|
||||
public List<AccessRightsViewModel>? AccessRights { get; set; }
|
||||
}
|
||||
|
||||
public static class AccountViewModelExtensions
|
||||
public class ViewModelProfile : Profile
|
||||
{
|
||||
public static AccountViewModel ToModel(this Account input)
|
||||
public ViewModelProfile()
|
||||
{
|
||||
CreateMap<Guid, string>().ConvertUsing(x => x.ToShort());
|
||||
}
|
||||
}
|
||||
|
||||
public class AccountViewModelProfile : Profile
|
||||
{
|
||||
public AccountViewModelProfile(
|
||||
IContextProvider contextProvider
|
||||
)
|
||||
{
|
||||
|
||||
CreateMap<AccountDetailedDto, AccountDetailedViewModel>()
|
||||
.ForMember(x => x.Account, o => o.MapFrom(x => x.Account))
|
||||
;
|
||||
|
||||
CreateMap<UserDto, UserViewModel>();
|
||||
|
||||
CreateMap<MyOffice.Data.Models.Users.User, UserViewModel>();
|
||||
|
||||
CreateMap<AccountDto, AccountViewModel>()
|
||||
.ForMember(x => x.Type, o => o.MapFrom(x => x.AccessRights!.FirstOrDefault(a => a.UserId == contextProvider.UserId)!.Type.ToString()))
|
||||
.ForMember(x => x.CurrencyId, o => o.MapFrom(x => x.CurrencyGlobalId))
|
||||
.ForMember(x => x.CurrencyName, o => o.MapFrom(x => x.Currency!.Name))
|
||||
.ForMember(x => x.AllowDelete, o => o.MapFrom(x => !x.HasMotions))
|
||||
;
|
||||
|
||||
CreateMap<AccountAccountCategoryDto, AccountCategoryViewModel>()
|
||||
.ForMember(x => x.Id, o => o.MapFrom(x => x.CategoryId))
|
||||
.ForMember(x => x.Name, o => o.MapFrom(x => x.Category!.Name))
|
||||
;
|
||||
|
||||
CreateMap<AccountAccessDto, AccessRightsViewModel>();
|
||||
}
|
||||
}
|
||||
|
||||
/*public static class AccountViewModelExtensions
|
||||
{
|
||||
public static AccountViewModel ToModel(this AccountDto input)
|
||||
{
|
||||
return new AccountViewModel
|
||||
{
|
||||
@@ -41,5 +86,5 @@
|
||||
.ToList(),
|
||||
};
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
<PackageReference Include="Auth0.AuthenticationApi" Version="7.17.4" />
|
||||
<PackageReference Include="Auth0.Core" Version="7.17.4" />
|
||||
<PackageReference Include="Auth0.ManagementApi" Version="7.17.4" />
|
||||
<PackageReference Include="AutoMapper" Version="12.0.1" />
|
||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
|
||||
<PackageReference Include="Google.Apis.Auth" Version="1.58.0-beta01" />
|
||||
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
|
||||
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="4.1.2" />
|
||||
|
||||
+36
-2
@@ -37,10 +37,14 @@ using Identity.Configure;
|
||||
using Infrastructure;
|
||||
using Microsoft.Extensions.Logging.Console;
|
||||
using IdentityServer4.Services;
|
||||
using Models.Account;
|
||||
using MyOffice.Services.Currency;
|
||||
using Services.Account;
|
||||
using Services.Item;
|
||||
using MyOffice.Services.Dashboard;
|
||||
using Services.Account.Domain;
|
||||
using MyOffice.Services.Identity;
|
||||
using AutoMapper;
|
||||
|
||||
public class Program
|
||||
{
|
||||
@@ -92,6 +96,10 @@ public class Program
|
||||
|
||||
AddIdentityServices(builder);
|
||||
|
||||
builder.Services.AddScoped<IContextProvider, ContextProvider>();
|
||||
|
||||
AddMapping(builder);
|
||||
|
||||
AddRepositories(builder);
|
||||
|
||||
AddBusinessServices(builder);
|
||||
@@ -205,6 +213,20 @@ public class Program
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddMapping(WebApplicationBuilder builder)
|
||||
{
|
||||
builder.Services.AddSingleton(provider => new MapperConfiguration(cfg =>
|
||||
{
|
||||
cfg.AddProfile(new AccountMappingProfile());
|
||||
cfg.AddProfile(new ViewModelProfile());
|
||||
cfg.AddProfile(new AccountViewModelProfile(provider.CreateScope().ServiceProvider.GetService<IContextProvider>()!));
|
||||
}).CreateMapper());
|
||||
|
||||
//builder.Services.AddAutoMapper(typeof(AccountMappingProfile));
|
||||
//builder.Services.AddAutoMapper(typeof(AccountViewModelProfile));
|
||||
//builder.Services.AddAutoMapper(typeof(ViewModelProfile));
|
||||
}
|
||||
|
||||
private static void AddRepositories(WebApplicationBuilder builder)
|
||||
{
|
||||
builder.Services.AddScoped<IUserRepository, UserRepository>();
|
||||
@@ -216,6 +238,7 @@ public class Program
|
||||
|
||||
builder.Services.AddScoped<IAccountCategoryRepository, AccountCategoryRepository>();
|
||||
builder.Services.AddScoped<IAccountRepository, AccountRepository>();
|
||||
builder.Services.AddScoped<IAccountAccessRepository, AccountAccessRepository>();
|
||||
builder.Services.AddScoped<IAccountAccountCategoryRepository, AccountAccountCategoryRepository>();
|
||||
|
||||
builder.Services.AddScoped<IItemCategoryRepository, ItemCategoryRepository>();
|
||||
@@ -274,9 +297,20 @@ public class Program
|
||||
{
|
||||
_firstRequest = false;
|
||||
|
||||
// set real frontend host
|
||||
globalSettings = ctx.RequestServices.GetRequiredService<GlobalSettings>();
|
||||
globalSettings.Host = GetFrontendHost(ctx, logger);
|
||||
|
||||
var configuration = ctx.RequestServices.GetRequiredService<IConfiguration>();
|
||||
var frontEndHost = configuration.GetValue<string>("FrontEnd:Host");
|
||||
var isDynamicFrontEndHost = frontEndHost.IsMissing();
|
||||
if (!isDynamicFrontEndHost)
|
||||
{
|
||||
globalSettings.Host = frontEndHost;
|
||||
}
|
||||
else
|
||||
{
|
||||
// set real frontend host
|
||||
globalSettings.Host = GetFrontendHost(ctx, logger);
|
||||
}
|
||||
|
||||
// update identity server
|
||||
var options = ctx.RequestServices.GetRequiredService<IdentityServerOptions>();
|
||||
|
||||
Reference in New Issue
Block a user