Compare commits
10
Commits
cf89dd6a4d
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
033b4fc247 | ||
|
|
4ddab34ad1 | ||
|
|
f495fc9b8f | ||
|
|
2feaf50802 | ||
|
|
775146ee86 | ||
|
|
045f60e373 | ||
|
|
a09fc7ece3 | ||
|
|
25184e9edc | ||
|
|
0d45061d81 | ||
|
|
70edf34cf6 |
@@ -0,0 +1,16 @@
|
||||
# Editor configuration, see https://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = tabs
|
||||
indent_size = 4
|
||||
insert_final_newline = false
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.ts]
|
||||
quote_type = single
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
||||
@@ -359,6 +359,8 @@ MigrationBackup/
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
.vscode/
|
||||
|
||||
/MyOffice.SPA/.vscode
|
||||
/MyOffice.SPA/dist/
|
||||
/MyOffice.SPA/src/environments/environment.ts
|
||||
@@ -382,3 +384,4 @@ package-lock.json
|
||||
/MyOffice.Shared/appsettings.shared.Production.json
|
||||
/linux_deploy_mybank.bat
|
||||
/linux_deploy_office.bat
|
||||
linux_deploy_office_public.bat
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
namespace MyOffice.Core.Attributes;
|
||||
|
||||
using System;
|
||||
|
||||
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
|
||||
public class LinkAttribute : Attribute
|
||||
{
|
||||
public LinkAttribute(Type type)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
|
||||
public class LinkFromAttribute : Attribute
|
||||
{
|
||||
public LinkFromAttribute(Type type)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
|
||||
public class LinkToAttribute : Attribute
|
||||
{
|
||||
public LinkToAttribute(Type type)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
|
||||
public class LinkWithAttribute : Attribute
|
||||
{
|
||||
public LinkWithAttribute(Type type)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace MyOffice.Core;
|
||||
|
||||
public class Error
|
||||
{
|
||||
private Exception? _exception;
|
||||
|
||||
public Error(string message)
|
||||
{
|
||||
Message = message;
|
||||
}
|
||||
|
||||
public Error(Exception exception): this(exception.GetType().Name)
|
||||
{
|
||||
_exception = exception;
|
||||
}
|
||||
|
||||
public Error(string message, Exception exception): this(message)
|
||||
{
|
||||
_exception = exception;
|
||||
}
|
||||
|
||||
public string Message { get; private set;}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace MyOffice.Core.Helpers;
|
||||
|
||||
using MyOffice.Core.Extensions;
|
||||
|
||||
public class RandomizationHelper
|
||||
{
|
||||
public static string Generate(int length)
|
||||
{
|
||||
var result = "";
|
||||
|
||||
while(result.Length < length)
|
||||
{
|
||||
result += Guid.NewGuid().ToShort();
|
||||
}
|
||||
|
||||
return result.Substring(0, length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace MyOffice.Core;
|
||||
|
||||
public interface IDataModel
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace MyOffice.Core;
|
||||
|
||||
public interface IDataModelDto<TSource> where TSource : IDataModel
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
namespace MyOffice.Data.Models.Accounts;
|
||||
|
||||
using Currencies;
|
||||
using MyOffice.Core;
|
||||
using MyOffice.Data.Models.Users;
|
||||
|
||||
public class Account
|
||||
public class Account: IDataModel
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string CurrencyGlobalId { get; set; } = null!;
|
||||
@@ -17,7 +18,7 @@ public class Account
|
||||
public IEnumerable<AccountAccessInvite>? Invites { get; set; }
|
||||
}
|
||||
|
||||
public class AccountDetailed
|
||||
public class AccountDetailed: IDataModel
|
||||
{
|
||||
public Account Account { get; set; } = null!;
|
||||
public decimal TotalPlus { get; set; }
|
||||
@@ -28,10 +29,10 @@ public class AccountDetailed
|
||||
public class AccountSimple
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Name { get; set; } = null!;
|
||||
public AccountAccessTypeEnum Type { get; set; }
|
||||
public string CurrencyName { get; set; }
|
||||
public string CurrencyShortName { 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; }
|
||||
@@ -42,7 +43,7 @@ public class AccountSimple
|
||||
public class MotionTotalSimple
|
||||
{
|
||||
public Guid? Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Name { get; set; } = null!;
|
||||
public string CurrencyId { get; set; } = null!;
|
||||
public string CurrencyName { get; set; } = null!;
|
||||
public decimal CurrencyRate { get; set; }
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
namespace MyOffice.Data.Models.Accounts;
|
||||
|
||||
using Core.Attributes;
|
||||
using Users;
|
||||
|
||||
public class AccountAccessInvite
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace MyOffice.Data.Models.Accounts.Domain;
|
||||
|
||||
using Currencies;
|
||||
|
||||
public class AccountWithRate
|
||||
{
|
||||
public Account Account { get; set; } = null!;
|
||||
public Currency? Currency { get; set; }
|
||||
public CurrencyRate? Rate { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace MyOffice.Data.Models.Notifications;
|
||||
|
||||
public enum EmailTemplateEnum
|
||||
{
|
||||
PasswordRestore,
|
||||
}
|
||||
|
||||
public class EmailTemplate
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Subject { get; set; }
|
||||
public string Sender { get; set; }
|
||||
public string SenderName { get; set; }
|
||||
public string Template { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace MyOffice.Data.Models.Verifications;
|
||||
|
||||
using MyOffice.Data.Models.Users;
|
||||
|
||||
public class VerificationCode
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public User? User { get; set; }
|
||||
public string Code { get; set; } = null!;
|
||||
public string DestinationType { get; set; } = null!;
|
||||
public string Destination { get; set; } = null!;
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public DateTime ExpiresOn { get; set; }
|
||||
public DateTime? VerifiedOn { get; set; }
|
||||
public string Template { get; set; } = null!;
|
||||
public string? Metadata { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace MyOffice.Data.Models.Verifications;
|
||||
|
||||
public enum VerificationCodeTemplateEnum
|
||||
{
|
||||
password_restore,
|
||||
email_confirm,
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace MyOffice.Data.Models.Verifications;
|
||||
|
||||
public enum VerificationCodeTypeEnum
|
||||
{
|
||||
email,
|
||||
phone,
|
||||
}
|
||||
@@ -3,6 +3,8 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Models.Accounts;
|
||||
using MyOffice.Data.Models.Accounts.Domain;
|
||||
using MyOffice.Data.Models.Currencies;
|
||||
using MyOffice.Data.Repositories;
|
||||
|
||||
public class AccountRepository : AppRepository<Account>, IAccountRepository
|
||||
@@ -19,11 +21,15 @@ public class AccountRepository : AppRepository<Account>, IAccountRepository
|
||||
{
|
||||
return _context.Accounts!
|
||||
.Include(x => x.CurrencyGlobal)
|
||||
.Include(x => x.Categories!.Where(x => x.Category.UserId == userId))!
|
||||
// categories created with current user
|
||||
.Include(x => x.Categories!.Where(c => c.Category.UserId == userId))!
|
||||
.ThenInclude(x => x.Category)
|
||||
.Include(x => x.AccessRights)!
|
||||
// access rights created with current user
|
||||
.Include(x => x.AccessRights!.Where(a => a.OwnerId == userId))!
|
||||
.ThenInclude(x => x.User)
|
||||
.Include(x => x.Motions)!
|
||||
// require only one motions to check if can to delete account
|
||||
.Include(x => x.Motions!.Take(1))!
|
||||
// only accounts with access to current user
|
||||
.Where(x => x.AccessRights!.Any(a => a.UserId == userId))
|
||||
.ToList();
|
||||
}
|
||||
@@ -116,42 +122,40 @@ public class AccountRepository : AppRepository<Account>, IAccountRepository
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public decimal GetPeriodIncome(Guid userId, DateTime from, DateTime to)
|
||||
public List<AccountWithRate> GetAccountsWithRate(Guid userId, DateTime date)
|
||||
{
|
||||
return _context.Accounts
|
||||
.Where(x => x.AccessRights!.Any(u => u.UserId == userId))
|
||||
.Include(x => x.CurrencyGlobal!)
|
||||
.ThenInclude(x => x.Currencies!)
|
||||
.ThenInclude(x => x.CurrentRate!)
|
||||
.Select(x => new {
|
||||
Currency = x.CurrencyGlobal!.Currencies!.FirstOrDefault(x => x.UserId == userId),
|
||||
Amount = x.Motions!
|
||||
.Where(x => !x.Item!.Category!.IsInternal)
|
||||
.Where(x => x.DateTime >= from && x.DateTime <= to)
|
||||
.Sum(m => m.AmountPlus)
|
||||
})
|
||||
.ToList()
|
||||
.Select(x => x.Amount * (x.Currency?.CurrentRate?.Rate * x.Currency?.CurrentRate?.Quantity))
|
||||
.Sum() ?? 0;
|
||||
}
|
||||
var accounts = _context.Accounts
|
||||
.Where(x => x.AccessRights!.Any(a => a.UserId == userId))
|
||||
.ToList();
|
||||
|
||||
public decimal GetPeriodOutcome(Guid userId, DateTime from, DateTime to)
|
||||
{
|
||||
return _context.Accounts
|
||||
.Where(x => x.AccessRights!.Any(u => u.UserId == userId))
|
||||
.Include(x => x.CurrencyGlobal!)
|
||||
.ThenInclude(x => x.Currencies!)
|
||||
.ThenInclude(x => x.CurrentRate!)
|
||||
.Select(x => new {
|
||||
Currency = x.CurrencyGlobal!.Currencies!.FirstOrDefault(x => x.UserId == userId),
|
||||
Amount = x.Motions!
|
||||
.Where(x => !x.Item!.Category!.IsInternal)
|
||||
.Where(x => x.DateTime >= from && x.DateTime <= to)
|
||||
.Sum(m => m.AmountMinus)
|
||||
var currencyIds = accounts
|
||||
.Select(x => x.CurrencyGlobalId)
|
||||
.ToList();
|
||||
|
||||
var rates = _context.CurrencyRates
|
||||
.Include(x => x.Currency)
|
||||
.Where(x => x.Currency!.UserId == userId)
|
||||
.Where(x => x.DateTime <= date)
|
||||
.Where(x => currencyIds.Contains(x.Currency!.CurrencyGlobalId))
|
||||
.GroupBy(x => x.Currency!.CurrencyGlobalId)
|
||||
.Select(x => x.OrderByDescending(r => r.DateTime).First())
|
||||
.ToList();
|
||||
|
||||
return accounts
|
||||
.Select(account =>
|
||||
{
|
||||
var rate = rates.FirstOrDefault(rate => rate.Currency!.CurrencyGlobalId == account.CurrencyGlobalId);
|
||||
|
||||
var result = new AccountWithRate
|
||||
{
|
||||
Account = account,
|
||||
Currency = rate?.Currency,
|
||||
Rate = rate,
|
||||
};
|
||||
|
||||
return result;
|
||||
})
|
||||
.ToList()
|
||||
.Select(x => x.Amount * (x.Currency?.CurrentRate?.Rate * x.Currency?.CurrentRate?.Quantity))
|
||||
.Sum() ?? 0;
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public List<AccountSimple> GetRestAtDate(Guid userId, DateTime date)
|
||||
@@ -184,8 +188,8 @@ public class AccountRepository : AppRepository<Account>, IAccountRepository
|
||||
Id = x.Id,
|
||||
Name = x.Name,
|
||||
Type = x.Type,
|
||||
CurrencyName = x.Currency!.Name,
|
||||
CurrencyShortName = x.Currency!.ShortName,
|
||||
CurrencyName = x.Currency?.Name,
|
||||
CurrencyShortName = x.Currency?.ShortName,
|
||||
CurrencyRate = x.CurrentRate?.Rate,
|
||||
CurrencyQuantity = x.CurrentRate?.Quantity,
|
||||
TotalMinus = x.Minus,
|
||||
@@ -197,63 +201,112 @@ public class AccountRepository : AppRepository<Account>, IAccountRepository
|
||||
|
||||
public List<MotionTotalSimple> GetIncomeByCategories(Guid userId, DateTime from, DateTime to)
|
||||
{
|
||||
var accounts = GetAccountsWithRate(userId, to);
|
||||
var accountIds = accounts.Select(x => x.Account.Id);
|
||||
|
||||
return _context.Motions
|
||||
.Where(x => x.DateTime >= from && x.DateTime <= to)
|
||||
.Where(x => x.Item.Category!.UserId == userId)
|
||||
.Where(x => accountIds.Contains(x.AccountId))
|
||||
.Where(x => !x.Item.Category!.IsInternal)
|
||||
.GroupBy(x => new { x.Item.CategoryId, x.Item.Category!.Name })
|
||||
.GroupBy(x => new
|
||||
{
|
||||
Id = x.Item.CategoryId,
|
||||
Name = x.Item.Category!.Name,
|
||||
IsUserCategory = x.Item.Category!.UserId == userId,
|
||||
CurrencyId = x.Account.CurrencyGlobalId,
|
||||
CurrencyName = x.Account.CurrencyGlobal!.Name,
|
||||
})
|
||||
.ToList()
|
||||
.Select(x => new MotionTotalSimple
|
||||
{
|
||||
Id = x.Key.CategoryId,
|
||||
Id = x.Key.IsUserCategory ? x.Key.Id : userId,
|
||||
Name = x.Key.Name,
|
||||
Amount = x.Sum(a => a.AmountPlus)
|
||||
}).ToList();
|
||||
CurrencyId = x.Key.CurrencyId,
|
||||
CurrencyName = x.Key.CurrencyName,
|
||||
Amount = x.Sum(a => a.AmountPlus),
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public List<MotionTotalSimple> GetIncomeByCategory(Guid userId, Guid categoryId, DateTime from, DateTime to)
|
||||
{
|
||||
return _context.Motions
|
||||
.Where(x => x.DateTime >= from && x.DateTime <= to)
|
||||
.Where(x => x.Item.Category!.UserId == userId)
|
||||
.Where(x => x.Item.CategoryId == categoryId)
|
||||
.Where(x => !x.Item.Category!.IsInternal)
|
||||
.Where(x => x.Item.Category!.UserId == userId)
|
||||
.GroupBy(x => new { Id = x.Item.ItemGlobalId, x.Item.ItemGlobal.Name })
|
||||
.GroupBy(x => new
|
||||
{
|
||||
Id = x.Item.ItemGlobalId,
|
||||
Name = x.Item.ItemGlobal!.Name,
|
||||
CurrencyId = x.Account.CurrencyGlobalId,
|
||||
CurrencyName = x.Account.CurrencyGlobal!.Name,
|
||||
})
|
||||
.Select(x => new MotionTotalSimple
|
||||
{
|
||||
Name = x.Key.Name,
|
||||
CurrencyId = x.Key.CurrencyId,
|
||||
CurrencyName = x.Key.CurrencyName,
|
||||
Amount = x.Sum(a => a.AmountPlus),
|
||||
}).ToList();
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
||||
public List<MotionTotalSimple> GetOutcomeByCategories(Guid userId, DateTime from, DateTime to)
|
||||
{
|
||||
var accounts = GetAccountsWithRate(userId, to);
|
||||
var accountIds = accounts.Select(x => x.Account.Id);
|
||||
|
||||
return _context.Motions
|
||||
.Where(x => x.DateTime >= from && x.DateTime <= to)
|
||||
.Where(x => x.Item.Category!.UserId == userId)
|
||||
.Where(x => accountIds.Contains(x.AccountId))
|
||||
.Where(x => !x.Item.Category!.IsInternal)
|
||||
.GroupBy(x => new { x.Item.CategoryId, x.Item.Category!.Name })
|
||||
.GroupBy(x => new
|
||||
{
|
||||
Id = x.Item.CategoryId,
|
||||
Name = x.Item.Category!.Name,
|
||||
IsUserCategory = x.Item.Category!.UserId == userId,
|
||||
CurrencyId = x.Account.CurrencyGlobalId,
|
||||
CurrencyName = x.Account.CurrencyGlobal!.Name,
|
||||
})
|
||||
.Select(x => new MotionTotalSimple
|
||||
{
|
||||
Id = x.Key.CategoryId,
|
||||
Name = x.Key.Name,
|
||||
Amount = x.Sum(a => a.AmountMinus)
|
||||
Id = x.Key.IsUserCategory ? x.Key.Id : userId,
|
||||
Name = x.Key.IsUserCategory ? x.Key.Name : "UnCategorized",
|
||||
//Name = x.Key.Name,
|
||||
CurrencyId = x.Key.CurrencyId,
|
||||
CurrencyName = x.Key.CurrencyName,
|
||||
Amount = x.Sum(a => a.AmountMinus),
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
|
||||
public List<MotionTotalSimple> GetOutcomeByCategory(Guid userId, Guid categoryId, DateTime from, DateTime to)
|
||||
{
|
||||
var accounts = GetAccountsWithRate(userId, to);
|
||||
var accountIds = accounts.Select(x => x.Account.Id);
|
||||
|
||||
return _context.Motions
|
||||
.Where(x => x.DateTime >= from && x.DateTime <= to)
|
||||
.Where(x => x.Item.CategoryId == categoryId)
|
||||
.Where(x => accountIds.Contains(x.AccountId))
|
||||
.Where(x => !x.Item.Category!.IsInternal)
|
||||
.Where(x => x.Item.Category!.UserId == userId)
|
||||
.GroupBy(x => new { Id = x.Item.ItemGlobalId, x.Item.ItemGlobal.Name })
|
||||
.Where(x => x.Item.CategoryId == categoryId)
|
||||
.GroupBy(x => new
|
||||
{
|
||||
Id = x.Item.ItemGlobalId,
|
||||
Name = x.Item.ItemGlobal!.Name,
|
||||
CurrencyId = x.Account.CurrencyGlobalId,
|
||||
CurrencyName = x.Account.CurrencyGlobal!.Name,
|
||||
})
|
||||
.Select(x => new MotionTotalSimple
|
||||
{
|
||||
CurrencyId = x.Key.CurrencyId,
|
||||
CurrencyName = x.Key.CurrencyName,
|
||||
Name = x.Key.Name,
|
||||
Amount = x.Sum(a => a.AmountMinus)
|
||||
}).ToList();
|
||||
Amount = x.Sum(a => a.AmountMinus),
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
@@ -15,8 +15,6 @@ public interface IAccountRepository
|
||||
bool Remove(Account account);
|
||||
List<Account> FindAccounts(Guid userId, string term);
|
||||
|
||||
decimal GetPeriodIncome(Guid userId, DateTime from, DateTime to);
|
||||
decimal GetPeriodOutcome(Guid userId, DateTime from, DateTime to);
|
||||
List<AccountSimple> GetRestAtDate(Guid userId, DateTime date);
|
||||
List<MotionTotalSimple> GetIncomeByCategories(Guid userId, DateTime from, DateTime to);
|
||||
List<MotionTotalSimple> GetIncomeByCategory(Guid userId, Guid categoryId, DateTime from, DateTime to);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
namespace MyOffice.Data.Repositories.Currency;
|
||||
|
||||
using System.Xml.Schema;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Models.Currencies;
|
||||
|
||||
@@ -18,18 +19,23 @@ public class CurrencyRateRepository : AppRepository<CurrencyRate>, ICurrencyRate
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public List<CurrencyRate> GetLastRates(List<string> currencyIds)
|
||||
public Dictionary<string, CurrencyRate> GetLastRates(Guid userId, List<string> currencyIds, DateTime? before = null)
|
||||
{
|
||||
return _context.CurrencyRates
|
||||
.Include(x => x.Currency)
|
||||
.Include(x => x.Currency!.CurrencyGlobal)
|
||||
.Where(x => x.DateTime <= before)
|
||||
.Where(x => x.Currency!.UserId == userId)
|
||||
.Where(x => currencyIds.Contains(x.Currency!.CurrencyGlobalId))
|
||||
.GroupBy(x => new
|
||||
{
|
||||
x.CurrencyId,
|
||||
//x.Currency!.Name,
|
||||
//x.Currency!.CurrencyGlobalId,
|
||||
}, (key, g) => g.OrderByDescending(x => x.DateTime).First())
|
||||
.ToList();
|
||||
x.Currency!.CurrencyGlobalId
|
||||
}, (key, g) => new
|
||||
{
|
||||
key.CurrencyGlobalId,
|
||||
rate = g.OrderByDescending(x => x.DateTime).First()
|
||||
})
|
||||
.ToDictionary(x => x.CurrencyGlobalId, x => x.rate);
|
||||
}
|
||||
|
||||
public bool AddRate(CurrencyRate currencyRate)
|
||||
|
||||
@@ -5,7 +5,7 @@ using Models.Currencies;
|
||||
public interface ICurrencyRateRepository
|
||||
{
|
||||
List<CurrencyRate> GetLastRates(Guid currencyId, DateTime? before = null, int count = 1);
|
||||
List<CurrencyRate> GetLastRates(List<string> currencyIds);
|
||||
Dictionary<string, CurrencyRate> GetLastRates(Guid userId, List<string> currencyIds, DateTime? before = null);
|
||||
bool AddRate(CurrencyRate currencyRate);
|
||||
List<CurrencyRate> GetAtDate(Guid currencyId, DateTime date);
|
||||
}
|
||||
@@ -7,4 +7,5 @@ public interface IItemGlobalRepository
|
||||
ItemGlobal? Get(Guid id);
|
||||
ItemGlobal? GetByName(string name);
|
||||
bool Add(ItemGlobal itemGlobal);
|
||||
List<ItemGlobal> GetAvailableToUser(Guid userId);
|
||||
}
|
||||
@@ -6,8 +6,7 @@ public interface IItemRepository
|
||||
{
|
||||
List<Item> GetAll(Guid userId);
|
||||
List<Item> GetByCategory(Guid userId, Guid categoryId);
|
||||
|
||||
Item? GetByGlobal(Guid userId, Guid globalMotionId);
|
||||
Item? GetByGlobal(Guid userId, Guid globalItemId);
|
||||
bool Add(Item item);
|
||||
bool Update(Item item);
|
||||
List<Item> Find(Guid userId, string term, int limit);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
namespace MyOffice.Data.Repositories.Item;
|
||||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MyOffice.Data.Models.Items;
|
||||
|
||||
public class ItemGlobalRepository : AppRepository<ItemGlobal>, IItemGlobalRepository
|
||||
@@ -18,4 +19,19 @@ public class ItemGlobalRepository : AppRepository<ItemGlobal>, IItemGlobalReposi
|
||||
{
|
||||
return AddBase(itemGlobal) > 0;
|
||||
}
|
||||
|
||||
public List<ItemGlobal> GetAvailableToUser(Guid userId)
|
||||
{
|
||||
return _context.Motions
|
||||
.Include(x => x.Item)
|
||||
.ThenInclude(x => x.ItemGlobal)
|
||||
.ThenInclude(x => x.Items)
|
||||
.ThenInclude(x => x.Category)
|
||||
.Where(x => x.Account.AccessRights!.Any(a => a.UserId == userId))
|
||||
.Where(x => x.Item.ItemGlobal.Items.All(g => g.Category!.UserId != userId))
|
||||
.Select(x => x.Item.ItemGlobal)
|
||||
.GroupBy(x => x.Id)
|
||||
.Select(x => x.First())
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
@@ -25,13 +25,13 @@ public class ItemRepository : AppRepository<Item>, IItemRepository
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public Item? GetByGlobal(Guid userId, Guid globalMotionId)
|
||||
public Item? GetByGlobal(Guid userId, Guid globalItemId)
|
||||
{
|
||||
return _context.Items
|
||||
.Include(x => x.Motions)
|
||||
.Include(x => x.Category)
|
||||
.Include(x => x.ItemGlobal)
|
||||
.FirstOrDefault(x => x.Category!.UserId == userId && x.ItemGlobalId == globalMotionId);
|
||||
.FirstOrDefault(x => x.Category!.UserId == userId && x.ItemGlobalId == globalItemId);
|
||||
}
|
||||
|
||||
public bool Update(Item item)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace MyOffice.Data.Repositories.Item;
|
||||
|
||||
using MyOffice.Data.Models.Notifications;
|
||||
|
||||
public class EmailTemplateRepository : AppRepository<EmailTemplate>, IEmailTemplateRepository
|
||||
{
|
||||
public EmailTemplate? Get(EmailTemplateEnum emailTemplate)
|
||||
{
|
||||
var emailTemplateStr = emailTemplate.ToString();
|
||||
return _context.EmailTemplates.FirstOrDefault(x => x.Id == emailTemplateStr);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace MyOffice.Data.Repositories.Item;
|
||||
|
||||
using MyOffice.Data.Models.Notifications;
|
||||
|
||||
public interface IEmailTemplateRepository
|
||||
{
|
||||
EmailTemplate? Get(EmailTemplateEnum emailTemplate);
|
||||
}
|
||||
@@ -5,7 +5,6 @@ using DbContext;
|
||||
|
||||
public class RepositoryBase<TEntity> where TEntity : class
|
||||
{
|
||||
//TODO: Rename
|
||||
protected readonly AppDbContext _context;
|
||||
|
||||
protected RepositoryBase(
|
||||
@@ -52,7 +51,6 @@ public class RepositoryBase<TEntity> where TEntity : class
|
||||
|
||||
protected int AddBase(TEntity entity)
|
||||
{
|
||||
//_context.Add(entity);
|
||||
_context.Entry(entity).State = EntityState.Added;
|
||||
|
||||
var result = SaveChanges();
|
||||
@@ -75,7 +73,6 @@ public class RepositoryBase<TEntity> where TEntity : class
|
||||
|
||||
protected int UpdateBase(TEntity entity)
|
||||
{
|
||||
//_context.Attach(entity);
|
||||
_context.Entry(entity).State = EntityState.Modified;
|
||||
|
||||
var result = SaveChanges();
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using MyOffice.Data.Models.Verifications;
|
||||
|
||||
namespace MyOffice.Data.Repositories.Item;
|
||||
|
||||
|
||||
public interface IVerificationCodeRepository
|
||||
{
|
||||
VerificationCode? GetByCode(string code);
|
||||
bool Add(VerificationCode entity);
|
||||
bool Update(VerificationCode entity);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace MyOffice.Data.Repositories.Item;
|
||||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MyOffice.Data.Models.Verifications;
|
||||
|
||||
public class VerificationCodeRepository : AppRepository<VerificationCode>, IVerificationCodeRepository
|
||||
{
|
||||
public bool Add(VerificationCode entity)
|
||||
{
|
||||
return AddBase(entity) > 0;
|
||||
}
|
||||
|
||||
public bool Update(VerificationCode entity)
|
||||
{
|
||||
return UpdateBase(entity) > 0;
|
||||
}
|
||||
|
||||
public VerificationCode? GetByCode(string code)
|
||||
{
|
||||
return _context.Verifications.FirstOrDefault(x => x.Code == code);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ using Data.Models.Items;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Data.Models.Users;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using MyOffice.Data.Models.Verifications;
|
||||
using MyOffice.Data.Models.Notifications;
|
||||
|
||||
public enum AppDbContextProvidersEnum
|
||||
{
|
||||
@@ -46,6 +48,9 @@ public class AppDbContext : DbContext
|
||||
public DbSet<Item> Items { get; set; } = null!;
|
||||
public DbSet<Motion> Motions { get; set; } = null!;
|
||||
|
||||
public DbSet<VerificationCode> Verifications { get; set; } = null!;
|
||||
public DbSet<EmailTemplate> EmailTemplates { get; set; } = null!;
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
var noCaseCollation = _noCaseCollation[_provider];
|
||||
@@ -82,10 +87,29 @@ public class AppDbContext : DbContext
|
||||
CurrencyCreating(modelBuilder);
|
||||
AccountCreating(modelBuilder);
|
||||
MotionsCreating(modelBuilder);
|
||||
VerificationsCreating(modelBuilder);
|
||||
EmailTemplateCreating(modelBuilder);
|
||||
|
||||
base.OnModelCreating(modelBuilder);
|
||||
}
|
||||
|
||||
private void VerificationsCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<VerificationCode>()
|
||||
.HasKey(x => x.Id);
|
||||
|
||||
modelBuilder.Entity<VerificationCode>()
|
||||
.HasOne(x => x.User)
|
||||
.WithMany()
|
||||
.HasForeignKey(x => x.UserId);
|
||||
}
|
||||
|
||||
private void EmailTemplateCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<EmailTemplate>()
|
||||
.HasKey(x => x.Id);
|
||||
}
|
||||
|
||||
private void UserCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<User>()
|
||||
@@ -128,24 +152,11 @@ public class AppDbContext : DbContext
|
||||
|
||||
private void AccountCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
#region Account
|
||||
|
||||
modelBuilder.Entity<Account>()
|
||||
.HasKey(x => x.Id);
|
||||
|
||||
modelBuilder.Entity<AccountAccess>()
|
||||
.HasKey(x => x.Id);
|
||||
|
||||
modelBuilder.Entity<AccountAccessInvite>()
|
||||
.HasKey(x => x.Id);
|
||||
|
||||
modelBuilder.Entity<Motion>()
|
||||
.HasKey(x => x.Id);
|
||||
|
||||
modelBuilder.Entity<AccountCategory>()
|
||||
.HasKey(x => x.Id);
|
||||
|
||||
modelBuilder.Entity<AccountAccountCategory>()
|
||||
.HasKey(x => x.Id);
|
||||
|
||||
modelBuilder.Entity<Account>()
|
||||
.HasOne(x => x.CurrencyGlobal)
|
||||
.WithMany(x => x.Accounts)
|
||||
@@ -156,6 +167,13 @@ public class AppDbContext : DbContext
|
||||
.WithMany(x => x.Accounts)
|
||||
.HasForeignKey(x => x.OwnerId);
|
||||
|
||||
#endregion Account
|
||||
|
||||
#region AccountAccess
|
||||
|
||||
modelBuilder.Entity<AccountAccess>()
|
||||
.HasKey(x => x.Id);
|
||||
|
||||
modelBuilder.Entity<AccountAccess>()
|
||||
.HasOne(x => x.Account)
|
||||
.WithMany(x => x.AccessRights)
|
||||
@@ -171,6 +189,26 @@ public class AppDbContext : DbContext
|
||||
.WithMany(x => x.AccountAccessOwners)
|
||||
.HasForeignKey(x => x.OwnerId);
|
||||
|
||||
modelBuilder
|
||||
.Entity<AccountAccess>()
|
||||
.Property(d => d.Type)
|
||||
.HasConversion(new EnumToStringConverter<AccountAccessTypeEnum>());
|
||||
|
||||
modelBuilder.Entity<AccountAccess>()
|
||||
.HasIndex(p => new { p.AccountId, p.UserId })
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder.Entity<AccountAccess>()
|
||||
.HasIndex(p => new { p.AccountId, p.OwnerId })
|
||||
.IsUnique();
|
||||
|
||||
#endregion AccountAccess
|
||||
|
||||
#region AccountAccessInvite
|
||||
|
||||
modelBuilder.Entity<AccountAccessInvite>()
|
||||
.HasKey(x => x.Id);
|
||||
|
||||
modelBuilder.Entity<AccountAccessInvite>()
|
||||
.HasOne(x => x.User)
|
||||
.WithMany(x => x.AccountAccessInvites)
|
||||
@@ -180,16 +218,37 @@ public class AppDbContext : DbContext
|
||||
.HasOne(x => x.Account)
|
||||
.WithMany(x => x.Invites)
|
||||
.HasForeignKey(x => x.AccountId);
|
||||
|
||||
#endregion AccountAccessInvite
|
||||
|
||||
#region Motion
|
||||
|
||||
modelBuilder.Entity<Motion>()
|
||||
.HasKey(x => x.Id);
|
||||
|
||||
modelBuilder.Entity<Motion>()
|
||||
.HasOne(x => x.Account)
|
||||
.WithMany(x => x.Motions)
|
||||
.HasForeignKey(x => x.AccountId);
|
||||
|
||||
#endregion Motion
|
||||
|
||||
#region AccountCategory
|
||||
|
||||
modelBuilder.Entity<AccountCategory>()
|
||||
.HasKey(x => x.Id);
|
||||
|
||||
modelBuilder.Entity<AccountCategory>()
|
||||
.HasOne(x => x.User)
|
||||
.WithMany(x => x.AccountCategories)
|
||||
.HasForeignKey(x => x.UserId);
|
||||
|
||||
#endregion AccountCategory
|
||||
|
||||
#region AccountAccountCategory
|
||||
|
||||
modelBuilder.Entity<AccountAccountCategory>()
|
||||
.HasKey(x => x.Id);
|
||||
|
||||
modelBuilder.Entity<AccountAccountCategory>()
|
||||
.HasOne(x => x.Account)
|
||||
@@ -201,10 +260,16 @@ public class AppDbContext : DbContext
|
||||
.WithMany(x => x.Accounts)
|
||||
.HasForeignKey(x => x.CategoryId);
|
||||
|
||||
modelBuilder
|
||||
.Entity<AccountAccess>()
|
||||
.Property(d => d.Type)
|
||||
.HasConversion(new EnumToStringConverter<AccountAccessTypeEnum>());
|
||||
modelBuilder.Entity<AccountAccountCategory>()
|
||||
.HasIndex(p => new { p.AccountId, p.CategoryId })
|
||||
.IsUnique();
|
||||
|
||||
modelBuilder.Entity<AccountAccountCategory>()
|
||||
.HasOne(x => x.Category)
|
||||
.WithMany(x => x.Accounts)
|
||||
.HasForeignKey(x => x.CategoryId);
|
||||
|
||||
#endregion AccountAccountCategory
|
||||
}
|
||||
|
||||
private void MotionsCreating(ModelBuilder modelBuilder)
|
||||
|
||||
+729
@@ -0,0 +1,729 @@
|
||||
// <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("20230804145453_AccountAccesUnique")]
|
||||
partial class AccountAccesUnique
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
|
||||
.HasAnnotation("ProductVersion", "7.0.0")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("CurrencyGlobalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid?>("OwnerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyGlobalId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsAllowManage")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAllowRead")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAllowWrite")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("OwnerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.HasIndex("AccountId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AccountAccesses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime?>("AcceptedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsAllowWrite")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTime?>("RejectedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AccountAccessInvites");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("CategoryId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.ToTable("AccountAccountCategories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AccountCategories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<decimal>("AmountMinus")
|
||||
.HasPrecision(18, 6)
|
||||
.HasColumnType("numeric(18,6)");
|
||||
|
||||
b.Property<decimal>("AmountPlus")
|
||||
.HasPrecision(18, 6)
|
||||
.HasColumnType("numeric(18,6)");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<DateTime>("DateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<DateTime?>("DeletedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid?>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.HasIndex("ItemId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Motions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("CurrencyGlobalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int?>("CurrentRateId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("IsPrimary")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ShortName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyGlobalId");
|
||||
|
||||
b.HasIndex("CurrentRateId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("DefaultQuantity")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Symbol")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CurrencyGlobals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("CurrencyId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("DateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("Quantity")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("Rate")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyId");
|
||||
|
||||
b.ToTable("CurrencyRates");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("CategoryId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("ItemGlobalId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.HasIndex("ItemGlobalId");
|
||||
|
||||
b.ToTable("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsInternal")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("ItemCategories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ItemGlobals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("CurrencyId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.UseCollation("my_ci_collation");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("FullName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsEmailConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Phone")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.UseCollation("my_ci_collation");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyId");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.UseCollation("my_ci_collation");
|
||||
|
||||
b.Property<string>("ExternalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Provider")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.UseCollation("my_ci_collation");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("CurrencyGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "Owner")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("OwnerId");
|
||||
|
||||
b.Navigation("CurrencyGlobal");
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("AccessRights")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "Owner")
|
||||
.WithMany("AccountAccessOwners")
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountAccess")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Owner");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Invites")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountAccessInvites")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Categories")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("CategoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Category");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountCategories")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Motions")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
|
||||
.WithMany("Motions")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", null)
|
||||
.WithMany("AccountMotions")
|
||||
.HasForeignKey("UserId");
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("CurrencyGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("CurrentRateId");
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CurrencyGlobal");
|
||||
|
||||
b.Navigation("CurrentRate");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
|
||||
.WithMany("Rates")
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("CategoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("ItemGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Category");
|
||||
|
||||
b.Navigation("ItemGlobal");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("ItemCategories")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("UserClaims")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.Navigation("AccessRights");
|
||||
|
||||
b.Navigation("Categories");
|
||||
|
||||
b.Navigation("Invites");
|
||||
|
||||
b.Navigation("Motions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
|
||||
{
|
||||
b.Navigation("Rates");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
|
||||
b.Navigation("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
|
||||
{
|
||||
b.Navigation("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
|
||||
{
|
||||
b.Navigation("Motions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
|
||||
{
|
||||
b.Navigation("AccountAccess");
|
||||
|
||||
b.Navigation("AccountAccessInvites");
|
||||
|
||||
b.Navigation("AccountAccessOwners");
|
||||
|
||||
b.Navigation("AccountCategories");
|
||||
|
||||
b.Navigation("AccountMotions");
|
||||
|
||||
b.Navigation("Accounts");
|
||||
|
||||
b.Navigation("Currencies");
|
||||
|
||||
b.Navigation("ItemCategories");
|
||||
|
||||
b.Navigation("UserClaims");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace MyOffice.Migrations.Postgres.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AccountAccesUnique : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_AccountAccesses_AccountId",
|
||||
table: "AccountAccesses");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AccountAccesses_AccountId_UserId",
|
||||
table: "AccountAccesses",
|
||||
columns: new[] { "AccountId", "UserId" },
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_AccountAccesses_AccountId_UserId",
|
||||
table: "AccountAccesses");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AccountAccesses_AccountId",
|
||||
table: "AccountAccesses",
|
||||
column: "AccountId");
|
||||
}
|
||||
}
|
||||
}
|
||||
+730
@@ -0,0 +1,730 @@
|
||||
// <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("20231217163807_acc_cat_unique")]
|
||||
partial class acccatunique
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
|
||||
.HasAnnotation("ProductVersion", "7.0.0")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("CurrencyGlobalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid?>("OwnerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyGlobalId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsAllowManage")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAllowRead")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAllowWrite")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("OwnerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.HasIndex("AccountId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AccountAccesses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime?>("AcceptedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsAllowWrite")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTime?>("RejectedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AccountAccessInvites");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("CategoryId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.HasIndex("AccountId", "CategoryId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AccountAccountCategories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AccountCategories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<decimal>("AmountMinus")
|
||||
.HasPrecision(18, 6)
|
||||
.HasColumnType("numeric(18,6)");
|
||||
|
||||
b.Property<decimal>("AmountPlus")
|
||||
.HasPrecision(18, 6)
|
||||
.HasColumnType("numeric(18,6)");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<DateTime>("DateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<DateTime?>("DeletedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid?>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.HasIndex("ItemId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Motions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("CurrencyGlobalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int?>("CurrentRateId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("IsPrimary")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ShortName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyGlobalId");
|
||||
|
||||
b.HasIndex("CurrentRateId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("DefaultQuantity")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Symbol")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CurrencyGlobals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("CurrencyId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("DateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("Quantity")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("Rate")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyId");
|
||||
|
||||
b.ToTable("CurrencyRates");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("CategoryId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("ItemGlobalId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.HasIndex("ItemGlobalId");
|
||||
|
||||
b.ToTable("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsInternal")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("ItemCategories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ItemGlobals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("CurrencyId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.UseCollation("my_ci_collation");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("FullName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsEmailConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Phone")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.UseCollation("my_ci_collation");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyId");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.UseCollation("my_ci_collation");
|
||||
|
||||
b.Property<string>("ExternalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Provider")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.UseCollation("my_ci_collation");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("CurrencyGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "Owner")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("OwnerId");
|
||||
|
||||
b.Navigation("CurrencyGlobal");
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("AccessRights")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "Owner")
|
||||
.WithMany("AccountAccessOwners")
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountAccess")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Owner");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Invites")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountAccessInvites")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Categories")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("CategoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Category");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountCategories")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Motions")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
|
||||
.WithMany("Motions")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", null)
|
||||
.WithMany("AccountMotions")
|
||||
.HasForeignKey("UserId");
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("CurrencyGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("CurrentRateId");
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CurrencyGlobal");
|
||||
|
||||
b.Navigation("CurrentRate");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
|
||||
.WithMany("Rates")
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("CategoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("ItemGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Category");
|
||||
|
||||
b.Navigation("ItemGlobal");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("ItemCategories")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("UserClaims")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.Navigation("AccessRights");
|
||||
|
||||
b.Navigation("Categories");
|
||||
|
||||
b.Navigation("Invites");
|
||||
|
||||
b.Navigation("Motions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
|
||||
{
|
||||
b.Navigation("Rates");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
|
||||
b.Navigation("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
|
||||
{
|
||||
b.Navigation("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
|
||||
{
|
||||
b.Navigation("Motions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
|
||||
{
|
||||
b.Navigation("AccountAccess");
|
||||
|
||||
b.Navigation("AccountAccessInvites");
|
||||
|
||||
b.Navigation("AccountAccessOwners");
|
||||
|
||||
b.Navigation("AccountCategories");
|
||||
|
||||
b.Navigation("AccountMotions");
|
||||
|
||||
b.Navigation("Accounts");
|
||||
|
||||
b.Navigation("Currencies");
|
||||
|
||||
b.Navigation("ItemCategories");
|
||||
|
||||
b.Navigation("UserClaims");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace MyOffice.Migrations.Postgres.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class acccatunique : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_AccountAccountCategories_AccountId",
|
||||
table: "AccountAccountCategories");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AccountAccountCategories_AccountId_CategoryId",
|
||||
table: "AccountAccountCategories",
|
||||
columns: new[] { "AccountId", "CategoryId" },
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_AccountAccountCategories_AccountId_CategoryId",
|
||||
table: "AccountAccountCategories");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AccountAccountCategories_AccountId",
|
||||
table: "AccountAccountCategories",
|
||||
column: "AccountId");
|
||||
}
|
||||
}
|
||||
}
|
||||
+733
@@ -0,0 +1,733 @@
|
||||
// <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("20231217185452_acc_access_unique")]
|
||||
partial class accaccessunique
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
|
||||
.HasAnnotation("ProductVersion", "7.0.0")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("CurrencyGlobalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid?>("OwnerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyGlobalId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsAllowManage")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAllowRead")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAllowWrite")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("OwnerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.HasIndex("AccountId", "OwnerId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("AccountId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AccountAccesses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime?>("AcceptedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsAllowWrite")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTime?>("RejectedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AccountAccessInvites");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("CategoryId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.HasIndex("AccountId", "CategoryId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AccountAccountCategories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AccountCategories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<decimal>("AmountMinus")
|
||||
.HasPrecision(18, 6)
|
||||
.HasColumnType("numeric(18,6)");
|
||||
|
||||
b.Property<decimal>("AmountPlus")
|
||||
.HasPrecision(18, 6)
|
||||
.HasColumnType("numeric(18,6)");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<DateTime>("DateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<DateTime?>("DeletedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("ItemId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<Guid?>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.HasIndex("ItemId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Motions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("CurrencyGlobalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int?>("CurrentRateId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<bool>("IsPrimary")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ShortName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyGlobalId");
|
||||
|
||||
b.HasIndex("CurrentRateId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("DefaultQuantity")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Symbol")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CurrencyGlobals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("CurrencyId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("DateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<int>("Quantity")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<decimal>("Rate")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyId");
|
||||
|
||||
b.ToTable("CurrencyRates");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("CategoryId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("ItemGlobalId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.HasIndex("ItemGlobalId");
|
||||
|
||||
b.ToTable("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsInternal")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("ItemCategories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ItemGlobals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("CurrencyId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.UseCollation("my_ci_collation");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("FullName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsEmailConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Phone")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.UseCollation("my_ci_collation");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyId");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.UseCollation("my_ci_collation");
|
||||
|
||||
b.Property<string>("ExternalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Provider")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.UseCollation("my_ci_collation");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("CurrencyGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "Owner")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("OwnerId");
|
||||
|
||||
b.Navigation("CurrencyGlobal");
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("AccessRights")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "Owner")
|
||||
.WithMany("AccountAccessOwners")
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountAccess")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Owner");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Invites")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountAccessInvites")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Categories")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("CategoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Category");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountCategories")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Motions")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
|
||||
.WithMany("Motions")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", null)
|
||||
.WithMany("AccountMotions")
|
||||
.HasForeignKey("UserId");
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("CurrencyGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("CurrentRateId");
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CurrencyGlobal");
|
||||
|
||||
b.Navigation("CurrentRate");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
|
||||
.WithMany("Rates")
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("CategoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("ItemGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Category");
|
||||
|
||||
b.Navigation("ItemGlobal");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("ItemCategories")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("UserClaims")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.Navigation("AccessRights");
|
||||
|
||||
b.Navigation("Categories");
|
||||
|
||||
b.Navigation("Invites");
|
||||
|
||||
b.Navigation("Motions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
|
||||
{
|
||||
b.Navigation("Rates");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
|
||||
b.Navigation("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
|
||||
{
|
||||
b.Navigation("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
|
||||
{
|
||||
b.Navigation("Motions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
|
||||
{
|
||||
b.Navigation("AccountAccess");
|
||||
|
||||
b.Navigation("AccountAccessInvites");
|
||||
|
||||
b.Navigation("AccountAccessOwners");
|
||||
|
||||
b.Navigation("AccountCategories");
|
||||
|
||||
b.Navigation("AccountMotions");
|
||||
|
||||
b.Navigation("Accounts");
|
||||
|
||||
b.Navigation("Currencies");
|
||||
|
||||
b.Navigation("ItemCategories");
|
||||
|
||||
b.Navigation("UserClaims");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace MyOffice.Migrations.Postgres.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class accaccessunique : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AccountAccesses_AccountId_OwnerId",
|
||||
table: "AccountAccesses",
|
||||
columns: new[] { "AccountId", "OwnerId" },
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_AccountAccesses_AccountId_OwnerId",
|
||||
table: "AccountAccesses");
|
||||
}
|
||||
}
|
||||
}
|
||||
+790
@@ -0,0 +1,790 @@
|
||||
// <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("20240107073407_VerificationCode")]
|
||||
partial class VerificationCode
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
|
||||
.HasAnnotation("ProductVersion", "7.0.0")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("CurrencyGlobalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid?>("OwnerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyGlobalId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsAllowManage")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAllowRead")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAllowWrite")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("OwnerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.HasIndex("AccountId", "OwnerId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("AccountId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AccountAccesses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime?>("AcceptedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsAllowWrite")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTime?>("RejectedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AccountAccessInvites");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("CategoryId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.HasIndex("AccountId", "CategoryId")
|
||||
.IsUnique();
|
||||
|
||||
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.Verifications.VerificationCode", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Destination")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("DestinationType")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("ExpiresOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Metadata")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Template")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime?>("VerifiedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Verifications");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("CurrencyGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "Owner")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("OwnerId");
|
||||
|
||||
b.Navigation("CurrencyGlobal");
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("AccessRights")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "Owner")
|
||||
.WithMany("AccountAccessOwners")
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountAccess")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Owner");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Invites")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountAccessInvites")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Categories")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("CategoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Category");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountCategories")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Motions")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
|
||||
.WithMany("Motions")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", null)
|
||||
.WithMany("AccountMotions")
|
||||
.HasForeignKey("UserId");
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("CurrencyGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("CurrentRateId");
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CurrencyGlobal");
|
||||
|
||||
b.Navigation("CurrentRate");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
|
||||
.WithMany("Rates")
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("CategoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("ItemGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Category");
|
||||
|
||||
b.Navigation("ItemGlobal");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("ItemCategories")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("UserClaims")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.Navigation("AccessRights");
|
||||
|
||||
b.Navigation("Categories");
|
||||
|
||||
b.Navigation("Invites");
|
||||
|
||||
b.Navigation("Motions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
|
||||
{
|
||||
b.Navigation("Rates");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
|
||||
b.Navigation("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
|
||||
{
|
||||
b.Navigation("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
|
||||
{
|
||||
b.Navigation("Motions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
|
||||
{
|
||||
b.Navigation("AccountAccess");
|
||||
|
||||
b.Navigation("AccountAccessInvites");
|
||||
|
||||
b.Navigation("AccountAccessOwners");
|
||||
|
||||
b.Navigation("AccountCategories");
|
||||
|
||||
b.Navigation("AccountMotions");
|
||||
|
||||
b.Navigation("Accounts");
|
||||
|
||||
b.Navigation("Currencies");
|
||||
|
||||
b.Navigation("ItemCategories");
|
||||
|
||||
b.Navigation("UserClaims");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace MyOffice.Migrations.Postgres.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class VerificationCode : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Verifications",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
Code = table.Column<string>(type: "text", nullable: false),
|
||||
DestinationType = table.Column<string>(type: "text", nullable: false),
|
||||
Destination = table.Column<string>(type: "text", nullable: false),
|
||||
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
ExpiresOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
VerifiedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
Template = table.Column<string>(type: "text", nullable: false),
|
||||
Metadata = table.Column<string>(type: "text", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Verifications", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Verifications_Users_UserId",
|
||||
column: x => x.UserId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Verifications_UserId",
|
||||
table: "Verifications",
|
||||
column: "UserId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Verifications");
|
||||
}
|
||||
}
|
||||
}
|
||||
+790
@@ -0,0 +1,790 @@
|
||||
// <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("20240107075033_VerificationCode2")]
|
||||
partial class VerificationCode2
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Npgsql:CollationDefinition:my_ci_collation", "en-u-ks-primary,en-u-ks-primary,icu,False")
|
||||
.HasAnnotation("ProductVersion", "7.0.0")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("CurrencyGlobalId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid?>("OwnerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CurrencyGlobalId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<bool>("IsAllowManage")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAllowRead")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsAllowWrite")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("OwnerId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.HasIndex("AccountId", "OwnerId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("AccountId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AccountAccesses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime?>("AcceptedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("IsAllowWrite")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTime?>("RejectedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AccountAccessInvites");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<Guid>("CategoryId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.HasIndex("AccountId", "CategoryId")
|
||||
.IsUnique();
|
||||
|
||||
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.Verifications.VerificationCode", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Destination")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("DestinationType")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("ExpiresOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Metadata")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Template")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime?>("VerifiedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Verifications");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("CurrencyGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "Owner")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("OwnerId");
|
||||
|
||||
b.Navigation("CurrencyGlobal");
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccess", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("AccessRights")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "Owner")
|
||||
.WithMany("AccountAccessOwners")
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountAccess")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Owner");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccessInvite", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Invites")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountAccessInvites")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountAccountCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Categories")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.AccountCategory", "Category")
|
||||
.WithMany("Accounts")
|
||||
.HasForeignKey("CategoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Category");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("AccountCategories")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Motion", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Accounts.Account", "Account")
|
||||
.WithMany("Motions")
|
||||
.HasForeignKey("AccountId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Items.Item", "Item")
|
||||
.WithMany("Motions")
|
||||
.HasForeignKey("ItemId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", null)
|
||||
.WithMany("AccountMotions")
|
||||
.HasForeignKey("UserId");
|
||||
|
||||
b.Navigation("Account");
|
||||
|
||||
b.Navigation("Item");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("CurrencyGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyRate", "CurrentRate")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("CurrentRateId");
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("Currencies")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("CurrencyGlobal");
|
||||
|
||||
b.Navigation("CurrentRate");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.Currency", "Currency")
|
||||
.WithMany("Rates")
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Items.ItemCategory", "Category")
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("CategoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("MyOffice.Data.Models.Items.ItemGlobal", "ItemGlobal")
|
||||
.WithMany("Items")
|
||||
.HasForeignKey("ItemGlobalId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Category");
|
||||
|
||||
b.Navigation("ItemGlobal");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("ItemCategories")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "Currency")
|
||||
.WithMany()
|
||||
.HasForeignKey("CurrencyId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.UserExternal", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany("UserClaims")
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.Navigation("AccessRights");
|
||||
|
||||
b.Navigation("Categories");
|
||||
|
||||
b.Navigation("Invites");
|
||||
|
||||
b.Navigation("Motions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.AccountCategory", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.Currency", b =>
|
||||
{
|
||||
b.Navigation("Rates");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyGlobal", b =>
|
||||
{
|
||||
b.Navigation("Accounts");
|
||||
|
||||
b.Navigation("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Currencies.CurrencyRate", b =>
|
||||
{
|
||||
b.Navigation("Currencies");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.Item", b =>
|
||||
{
|
||||
b.Navigation("Motions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemCategory", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Items.ItemGlobal", b =>
|
||||
{
|
||||
b.Navigation("Items");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Users.User", b =>
|
||||
{
|
||||
b.Navigation("AccountAccess");
|
||||
|
||||
b.Navigation("AccountAccessInvites");
|
||||
|
||||
b.Navigation("AccountAccessOwners");
|
||||
|
||||
b.Navigation("AccountCategories");
|
||||
|
||||
b.Navigation("AccountMotions");
|
||||
|
||||
b.Navigation("Accounts");
|
||||
|
||||
b.Navigation("Currencies");
|
||||
|
||||
b.Navigation("ItemCategories");
|
||||
|
||||
b.Navigation("UserClaims");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace MyOffice.Migrations.Postgres.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class VerificationCode2 : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,12 +84,16 @@ namespace MyOffice.Migrations.Postgres.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.HasIndex("AccountId", "OwnerId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("AccountId", "UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AccountAccesses");
|
||||
});
|
||||
|
||||
@@ -146,10 +150,11 @@ namespace MyOffice.Migrations.Postgres.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AccountId");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.HasIndex("AccountId", "CategoryId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AccountAccountCategories");
|
||||
});
|
||||
|
||||
@@ -447,6 +452,52 @@ namespace MyOffice.Migrations.Postgres.Migrations
|
||||
b.ToTable("UserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Destination")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("DestinationType")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("ExpiresOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Metadata")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Template")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid");
|
||||
|
||||
b.Property<DateTime?>("VerifiedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Verifications");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Currencies.CurrencyGlobal", "CurrencyGlobal")
|
||||
@@ -651,6 +702,17 @@ namespace MyOffice.Migrations.Postgres.Migrations
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Verifications.VerificationCode", b =>
|
||||
{
|
||||
b.HasOne("MyOffice.Data.Models.Users.User", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MyOffice.Data.Models.Accounts.Account", b =>
|
||||
{
|
||||
b.Navigation("AccessRights");
|
||||
|
||||
@@ -45,7 +45,7 @@ export class LockedComponent implements OnInit {
|
||||
if (this.authForm.invalid) {
|
||||
return;
|
||||
} else {
|
||||
this.router.navigate(['/dashboard/dashboard']);
|
||||
this.router.navigate(['/dashboard/rests']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,14 +24,13 @@ export class ErrorInterceptor implements HttpInterceptor {
|
||||
this.authenticationService.logout();
|
||||
location.reload();
|
||||
}
|
||||
let error = err.message || err.statusText;
|
||||
error = !err.error ? error : err.error.message || err.error.title;
|
||||
|
||||
let error = err.error || err.message || err.statusText;
|
||||
|
||||
if (!error) {
|
||||
console.log('not parsed error', err);
|
||||
}
|
||||
return throwError(error);
|
||||
//return throwError(err.error || err);
|
||||
return throwError(() => error);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { SelectableModel } from './selectable.model';
|
||||
|
||||
describe('SelectableModel', () => {
|
||||
it('should create an instance', () => {
|
||||
expect(new SelectableModel()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface ISelectableModel<T> {
|
||||
model: T;
|
||||
selected: boolean;
|
||||
}
|
||||
@@ -5,50 +5,20 @@
|
||||
<app-breadcrumb [title]="'MENUITEMS.DASHBOARD.LIST.INCOME'" [items]="['HOME']" [active_item]="'MENUITEMS.DASHBOARD.LIST.INCOME'"></app-breadcrumb>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="row">
|
||||
|
||||
<div class="col-4 col-sm-4 col-md-4">
|
||||
<div class="col-xl-12 col-lg-12 col-md-12 col-sm-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<h5>{{'BALANCE' | translate}}</h5>
|
||||
</div>
|
||||
<h3 class="text-danger">{{dashboardModel?.balance | number: '0.2-2'}}</h3>
|
||||
</div>
|
||||
<div class="header">
|
||||
<h2>{{'PERIOD' | translate}}</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-4 col-sm-4 col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<h5>{{'DEBIT.BALANCE' | translate}}</h5>
|
||||
<p class="text-muted"></p>
|
||||
</div>
|
||||
<h3 class="text-success">{{dashboardModel?.balanceDebit | number: '0.2-2'}}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-4 col-sm-4 col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<h5>{{'CREDIT.BALANCE' | translate}}</h5>
|
||||
</div>
|
||||
<h3 class="text-danger">{{dashboardModel?.balanceCredit | number: '0.2-2'}}</h3>
|
||||
<div class="body">
|
||||
<div class="example-container">
|
||||
<app-date-period [from]="dateFrom" [to]="dateTo" (onChange)="onChangePeriod($event)"></app-date-period>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="row clearfix">
|
||||
<!-- Bar chart with line -->
|
||||
@@ -67,16 +37,31 @@
|
||||
</div>
|
||||
<div class="body">
|
||||
<div id="chart">
|
||||
<apx-chart #chart *ngIf="chartOptions" class="apex-pie-center"
|
||||
<apx-chart #chart *ngIf="chartOptions" class="apex-pie-center" (contextmenu)="onRightClick($event)"
|
||||
[series]="chartOptions.series!"
|
||||
[chart]="chartOptions.chart!"
|
||||
[dataLabels]="chartOptions.dataLabels!"
|
||||
[plotOptions]="chartOptions.plotOptions!"
|
||||
[title]="chartOptions.title!"
|
||||
[legend]="chartOptions.legend!"
|
||||
>
|
||||
[legend]="chartOptions.legend!">
|
||||
</apx-chart>
|
||||
</div>
|
||||
<div class="table-responsive m-t-15" *ngIf="dashboardModel">
|
||||
<table class="table align-items-center">
|
||||
<tbody>
|
||||
<tr *ngFor="let item of dashboardModel!.details">
|
||||
<td><i class="fa fa-circle col-cyan msr-2"></i> {{item.name}}</td>
|
||||
<td [ngClass]="{ 'col-green': item.value != 0, 'col-red': item.value == 0}" style="text-align: right;">{{item.valueRaw | number: '1.2'}}</td>
|
||||
<td [ngClass]="{ 'col-green': item.value != 0, 'col-red': item.value == 0}" style="text-align: right;">{{item.value | number: '1.2'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-cyan">{{'TOTAL' | translate}}</td>
|
||||
<td class="col-cyan" style="text-align: right;"></td>
|
||||
<td class="col-cyan" style="text-align: right;">{{total | number: '1.2'}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
ApexPlotOptions,
|
||||
ApexLegend
|
||||
} from "ng-apexcharts";
|
||||
import * as moment from 'moment'
|
||||
|
||||
// app
|
||||
import { ApiRoutes } from '../../api-routes';
|
||||
@@ -40,6 +41,9 @@ export class DashboardIncomeComponent implements OnInit {
|
||||
@ViewChild("chart") chart!: ChartComponent;
|
||||
public chartOptions!: Partial<ChartOptions>;
|
||||
dashboardModel?: DashboardInOutModel;
|
||||
total?: number;
|
||||
public dateFrom: Date = moment(new Date).add(-30, 'days').toDate();
|
||||
public dateTo: Date = moment(new Date).add(0, 'days').toDate();
|
||||
|
||||
colors: string[] = ["#fd7f6f", "#7eb0d5", "#b2e061", "#bd7ebe", "#ffb55a", "#ffee65", "#beb9db", "#fdcce5", "#8bd3c7"];
|
||||
|
||||
@@ -51,15 +55,29 @@ export class DashboardIncomeComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
onChangePeriod(dates: Date[]) {
|
||||
this.dateFrom = dates[0];
|
||||
this.dateTo = dates[1];
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
loadData(update?: boolean, category?: string) {
|
||||
let params = new HttpParams()
|
||||
.set('from', '2023-07-01')
|
||||
.set('to', '2023-08-01');
|
||||
.set('from', moment(this.dateFrom).format('YYYY-MM-DD'))
|
||||
.set('to', moment(this.dateTo).format('YYYY-MM-DD'))
|
||||
.set('category', category || '')
|
||||
;
|
||||
|
||||
this.httpClient
|
||||
.get<DashboardInOutModel>(ApiRoutes.DashboardIncome, { params: params })
|
||||
.subscribe(response => {
|
||||
this.dashboardModel = response;
|
||||
|
||||
var series = response.data.map(x => ({
|
||||
x: x.name + '(' + this._decimalPipe.transform(x.value, '1.2-2') || "" + ')',
|
||||
x: x.name + '(' + (this._decimalPipe.transform(x.value, '1.2-2') || "") + ')',
|
||||
y: x.value
|
||||
}));
|
||||
var min = Math.min(...response.data.map(x => x.value));
|
||||
@@ -73,10 +91,24 @@ export class DashboardIncomeComponent implements OnInit {
|
||||
color: this.colors[this.colors.length - i - 1],
|
||||
});
|
||||
}
|
||||
this.setChartOptions(series, ranges);
|
||||
|
||||
this.total = response.data.reduce((sum, current) => sum + current.value, 0);
|
||||
|
||||
if (update) {
|
||||
this.chart.updateSeries([{
|
||||
data: series
|
||||
}]);
|
||||
} else {
|
||||
this.setChartOptions(series, ranges);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onRightClick(event?: Event) {
|
||||
event?.preventDefault();
|
||||
this.loadData(true);
|
||||
}
|
||||
|
||||
private setChartOptions(data: any[], ranges: any[]) {
|
||||
var self = this;
|
||||
|
||||
@@ -88,6 +120,12 @@ export class DashboardIncomeComponent implements OnInit {
|
||||
type: 'treemap',
|
||||
width: 600,
|
||||
height: 600,
|
||||
events: {
|
||||
click: function (event, chartContext, config) {
|
||||
var data = self.dashboardModel!.data[config.dataPointIndex];
|
||||
self.loadData(true, data.id);
|
||||
}
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
treemap: {
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row clearfix">
|
||||
<!-- Bar chart with line -->
|
||||
<div class="col-xl-12 col-lg-12 col-md-12 col-sm-12">
|
||||
@@ -37,7 +38,7 @@
|
||||
-->
|
||||
</div>
|
||||
<div class="body">
|
||||
<apx-chart #chart *ngIf="chartOptions" class="apex-pie-center"
|
||||
<apx-chart #chart *ngIf="chartOptions" class="apex-pie-center" (contextmenu)="onRightClick($event)"
|
||||
[series]="chartOptions.series!"
|
||||
[chart]="chartOptions.chart!"
|
||||
[dataLabels]="chartOptions.dataLabels!"
|
||||
@@ -45,9 +46,27 @@
|
||||
[title]="chartOptions.title!"
|
||||
[legend]="chartOptions.legend!">
|
||||
</apx-chart>
|
||||
<div class="table-responsive m-t-15" *ngIf="dashboardModel">
|
||||
<table class="table align-items-center">
|
||||
<tbody>
|
||||
<tr *ngFor="let item of dashboardModel!.details">
|
||||
<td><i class="fa fa-circle col-cyan msr-2"></i> {{item.name}}</td>
|
||||
<td [ngClass]="{ 'col-green': item.value != 0, 'col-red': item.value == 0}" style="text-align: right;">{{item.valueRaw | number: '1.2'}}</td>
|
||||
<td [ngClass]="{ 'col-green': item.value != 0, 'col-red': item.value == 0}" style="text-align: right;">{{item.value | number: '1.2'}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-cyan">{{'TOTAL' | translate}}</td>
|
||||
<td class="col-cyan" style="text-align: right;"></td>
|
||||
<td class="col-cyan" style="text-align: right;">{{total | number: '1.2'}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -6,8 +6,6 @@ import { HttpClient } from '@angular/common/http';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { DecimalPipe } from '@angular/common';
|
||||
import { UntypedFormBuilder } from '@angular/forms';
|
||||
import { UntypedFormGroup } from '@angular/forms';
|
||||
import { Validators } from '@angular/forms';
|
||||
|
||||
// libs
|
||||
import {
|
||||
@@ -44,7 +42,7 @@ export class DashboardOutcomeComponent implements OnInit {
|
||||
@ViewChild("chart") chart!: ChartComponent;
|
||||
public chartOptions!: Partial<ChartOptions>;
|
||||
dashboardModel?: DashboardInOutModel;
|
||||
public form!: UntypedFormGroup;
|
||||
total?: number;
|
||||
public dateFrom: Date = moment(new Date).add(-30, 'days').toDate();
|
||||
public dateTo: Date = moment(new Date).add(0, 'days').toDate();
|
||||
|
||||
@@ -58,8 +56,6 @@ export class DashboardOutcomeComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.form = this.fb.group({
|
||||
});
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
@@ -69,6 +65,11 @@ export class DashboardOutcomeComponent implements OnInit {
|
||||
this.loadData();
|
||||
}
|
||||
|
||||
onRightClick(event?: Event) {
|
||||
event?.preventDefault();
|
||||
this.loadData(true);
|
||||
}
|
||||
|
||||
private loadData(update?: boolean, category?: string) {
|
||||
let params = new HttpParams()
|
||||
.set('from', moment(this.dateFrom).format('YYYY-MM-DD'))
|
||||
@@ -96,6 +97,9 @@ export class DashboardOutcomeComponent implements OnInit {
|
||||
color: this.colors[this.colors.length - i - 1],
|
||||
});
|
||||
}
|
||||
|
||||
this.total = response.data.reduce((sum, current) => sum + current.value, 0);
|
||||
|
||||
if (update) {
|
||||
this.chart.updateSeries([{
|
||||
data: series
|
||||
|
||||
@@ -126,7 +126,7 @@ export class HeaderComponent extends UnsubscribeOnDestroyAdapter implements OnIn
|
||||
|
||||
this.setUser();
|
||||
|
||||
this.homePage = 'dashboard/dashboard';
|
||||
this.homePage = 'dashboard/rests';
|
||||
|
||||
this.langStoreValue = localStorage.getItem('lang') as string;
|
||||
const val = this.listLang.filter((x) => x.lang === this.langStoreValue);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="navbar-header">
|
||||
<ul class="nav navbar-nav flex-row">
|
||||
<li class="nav-item logo">
|
||||
<a class="navbar-brand" routerLink="dashboard/dashboard">
|
||||
<a class="navbar-brand" routerLink="dashboard/rests">
|
||||
<img src="assets/images/logo.png" alt=""/>
|
||||
<span class="logo-name">ase.com.ua</span>
|
||||
</a>
|
||||
|
||||
@@ -7,6 +7,7 @@ export interface AccountModel {
|
||||
currencyId?: string,
|
||||
currencyName?: string,
|
||||
type?: string,
|
||||
allowWrite: boolean,
|
||||
allowDelete: boolean,
|
||||
allowManage: boolean,
|
||||
categories?: AccountCategoryModel[],
|
||||
|
||||
@@ -26,10 +26,13 @@ export interface DashboardRestModel {
|
||||
|
||||
export interface DashboardInOutModel {
|
||||
data: DashboardInOutItemModel[];
|
||||
details: DashboardInOutItemModel[];
|
||||
}
|
||||
|
||||
export interface DashboardInOutItemModel {
|
||||
id: string;
|
||||
currency: string;
|
||||
name: string;
|
||||
value: number;
|
||||
valueRaw: number;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
account-motion:nth-child(even) {
|
||||
filter: brightness(1)
|
||||
:host-context(body.dark)account-motion:nth-child(even) {
|
||||
filter: brightness(1);
|
||||
}
|
||||
|
||||
account-motion:nth-child(odd) {
|
||||
filter: brightness(1.75)
|
||||
:host-context(body.dark)account-motion:nth-child(odd) {
|
||||
filter: brightness(1.75);
|
||||
}
|
||||
|
||||
:host-context(body.light)account-motion:nth-child(even) {
|
||||
filter: brightness(0.75);
|
||||
}
|
||||
|
||||
:host-context(body.light)account-motion:nth-child(odd) {
|
||||
filter: brightness(1);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,10 @@ export class AccountComponent {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
/*this.activatedRoute.params.subscribe(params => {
|
||||
console.log(params);
|
||||
this.loadMotions();
|
||||
});*/
|
||||
this.loadMotions();
|
||||
|
||||
this.reloadEvent.subscribe(x => {
|
||||
@@ -86,13 +90,11 @@ export class AccountComponent {
|
||||
url += '?from=' + moment(this.dateFrom).format('yyyy-MM-DD');
|
||||
url += '&to=' + moment(this.dateTo).format('yyyy-MM-DD');
|
||||
|
||||
this.activatedRoute.params.subscribe(params => {
|
||||
this.httpClient
|
||||
.get<MotionModel[]>(url)
|
||||
.subscribe(data => {
|
||||
this.motions = data;
|
||||
});
|
||||
});
|
||||
this.httpClient
|
||||
.get<MotionModel[]>(url)
|
||||
.subscribe(data => {
|
||||
this.motions = data;
|
||||
});
|
||||
}
|
||||
|
||||
afterExpand() {
|
||||
|
||||
@@ -129,6 +129,7 @@ export class MotionComponent {
|
||||
this.setInProgress();
|
||||
|
||||
var data: MotionModel = {
|
||||
date: this.form.value.date,
|
||||
description: this.form.value.description,
|
||||
plus: this.form.value.plus || 0,
|
||||
minus: this.form.value.minus || 0,
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
<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" *ngIf="account.allowWrite" (click)="edit(account)" mat-raised-button color="primary">
|
||||
Edit
|
||||
</button>
|
||||
<button class="btn-space" *ngIf="account.allowManage" (click)="access(account)" mat-raised-button color="primary">
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
<button class="btn-space" (click)="setRate(item)" mat-raised-button color="primary">
|
||||
Edit
|
||||
</button>
|
||||
<button class="btn-space" (click)="delete(item)" mat-raised-button color="warn">
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { HttpClient } from '@angular/common/http';
|
||||
|
||||
// libs
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import Swal from 'sweetalert2';
|
||||
|
||||
// app
|
||||
import { ApiRoutes } from '../../../api-routes';
|
||||
@@ -60,6 +61,33 @@ export class SettingsCurrencyComponent {
|
||||
});
|
||||
}
|
||||
|
||||
delete(currency: CurrencyModel) {
|
||||
Swal.fire({
|
||||
title: 'Delete currency ' + currency.name,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Delete',
|
||||
showLoaderOnConfirm: true,
|
||||
preConfirm: (name) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.httpClient.delete(ApiRoutes.SettingsCurrency.replace(':id', currency.id!))
|
||||
.subscribe(data => {
|
||||
resolve(data);
|
||||
}, error => {
|
||||
Swal.showValidationMessage(error.detail);
|
||||
reject();
|
||||
});
|
||||
|
||||
}).catch(x => {
|
||||
return false;
|
||||
});
|
||||
},
|
||||
allowOutsideClick: () => !Swal.isLoading(),
|
||||
}).then((result) => {
|
||||
this.load();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private load() {
|
||||
this.httpClient
|
||||
.get<CurrencyModel[]>(ApiRoutes.GeneralCurrencies)
|
||||
@@ -73,21 +101,23 @@ export class SettingsCurrencyComponent {
|
||||
this.httpClient
|
||||
.get<CurrencyModel[]>(ApiRoutes.SettingsCurrencies)
|
||||
.subscribe(data => {
|
||||
this.myCurrencies = data.map(myCurrency => {
|
||||
var globalCurrency = this.currencies?.find(x => x.id === myCurrency.code);
|
||||
this.myCurrencies = data
|
||||
.sort((a, b) => a.code!.localeCompare(b.code!))
|
||||
.map(myCurrency => {
|
||||
var globalCurrency = this.currencies?.find(x => x.id === myCurrency.code);
|
||||
|
||||
return {
|
||||
id: myCurrency.id,
|
||||
code: myCurrency.code,
|
||||
name: myCurrency.name,
|
||||
quantity: myCurrency.quantity,
|
||||
rate: myCurrency.rate,
|
||||
rateDate: myCurrency.rateDate,
|
||||
shortName: myCurrency.shortName,
|
||||
symbol: globalCurrency?.symbol,
|
||||
isPrimary: myCurrency.isPrimary,
|
||||
};
|
||||
});
|
||||
return {
|
||||
id: myCurrency.id,
|
||||
code: myCurrency.code,
|
||||
name: myCurrency.name,
|
||||
quantity: myCurrency.quantity,
|
||||
rate: myCurrency.rate,
|
||||
rateDate: myCurrency.rateDate,
|
||||
shortName: myCurrency.shortName,
|
||||
symbol: globalCurrency?.symbol,
|
||||
isPrimary: myCurrency.isPrimary,
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
<div class="text-inside">
|
||||
<mat-form-field class="example-full-width" appearance="fill">
|
||||
<mat-label>Rate</mat-label>
|
||||
<input matInput [value]="currency.rate | number:'0.2-2'" formControlName="rate" currencyMask [options]="{ prefix: '', precision: 4, inputMode: 1 }" required>
|
||||
<input matInput [value]="currency.rate | number:'0.2-2'" formControlName="rate" currencyMask
|
||||
[options]="{ prefix: '', precision: 4, inputMode: 1 }" required>
|
||||
<mat-error *ngIf="addForm.controls?.['rate']?.hasError('required')">
|
||||
Please enter rate
|
||||
</mat-error>
|
||||
@@ -52,7 +53,8 @@
|
||||
<div class="text-inside">
|
||||
<mat-form-field class="example-full-width" appearance="fill">
|
||||
<mat-label>Quantity</mat-label>
|
||||
<input matInput [value]="currency.rate | number:'0.0-0'" formControlName="quantity" currencyMask [options]="{ prefix: '', precision: 0 }" required>
|
||||
<input matInput [value]="currency.rate | number:'0.0-0'" formControlName="quantity"
|
||||
currencyMask [options]="{ prefix: '', precision: 0 }" required>
|
||||
<mat-error *ngIf="addForm.controls?.['rate']?.hasError('required')">
|
||||
Please enter rate
|
||||
</mat-error>
|
||||
@@ -63,7 +65,8 @@
|
||||
<div class="text-inside">
|
||||
<mat-form-field class="example-full-width">
|
||||
<mat-label>Rate Date</mat-label>
|
||||
<input matInput [matDatepicker]="picker3" (focus)="picker3.open()" value={{currency.rateDate}} formControlName="rateDate" required>
|
||||
<input matInput [matDatepicker]="picker3" (focus)="picker3.open()"
|
||||
value={{currency.rateDate}} formControlName="rateDate" required>
|
||||
<mat-hint>DD/MM/YYYY</mat-hint>
|
||||
<mat-datepicker-toggle matSuffix [for]="picker3"></mat-datepicker-toggle>
|
||||
<mat-datepicker #picker3></mat-datepicker>
|
||||
@@ -85,8 +88,11 @@
|
||||
</div>
|
||||
<mat-dialog-actions class="mat-dialog-actions">
|
||||
<div class="mat-dialog-left">
|
||||
<div class="alert alert-danger mat-dialog-error" *ngIf="errorMessage">
|
||||
{{errorMessage}}
|
||||
<div class="alert alert-danger mat-dialog-error" *ngIf="error">
|
||||
<p *ngIf="error.title">{{error.title}}</p>
|
||||
<ul *ngIf="error.errors">
|
||||
<li *ngFor="let error of error.errors | keyvalue">{{error.value}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mat-dialog-right">
|
||||
@@ -98,4 +104,4 @@
|
||||
</mat-dialog-actions>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -21,7 +21,7 @@ import { CurrencyModel } from '../../../model/currency.model';
|
||||
})
|
||||
export class SettingsRateCurrencyComponent {
|
||||
public addForm!: UntypedFormGroup;
|
||||
public errorMessage?: string;
|
||||
public error?: any;
|
||||
|
||||
constructor(
|
||||
private fb: UntypedFormBuilder,
|
||||
@@ -71,20 +71,26 @@ export class SettingsRateCurrencyComponent {
|
||||
}
|
||||
|
||||
onSubmitClick() {
|
||||
this.error = undefined;
|
||||
if (this.addForm.valid) {
|
||||
this.errorMessage = undefined;
|
||||
this.httpClient
|
||||
.put<CurrencyModel>(ApiRoutes.SettingsCurrency.replace(':id', this.addForm.value.id), this.addForm.value)
|
||||
.subscribe(response => {
|
||||
this.httpClient
|
||||
.post<CurrencyModel[]>(ApiRoutes.SettingsCurrenciesRate.replace(':id', this.addForm.value.id), this.addForm.value)
|
||||
.subscribe(response => {
|
||||
this.dialogRef.close({ refresh: true });
|
||||
}, error => {
|
||||
this.errorMessage = error.detail;
|
||||
});
|
||||
}, error => {
|
||||
this.errorMessage = error.detail;
|
||||
.subscribe({
|
||||
next: (response) => {
|
||||
this.httpClient
|
||||
.post<CurrencyModel[]>(ApiRoutes.SettingsCurrenciesRate.replace(':id', this.addForm.value.id), this.addForm.value)
|
||||
.subscribe({
|
||||
next: (response) => {
|
||||
this.dialogRef.close({ refresh: true });
|
||||
},
|
||||
error: (error) => {
|
||||
this.error = error;
|
||||
},
|
||||
});
|
||||
},
|
||||
error: (error) => {
|
||||
this.error = error;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,30 @@
|
||||
<div class="card">
|
||||
<div class="body">
|
||||
<div id="mail-nav">
|
||||
<ul>
|
||||
<mat-form-field class="example-full-width right-content" *ngIf="selectedCount > 0">
|
||||
<mat-label>Move to category</mat-label>
|
||||
<mat-select [(ngModel)]="category" (selectionChange)="onCategoryChange($event)">
|
||||
<mat-option *ngFor="let category of categories" [value]="category.id">
|
||||
{{category.name}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</ul>
|
||||
<ul class="" id="mail-folders">
|
||||
<li *ngFor="let category of categories" [class.active]="selectedCategory && selectedCategory.id == category.id">
|
||||
<a href="javascript:;" (click)="selectCategory(category)" title="{{category.name}}">{{category.name}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul *ngIf="categoryAddShow">
|
||||
<mat-form-field class="example-full-width">
|
||||
<mat-label>Code</mat-label>
|
||||
<input matInput [(ngModel)]="categoryAddName">
|
||||
</mat-form-field>
|
||||
</ul>
|
||||
<ul *ngIf="!categoryAddShow">
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -36,9 +55,13 @@
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr *ngFor="let item of items">
|
||||
<td>{{item.name}}</td>
|
||||
<td>
|
||||
<button class="btn-space" (click)="edit(item)" mat-raised-button color="primary">
|
||||
<mat-checkbox [(ngModel)]="item.selected" (change)="onCheckboxChange(item)">
|
||||
{{item.model.name}}
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn-space" (click)="edit(item.model)" mat-raised-button color="primary">
|
||||
Edit
|
||||
</button>
|
||||
</td>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
.card-title {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.left-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.right-content {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import { MatDialog } from '@angular/material/dialog';
|
||||
import { ApiRoutes } from '../../../api-routes';
|
||||
import { SettingsItemEditComponent } from './edit.item.component';
|
||||
import { ItemService } from '../../../services/item.service';
|
||||
import { ISelectableModel } from '../../../core/models/selectable.model';
|
||||
import { ItemModel } from '../../../model/item.model';
|
||||
import { ItemCategoryModel } from '../../../model/item.category.model';
|
||||
|
||||
@@ -18,9 +19,13 @@ import { ItemCategoryModel } from '../../../model/item.category.model';
|
||||
styleUrls: ['./item.component.scss'],
|
||||
})
|
||||
export class SettingsItemComponent {
|
||||
public items?: ItemModel[];
|
||||
public items?: ISelectableModel<ItemModel>[];
|
||||
public categories?: ItemCategoryModel[];
|
||||
public selectedCategory?: ItemCategoryModel;
|
||||
public selectedCount: number = 0;
|
||||
public category?: ItemCategoryModel;
|
||||
public categoryAddShow: boolean = false;
|
||||
public categoryAddName?: string;
|
||||
|
||||
constructor(
|
||||
private dialogModel: MatDialog,
|
||||
@@ -53,7 +58,7 @@ export class SettingsItemComponent {
|
||||
this.selectedCategory = category;
|
||||
this.itemService.getItems(category.id)
|
||||
.subscribe(data => {
|
||||
this.items = data;
|
||||
this.items = data.map<ISelectableModel<ItemModel>>(x => { return { model: x, selected: false } });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -95,4 +100,22 @@ export class SettingsItemComponent {
|
||||
this.load();
|
||||
});
|
||||
}
|
||||
|
||||
onCheckboxChange(item: ISelectableModel<ItemModel>) {
|
||||
this.selectedCount += item.selected ? 1 : -1;
|
||||
}
|
||||
|
||||
onCategoryChange(item: any) {
|
||||
var data = {
|
||||
category: item.value,
|
||||
items: this.items!.filter(x => x.selected).map(x => x.model.id)
|
||||
}
|
||||
this.httpClient.post(ApiRoutes.SettingsItems, data)
|
||||
.subscribe(data => {
|
||||
this.category = undefined;
|
||||
this.selectedCount = 0;
|
||||
this.load();
|
||||
}, error => {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,5 +103,6 @@
|
||||
"OTHER": "Інші",
|
||||
"TOTAL": "Всього",
|
||||
"INCOME": "Надходження",
|
||||
"OUTCOME": "Витрати"
|
||||
"OUTCOME": "Витрати",
|
||||
"PERIOD": "Період"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
namespace MyOffice.Services.Account;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Core;
|
||||
using Core.Extensions;
|
||||
using Data.Models.Accounts;
|
||||
using Domain;
|
||||
|
||||
public partial class AccountService
|
||||
{
|
||||
public Exec<AccountAccessInviteDto, AccessInviteStatus> AccessInvite(Guid userId, Guid accountId, string email, bool isAllowWrite)
|
||||
{
|
||||
if (email == null)
|
||||
throw new ArgumentNullException(nameof(email));
|
||||
|
||||
var result = new Exec<AccountAccessInviteDto, AccessInviteStatus>(AccessInviteStatus.success);
|
||||
|
||||
var account = _accountRepository.Get(userId, accountId);
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(AccessInviteStatus.account_not_found);
|
||||
}
|
||||
|
||||
if (account.AccessRights!.Any(x => x.User!.Email.EqualsIgnoreCase(email)))
|
||||
{
|
||||
return result.Set(AccessInviteStatus.access_exists);
|
||||
}
|
||||
|
||||
var access = _accountAccessInviteRepository.Get(userId, email);
|
||||
if (access != null)
|
||||
{
|
||||
return result.Set(AccessInviteStatus.invite_exists);
|
||||
}
|
||||
|
||||
var invite = new AccountAccessInvite
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
CreatedOn = DateTime.UtcNow,
|
||||
UserId = userId,
|
||||
AccountId = account.Id,
|
||||
Email = email.SafeTrim()!,
|
||||
IsAllowWrite = isAllowWrite,
|
||||
};
|
||||
|
||||
_accountAccessInviteRepository.Add(invite);
|
||||
|
||||
return result.Set(_mapper.Map<AccountAccessInviteDto>(invite));
|
||||
}
|
||||
|
||||
public Exec<AccountDto, GeneralExecStatus> AccessUpdate(Guid userId, Guid accountId, List<AccountAccessDto> accesses)
|
||||
{
|
||||
if (accesses == null)
|
||||
throw new ArgumentNullException(nameof(accesses));
|
||||
|
||||
var result = new Exec<AccountDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var account = _accountRepository.Get(userId, accountId);
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
foreach (var access in account.AccessRights!)
|
||||
{
|
||||
var newAccess = accesses.FirstOrDefault(x => x.UserId == access.UserId);
|
||||
if (newAccess != null && newAccess.IsAllowWrite != access.IsAllowWrite)
|
||||
{
|
||||
access.IsAllowWrite = newAccess.IsAllowWrite;
|
||||
_accountAccessRepository.Update(access);
|
||||
}
|
||||
}
|
||||
|
||||
account = _accountRepository.Get(userId, accountId);
|
||||
|
||||
return result.Set(_mapper.Map<AccountDto>(account));
|
||||
}
|
||||
|
||||
public Exec<AccountDto, GeneralExecStatus> AccessDelete(Guid userId, Guid accountId, Guid accessUserId)
|
||||
{
|
||||
var result = new Exec<AccountDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var account = _accountRepository.Get(userId, accountId);
|
||||
if (account == null || !account.AccessRights!.Any() || account.AccessRights!.Count() == 1)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
var access = account.AccessRights!.FirstOrDefault(x => x.UserId == accessUserId);
|
||||
if (access == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
if (access.OwnerId == access.UserId)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
_accountAccessRepository.Delete(access);
|
||||
|
||||
account = _accountRepository.Get(userId, accountId);
|
||||
|
||||
return result.Set(_mapper.Map<AccountDto>(account));
|
||||
|
||||
}
|
||||
|
||||
public List<AccountAccessInviteDto> InvitesGet(string email)
|
||||
{
|
||||
return _mapper.Map<List<AccountAccessInviteDto>>(_accountAccessInviteRepository.GetActive(email).ToList());
|
||||
}
|
||||
|
||||
public Exec<AccountDto, InviteAcceptStatus> InviteAccept(Guid userId, Guid id, string name)
|
||||
{
|
||||
var result = new Exec<AccountDto, InviteAcceptStatus>(InviteAcceptStatus.success);
|
||||
|
||||
var invite = _accountAccessInviteRepository.Get(id);
|
||||
if (invite == null
|
||||
|| !invite.Email.EqualsIgnoreCase(_contextProvider.User.Email)
|
||||
|| invite.AcceptedOn.HasValue
|
||||
|| invite.RejectedOn.HasValue
|
||||
)
|
||||
{
|
||||
return result.Set(InviteAcceptStatus.invite_not_found);
|
||||
}
|
||||
|
||||
var account = _accountRepository.Get(invite.UserId, invite.AccountId);
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(InviteAcceptStatus.account_not_found);
|
||||
}
|
||||
|
||||
if (account.AccessRights!.Any(x => x.UserId == userId))
|
||||
{
|
||||
result.Set(InviteAcceptStatus.already_accepted);
|
||||
}
|
||||
else
|
||||
{
|
||||
_accountAccessRepository.Add(new AccountAccess
|
||||
{
|
||||
UserId = userId,
|
||||
AccountId = account.Id,
|
||||
OwnerId = invite.UserId,
|
||||
Name = name,
|
||||
IsAllowWrite = invite.IsAllowWrite,
|
||||
Type = AccountAccessTypeEnum.external,
|
||||
});
|
||||
}
|
||||
|
||||
invite.AcceptedOn = DateTime.UtcNow;
|
||||
_accountAccessInviteRepository.Update(invite);
|
||||
|
||||
account = _accountRepository.Get(userId, account.Id);
|
||||
|
||||
return result.Set(_mapper.Map<AccountDto>(account));
|
||||
}
|
||||
|
||||
public Exec<AccountAccessInviteDto, GeneralExecStatus> InviteReject(Guid id)
|
||||
{
|
||||
var result = new Exec<AccountAccessInviteDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var invite = _accountAccessInviteRepository.Get(id);
|
||||
if (invite == null
|
||||
|| !invite.Email.EqualsIgnoreCase(_contextProvider.User.Email)
|
||||
|| invite.AcceptedOn.HasValue
|
||||
|| invite.RejectedOn.HasValue
|
||||
)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
invite.RejectedOn = DateTime.UtcNow;
|
||||
_accountAccessInviteRepository.Update(invite);
|
||||
|
||||
return result.Set(_mapper.Map<AccountAccessInviteDto>(invite));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
namespace MyOffice.Services.Account;
|
||||
|
||||
using MyOffice.Core;
|
||||
using MyOffice.Core.Extensions;
|
||||
using MyOffice.Data.Models.Accounts;
|
||||
using MyOffice.Services.Account.Domain;
|
||||
|
||||
public partial class AccountService
|
||||
{
|
||||
public List<AccountDto> GetAllAccounts(Guid userId)
|
||||
{
|
||||
return _accountRepository
|
||||
.GetAll(userId)
|
||||
.ToDto<AccountDto>(_mapper);
|
||||
}
|
||||
|
||||
public List<AccountDto> GetByCategory(Guid userId, Guid categoryId)
|
||||
{
|
||||
return _accountRepository
|
||||
.GetByCategory(userId, categoryId)
|
||||
.ToDto<AccountDto>(_mapper);
|
||||
}
|
||||
|
||||
public List<AccountDto> FindAccounts(Guid userId, string term)
|
||||
{
|
||||
return _accountRepository
|
||||
.FindAccounts(userId, term)
|
||||
.ToDto<AccountDto>(_mapper);
|
||||
}
|
||||
|
||||
public List<AccountDetailedDto> GetByCategoryDetailed(Guid userId, Guid categoryId)
|
||||
{
|
||||
return _accountRepository
|
||||
.GetByCategoryDetailed(userId, categoryId)
|
||||
.ToDto<AccountDetailedDto>(_mapper);
|
||||
}
|
||||
|
||||
public Exec<AccountDetailedDto, GeneralExecStatus> GetByIdDetailed(Guid userId, Guid id)
|
||||
{
|
||||
var result = new Exec<AccountDetailedDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var account = _accountRepository.GetByIdDetailed(userId, id);
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
return result.Set(account.ToDto<AccountDetailedDto>(_mapper));;
|
||||
}
|
||||
|
||||
public Exec<AccountDto, AccountAddStatus> AccountAdd(Guid userId, AccountAdd input)
|
||||
{
|
||||
if (input == null)
|
||||
throw new ArgumentNullException(nameof(input));
|
||||
|
||||
var result = new Exec<AccountDto, AccountAddStatus>(AccountAddStatus.success);
|
||||
|
||||
var category = _accountCategoryRepository.Get(userId, input.CategoryId);
|
||||
if (category == null)
|
||||
{
|
||||
return result.Set(AccountAddStatus.category_not_found);
|
||||
}
|
||||
var currency = _currencyRepository.GetByGlobalCurrency(userId, input.CurrencyId);
|
||||
if (currency == null)
|
||||
{
|
||||
return result.Set(AccountAddStatus.currency_not_found);
|
||||
}
|
||||
|
||||
var account = new Account
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Name = input.Name,
|
||||
CurrencyGlobalId = currency.CurrencyGlobalId,
|
||||
OwnerId = userId,
|
||||
};
|
||||
|
||||
account.Categories = new List<AccountAccountCategory>
|
||||
{
|
||||
new()
|
||||
{
|
||||
AccountId = account.Id,
|
||||
CategoryId = category.Id,
|
||||
}
|
||||
};
|
||||
account.AccessRights = new List<AccountAccess>
|
||||
{
|
||||
new()
|
||||
{
|
||||
AccountId = account.Id,
|
||||
UserId = userId,
|
||||
OwnerId = userId,
|
||||
IsAllowManage = true,
|
||||
IsAllowRead = true,
|
||||
IsAllowWrite = true,
|
||||
}
|
||||
};
|
||||
|
||||
if (!_accountRepository.Add(account))
|
||||
{
|
||||
return result.Set(AccountAddStatus.failure);
|
||||
}
|
||||
// TODO: Add category refactoring
|
||||
if (!_accountAccountCategoryRepository.Add(account.Categories.FirstOrDefault()!))
|
||||
{
|
||||
return result.Set(AccountAddStatus.failure);
|
||||
}
|
||||
// TODO: Add access refactoring
|
||||
if (!_accountAccessRepository.Add(account.AccessRights.FirstOrDefault()!))
|
||||
{
|
||||
return result.Set(AccountAddStatus.failure);
|
||||
}
|
||||
|
||||
// TODO: Add account update AccessRights ???
|
||||
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.ToDto<AccountDto>(_mapper));
|
||||
}
|
||||
|
||||
public Exec<AccountDto, GeneralExecStatus> AccountDelete(Guid userId, string id)
|
||||
{
|
||||
var result = new Exec<AccountDto, 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.ToDto<AccountDto>(_mapper));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Exec<AccountDto, AccountEditStatus> AccountUpdate(Guid userId, Guid accountId, AccountEdit input)
|
||||
{
|
||||
if (input == null)
|
||||
throw new ArgumentNullException(nameof(input));
|
||||
|
||||
var result = new Exec<AccountDto, AccountEditStatus>(AccountEditStatus.success);
|
||||
|
||||
AccountCategory? category = null;
|
||||
if (input.CategoryId.HasValue)
|
||||
{
|
||||
category = _accountCategoryRepository.Get(userId, input.CategoryId.Value);
|
||||
if (category == null)
|
||||
{
|
||||
return result.Set(AccountEditStatus.category_not_found);
|
||||
}
|
||||
}
|
||||
|
||||
var currency = _currencyRepository.GetByGlobalCurrency(userId, input.CurrencyId);
|
||||
if (currency == null)
|
||||
{
|
||||
return result.Set(AccountEditStatus.currency_not_found);
|
||||
}
|
||||
|
||||
var account = _accountRepository.Get(userId, accountId);
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(AccountEditStatus.not_found);
|
||||
}
|
||||
|
||||
account.Name = input.Name;
|
||||
if (account.CurrencyGlobalId != currency.CurrencyGlobalId)
|
||||
{
|
||||
account.CurrencyGlobalId = currency.CurrencyGlobalId;
|
||||
}
|
||||
|
||||
if (category != null && account.Categories!.All(x => x.CategoryId != category.Id))
|
||||
{
|
||||
_accountAccountCategoryRepository.Add(new AccountAccountCategory
|
||||
{
|
||||
AccountId = account.Id,
|
||||
CategoryId = category.Id,
|
||||
});
|
||||
}
|
||||
|
||||
if (!_accountRepository.Update(account))
|
||||
{
|
||||
return result.Set(AccountEditStatus.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.ToDto<AccountDto>(_mapper));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
namespace MyOffice.Services.Account;
|
||||
|
||||
using MyOffice.Core;
|
||||
using MyOffice.Data.Models.Accounts;
|
||||
using MyOffice.Services.Account.Domain;
|
||||
|
||||
public partial class AccountService
|
||||
{
|
||||
public List<AccountCategoryDto> GetAllCategories(Guid userId)
|
||||
{
|
||||
var categories = _accountCategoryRepository.GetAll(userId);
|
||||
|
||||
return _mapper.Map<List<AccountCategoryDto>>(categories);
|
||||
}
|
||||
|
||||
public Exec<AccountCategoryDto, GeneralExecStatus> GetCategory(Guid userId, Guid id)
|
||||
{
|
||||
var result = new Exec<AccountCategoryDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var category = _accountCategoryRepository.Get(userId, id);
|
||||
|
||||
if (category == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
return result.Set(_mapper.Map<AccountCategoryDto>(category));
|
||||
}
|
||||
|
||||
public Exec<AccountCategoryDto, GeneralExecStatus> CategoryAdd(Guid userId, AccountCategoryDto input)
|
||||
{
|
||||
if (input == null)
|
||||
throw new ArgumentNullException(nameof(input));
|
||||
|
||||
var result = new Exec<AccountCategoryDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var category = new AccountCategory
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
UserId = userId,
|
||||
Name = input.Name,
|
||||
};
|
||||
|
||||
if (!_accountCategoryRepository.Add(category))
|
||||
{
|
||||
return result.Set(GeneralExecStatus.failure);
|
||||
}
|
||||
|
||||
return result.Set(_mapper.Map<AccountCategoryDto>(category));
|
||||
}
|
||||
|
||||
public Exec<AccountCategoryDto, GeneralExecStatus> CategoryUpdate(Guid userId, Guid id, AccountCategoryDto input)
|
||||
{
|
||||
if (input == null)
|
||||
throw new ArgumentNullException(nameof(input));
|
||||
|
||||
var result = new Exec<AccountCategoryDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var exists = _accountCategoryRepository.Get(userId, id);
|
||||
if (exists == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
exists.Name = input.Name;
|
||||
|
||||
if (!_accountCategoryRepository.Update(exists))
|
||||
{
|
||||
return result.Set(GeneralExecStatus.failure);
|
||||
}
|
||||
|
||||
return result.Set(_mapper.Map<AccountCategoryDto>(exists));
|
||||
}
|
||||
|
||||
public Exec<AccountCategoryDto, AccountCategoryRemoveResult> CategoryRemove(Guid userId, Guid id)
|
||||
{
|
||||
var result = new Exec<AccountCategoryDto, AccountCategoryRemoveResult>(AccountCategoryRemoveResult.success);
|
||||
|
||||
var exists = _accountCategoryRepository.Get(userId, id);
|
||||
if (exists == null)
|
||||
{
|
||||
return result.Set(AccountCategoryRemoveResult.not_found);
|
||||
}
|
||||
|
||||
if (exists.Accounts?.Any() == true)
|
||||
{
|
||||
return result.Set(AccountCategoryRemoveResult.accounts_exists);
|
||||
}
|
||||
if (!_accountCategoryRepository.Remove(exists))
|
||||
{
|
||||
return result.Set(AccountCategoryRemoveResult.failure);
|
||||
}
|
||||
|
||||
return result.Set(_mapper.Map<AccountCategoryDto>(exists));
|
||||
}
|
||||
|
||||
public Exec<List<AccountAccountCategoryDto>, GeneralExecStatus> AccountCategoryRemove(Guid userId, Guid accountId, Guid categoryId)
|
||||
{
|
||||
var result = new Exec<List<AccountAccountCategoryDto>, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var categories = _accountAccountCategoryRepository.Get(userId, accountId, categoryId);
|
||||
if (categories.Count == 0)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
foreach (var category in categories)
|
||||
{
|
||||
_accountAccountCategoryRepository.Remove(category);
|
||||
}
|
||||
|
||||
return result.Set(_mapper.Map<List<AccountAccountCategoryDto>>(categories));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
namespace MyOffice.Services.Account;
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Core;
|
||||
using Core.Extensions;
|
||||
using Data.Models.Accounts;
|
||||
using Domain;
|
||||
using Item.Domain;
|
||||
|
||||
public partial class AccountService
|
||||
{
|
||||
public Exec<List<MotionDto>, MotionAddStatus> MotionAdd(
|
||||
Guid userId,
|
||||
Guid accountId,
|
||||
MotionAddUpdate motion
|
||||
)
|
||||
{
|
||||
if (motion == null)
|
||||
throw new ArgumentNullException(nameof(motion));
|
||||
if (motion.Item == null)
|
||||
throw new ArgumentNullException(nameof(motion.Item));
|
||||
|
||||
var result = new Exec<List<MotionDto>, MotionAddStatus>(MotionAddStatus.success);
|
||||
|
||||
var account = _accountRepository.Get(userId, accountId);
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(MotionAddStatus.account_not_found);
|
||||
}
|
||||
|
||||
var itemExec = _itemService.GetOrCreate(userId, motion.Item);
|
||||
if (itemExec.Status != ItemGetOrAddResult.success)
|
||||
{
|
||||
return result.Set(MotionAddStatus.failure);
|
||||
}
|
||||
|
||||
var motionDb = new Motion
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
CreatedOn = DateTime.UtcNow,
|
||||
DateTime = motion.Date,
|
||||
AccountId = account.Id,
|
||||
ItemId = itemExec.Result!.Id,
|
||||
Description = motion.Description,
|
||||
AmountPlus = motion.Plus,
|
||||
AmountMinus = motion.Minus,
|
||||
};
|
||||
|
||||
if (!_motionRepository.Add(motionDb))
|
||||
{
|
||||
return result.Set(MotionAddStatus.failure);
|
||||
}
|
||||
|
||||
result.Set(new List<MotionDto>());
|
||||
result.Result!.Add(_mapper.Map<MotionDto>(motionDb));
|
||||
|
||||
if (motion.AccountId.IsPresent() && motion.AmountBalancing != 0)
|
||||
{
|
||||
var accountBalancing = _accountRepository.Get(userId, motion.AccountId!.AsGuid());
|
||||
if (accountBalancing != null)
|
||||
{
|
||||
var balancingName = $"+{account.Name}";
|
||||
var itemBalancingExec = _itemService.GetOrCreate(userId, balancingName);
|
||||
var plus = motion.AmountBalancing;
|
||||
var minus = 0m;
|
||||
if (motion.Plus != 0)
|
||||
{
|
||||
plus = 0;
|
||||
minus = motion.AmountBalancing;
|
||||
}
|
||||
var motionBalancing = new Motion
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
CreatedOn = DateTime.UtcNow,
|
||||
DateTime = motion.Date,
|
||||
AccountId = accountBalancing.Id,
|
||||
ItemId = itemBalancingExec.Result!.Id,
|
||||
Description = motion.Description,
|
||||
AmountPlus = plus,
|
||||
AmountMinus = minus,
|
||||
};
|
||||
|
||||
if (_motionRepository.Add(motionBalancing))
|
||||
{
|
||||
result.Result!.Add(_mapper.Map<MotionDto>(motionBalancing));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
motionDb.Item = itemExec.Result!;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Exec<MotionDto, MotionUpdateStatus> MotionUpdate(
|
||||
Guid userId,
|
||||
Guid accountId,
|
||||
Guid motionId,
|
||||
MotionAddUpdate motion
|
||||
)
|
||||
{
|
||||
if (motion == null)
|
||||
throw new ArgumentNullException(nameof(motion));
|
||||
if (motion.Item == null)
|
||||
throw new ArgumentNullException(nameof(motion.Item));
|
||||
|
||||
var result = new Exec<MotionDto, MotionUpdateStatus>(MotionUpdateStatus.success);
|
||||
|
||||
var exists = _motionRepository.Get(userId, motionId);
|
||||
if (exists == null || exists.AccountId != accountId)
|
||||
{
|
||||
return result.Set(MotionUpdateStatus.not_found);
|
||||
}
|
||||
|
||||
var itemExec = _itemService.GetOrCreate(userId, motion.Item);
|
||||
if (itemExec.Status != ItemGetOrAddResult.success)
|
||||
{
|
||||
return result.Set(MotionUpdateStatus.failure);
|
||||
}
|
||||
|
||||
exists.Item.Id = itemExec.Result!.Id;
|
||||
exists.DateTime = motion.Date;
|
||||
exists.Description = motion.Description;
|
||||
exists.AmountPlus = motion.Plus;
|
||||
exists.AmountMinus = motion.Minus;
|
||||
|
||||
if (!_motionRepository.Update(exists))
|
||||
{
|
||||
return result.Set(MotionUpdateStatus.failure);
|
||||
|
||||
}
|
||||
|
||||
return result.Set(_mapper.Map<MotionDto>(exists));
|
||||
}
|
||||
|
||||
public Exec<List<MotionDto>, GeneralExecStatus> GetMotions(
|
||||
Guid userId,
|
||||
Guid accountId,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo
|
||||
)
|
||||
{
|
||||
var result = new Exec<List<MotionDto>, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var account = _accountRepository.Get(userId, accountId);
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
var motions = _motionRepository.GetByAccount(accountId, dateFrom.ToUtc(), dateTo.ToUtc());
|
||||
|
||||
return result.Set(_mapper.Map<List<MotionDto>>(motions));
|
||||
}
|
||||
|
||||
public Exec<MotionDto, MotionDeleteStatus> MotionRemove(
|
||||
Guid userId,
|
||||
Guid accountId,
|
||||
Guid motionId
|
||||
)
|
||||
{
|
||||
var result = new Exec<MotionDto, MotionDeleteStatus>(MotionDeleteStatus.success);
|
||||
|
||||
var exists = _motionRepository.Get(userId, motionId);
|
||||
if (exists == null || exists.AccountId != accountId)
|
||||
{
|
||||
return result.Set(MotionDeleteStatus.not_found);
|
||||
}
|
||||
|
||||
if (!_motionRepository.Remove(exists))
|
||||
{
|
||||
return result.Set(MotionDeleteStatus.failure);
|
||||
}
|
||||
|
||||
return result.Set(_mapper.Map<MotionDto>(exists));
|
||||
}
|
||||
}
|
||||
@@ -1,685 +1,58 @@
|
||||
namespace MyOffice.Services.Account
|
||||
namespace MyOffice.Services.Account;
|
||||
|
||||
using AutoMapper;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using Identity;
|
||||
using Data.Repositories.Account;
|
||||
using Data.Repositories.Currency;
|
||||
using Data.Repositories.Item;
|
||||
using Item;
|
||||
|
||||
public partial class AccountService
|
||||
{
|
||||
using AutoMapper;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.Generic;
|
||||
private ILogger<AccountService> _logger;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly IAccountCategoryRepository _accountCategoryRepository;
|
||||
private readonly IAccountAccessRepository _accountAccessRepository;
|
||||
private readonly IAccountAccessInviteRepository _accountAccessInviteRepository;
|
||||
private readonly IAccountRepository _accountRepository;
|
||||
private readonly ICurrencyRepository _currencyRepository;
|
||||
private readonly IAccountAccountCategoryRepository _accountAccountCategoryRepository;
|
||||
private readonly IMotionRepository _motionRepository;
|
||||
private readonly IItemRepository _itemRepository;
|
||||
private readonly IItemGlobalRepository _itemGlobalRepository;
|
||||
private readonly ItemService _itemService;
|
||||
private readonly IContextProvider _contextProvider;
|
||||
|
||||
using Identity;
|
||||
using Core;
|
||||
using Core.Extensions;
|
||||
using Data.Models.Accounts;
|
||||
using Data.Repositories.Account;
|
||||
using Data.Repositories.Currency;
|
||||
using Data.Repositories.Item;
|
||||
using Domain;
|
||||
using Item;
|
||||
using Item.Domain;
|
||||
|
||||
public class AccountService
|
||||
public AccountService(
|
||||
ILogger<AccountService> logger,
|
||||
IMapper mapper,
|
||||
IAccountCategoryRepository accountCategoryRepository,
|
||||
IAccountAccessRepository accountAccessRepository,
|
||||
IAccountAccessInviteRepository accountAccessInviteRepository,
|
||||
IAccountRepository accountRepository,
|
||||
ICurrencyRepository currencyRepository,
|
||||
IAccountAccountCategoryRepository accountAccountCategoryRepository,
|
||||
IMotionRepository motionRepository,
|
||||
IItemRepository itemRepository,
|
||||
IItemGlobalRepository itemGlobalRepository,
|
||||
ItemService itemService,
|
||||
IContextProvider contextProvider
|
||||
)
|
||||
{
|
||||
private ILogger<AccountService> _logger;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly IAccountCategoryRepository _accountCategoryRepository;
|
||||
private readonly IAccountAccessRepository _accountAccessRepository;
|
||||
private readonly IAccountAccessInviteRepository _accountAccessInviteRepository;
|
||||
private readonly IAccountRepository _accountRepository;
|
||||
private readonly ICurrencyRepository _currencyRepository;
|
||||
private readonly IAccountAccountCategoryRepository _accountAccountCategoryRepository;
|
||||
private readonly IMotionRepository _motionRepository;
|
||||
private readonly IItemRepository _itemRepository;
|
||||
private readonly IItemGlobalRepository _itemGlobalRepository;
|
||||
private readonly ItemService _itemService;
|
||||
private readonly IContextProvider _contextProvider;
|
||||
|
||||
public AccountService(
|
||||
ILogger<AccountService> logger,
|
||||
IMapper mapper,
|
||||
IAccountCategoryRepository accountCategoryRepository,
|
||||
IAccountAccessRepository accountAccessRepository,
|
||||
IAccountAccessInviteRepository accountAccessInviteRepository,
|
||||
IAccountRepository accountRepository,
|
||||
ICurrencyRepository currencyRepository,
|
||||
IAccountAccountCategoryRepository accountAccountCategoryRepository,
|
||||
IMotionRepository motionRepository,
|
||||
IItemRepository itemRepository,
|
||||
IItemGlobalRepository itemGlobalRepository,
|
||||
ItemService itemService,
|
||||
IContextProvider contextProvider
|
||||
)
|
||||
{
|
||||
_logger = logger;
|
||||
_mapper = mapper;
|
||||
_accountCategoryRepository = accountCategoryRepository;
|
||||
_accountAccessRepository = accountAccessRepository;
|
||||
_accountAccessInviteRepository = accountAccessInviteRepository;
|
||||
_accountRepository = accountRepository;
|
||||
_currencyRepository = currencyRepository;
|
||||
_accountAccountCategoryRepository = accountAccountCategoryRepository;
|
||||
_motionRepository = motionRepository;
|
||||
_itemRepository = itemRepository;
|
||||
_itemGlobalRepository = itemGlobalRepository;
|
||||
_itemService = itemService;
|
||||
_contextProvider = contextProvider;
|
||||
}
|
||||
|
||||
public List<AccountCategoryDto> GetAllCategories(Guid userId)
|
||||
{
|
||||
var categories = _accountCategoryRepository.GetAll(userId);
|
||||
|
||||
return _mapper.Map<List<AccountCategoryDto>>(categories);
|
||||
}
|
||||
|
||||
public Exec<AccountCategoryDto, GeneralExecStatus> GetCategory(Guid userId, Guid id)
|
||||
{
|
||||
var result = new Exec<AccountCategoryDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var category = _accountCategoryRepository.Get(userId, id);
|
||||
|
||||
if (category == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
return result.Set(_mapper.Map<AccountCategoryDto>(category));
|
||||
}
|
||||
|
||||
public Exec<AccountCategoryDto, GeneralExecStatus> CategoryAdd(Guid userId, AccountCategoryDto input)
|
||||
{
|
||||
if (input == null)
|
||||
throw new ArgumentNullException(nameof(input));
|
||||
|
||||
var result = new Exec<AccountCategoryDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var category = new AccountCategory
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
UserId = userId,
|
||||
Name = input.Name,
|
||||
};
|
||||
|
||||
if (!_accountCategoryRepository.Add(category))
|
||||
{
|
||||
return result.Set(GeneralExecStatus.failure);
|
||||
}
|
||||
|
||||
return result.Set(_mapper.Map<AccountCategoryDto>(category));
|
||||
}
|
||||
|
||||
public Exec<AccountCategoryDto, GeneralExecStatus> CategoryUpdate(Guid userId, Guid id, AccountCategoryDto input)
|
||||
{
|
||||
if (input == null)
|
||||
throw new ArgumentNullException(nameof(input));
|
||||
|
||||
var result = new Exec<AccountCategoryDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var exists = _accountCategoryRepository.Get(userId, id);
|
||||
if (exists == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
exists.Name = input.Name;
|
||||
|
||||
if (!_accountCategoryRepository.Update(exists))
|
||||
{
|
||||
return result.Set(GeneralExecStatus.failure);
|
||||
}
|
||||
|
||||
return result.Set(_mapper.Map<AccountCategoryDto>(exists));
|
||||
}
|
||||
|
||||
public Exec<AccountCategoryDto, AccountCategoryRemoveResult> CategoryRemove(Guid userId, Guid id)
|
||||
{
|
||||
var result = new Exec<AccountCategoryDto, AccountCategoryRemoveResult>(AccountCategoryRemoveResult.success);
|
||||
|
||||
var exists = _accountCategoryRepository.Get(userId, id);
|
||||
if (exists == null)
|
||||
{
|
||||
return result.Set(AccountCategoryRemoveResult.not_found);
|
||||
}
|
||||
|
||||
if (exists.Accounts?.Any() == true)
|
||||
{
|
||||
return result.Set(AccountCategoryRemoveResult.accounts_exists);
|
||||
}
|
||||
if (!_accountCategoryRepository.Remove(exists))
|
||||
{
|
||||
return result.Set(AccountCategoryRemoveResult.failure);
|
||||
}
|
||||
|
||||
return result.Set(_mapper.Map<AccountCategoryDto>(exists));
|
||||
}
|
||||
|
||||
public List<AccountDto> GetAllAccounts(Guid userId)
|
||||
{
|
||||
var accounts = _accountRepository.GetAll(userId);
|
||||
|
||||
return _mapper.Map<List<AccountDto>>(accounts, o => o.Items.Add("UserId", userId));
|
||||
}
|
||||
|
||||
public List<AccountDto> GetByCategory(Guid userId, Guid categoryId)
|
||||
{
|
||||
return _mapper.Map<List<AccountDto>>(_accountRepository.GetByCategory(userId, categoryId));
|
||||
}
|
||||
|
||||
public List<AccountDetailedDto> GetByCategoryDetailed(Guid userId, Guid categoryId)
|
||||
{
|
||||
return _mapper.Map<List<AccountDetailedDto>>(_accountRepository.GetByCategoryDetailed(userId, categoryId));
|
||||
}
|
||||
|
||||
public Exec<AccountDetailedDto, GeneralExecStatus> GetByIdDetailed(Guid userId, Guid id)
|
||||
{
|
||||
var result = new Exec<AccountDetailedDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var account = _accountRepository.GetByIdDetailed(userId, id);
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
return result.Set(_mapper.Map<AccountDetailedDto>(account));
|
||||
}
|
||||
|
||||
public Exec<Account, AccountAddStatus> AccountAdd(Guid userId, AccountAdd input)
|
||||
{
|
||||
if (input == null)
|
||||
throw new ArgumentNullException(nameof(input));
|
||||
|
||||
var result = new Exec<Account, AccountAddStatus>(AccountAddStatus.success);
|
||||
|
||||
var category = _accountCategoryRepository.Get(userId, input.CategoryId);
|
||||
if (category == null)
|
||||
{
|
||||
return result.Set(AccountAddStatus.category_not_found);
|
||||
}
|
||||
var currency = _currencyRepository.GetByGlobalCurrency(userId, input.CurrencyId);
|
||||
if (currency == null)
|
||||
{
|
||||
return result.Set(AccountAddStatus.currency_not_found);
|
||||
}
|
||||
|
||||
var account = new Account
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Name = input.Name,
|
||||
CurrencyGlobalId = currency.CurrencyGlobalId,
|
||||
OwnerId = userId,
|
||||
};
|
||||
|
||||
account.Categories = new List<AccountAccountCategory>
|
||||
{
|
||||
new()
|
||||
{
|
||||
AccountId = account.Id,
|
||||
CategoryId = category.Id,
|
||||
}
|
||||
};
|
||||
account.AccessRights = new List<AccountAccess>
|
||||
{
|
||||
new()
|
||||
{
|
||||
AccountId = account.Id,
|
||||
UserId = userId,
|
||||
OwnerId = userId,
|
||||
IsAllowManage = true,
|
||||
IsAllowRead = true,
|
||||
IsAllowWrite = true,
|
||||
}
|
||||
};
|
||||
|
||||
if (!_accountRepository.Add(account))
|
||||
{
|
||||
return result.Set(AccountAddStatus.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, AccountEditStatus> AccountUpdate(Guid userId, Guid accountId, AccountEdit input)
|
||||
{
|
||||
if (input == null)
|
||||
throw new ArgumentNullException(nameof(input));
|
||||
|
||||
var result = new Exec<Account, AccountEditStatus>(AccountEditStatus.success);
|
||||
|
||||
AccountCategory? category = null;
|
||||
if (input.CategoryId.HasValue)
|
||||
{
|
||||
category = _accountCategoryRepository.Get(userId, input.CategoryId.Value);
|
||||
if (category == null)
|
||||
{
|
||||
return result.Set(AccountEditStatus.category_not_found);
|
||||
}
|
||||
}
|
||||
|
||||
var currency = _currencyRepository.GetByGlobalCurrency(userId, input.CurrencyId);
|
||||
if (currency == null)
|
||||
{
|
||||
return result.Set(AccountEditStatus.currency_not_found);
|
||||
}
|
||||
|
||||
var account = _accountRepository.Get(userId, accountId);
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(AccountEditStatus.not_found);
|
||||
}
|
||||
|
||||
account.Name = input.Name;
|
||||
if (account.CurrencyGlobalId != currency.CurrencyGlobalId)
|
||||
{
|
||||
account.CurrencyGlobalId = currency.CurrencyGlobalId;
|
||||
}
|
||||
|
||||
if (category != null && account.Categories!.All(x => x.CategoryId != category.Id))
|
||||
{
|
||||
_accountAccountCategoryRepository.Add(new AccountAccountCategory
|
||||
{
|
||||
AccountId = account.Id,
|
||||
CategoryId = category.Id,
|
||||
});
|
||||
}
|
||||
|
||||
if (!_accountRepository.Update(account))
|
||||
{
|
||||
return result.Set(AccountEditStatus.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<List<AccountAccountCategory>, GeneralExecStatus> AccountCategoryRemove(Guid userId, Guid accountId, Guid categoryId)
|
||||
{
|
||||
var result = new Exec<List<AccountAccountCategory>, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var categories = _accountAccountCategoryRepository.Get(userId, accountId, categoryId);
|
||||
if (categories.Count == 0)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
foreach (var category in categories)
|
||||
{
|
||||
_accountAccountCategoryRepository.Remove(category);
|
||||
}
|
||||
|
||||
return result.Set(categories);
|
||||
}
|
||||
|
||||
public Exec<List<MotionDto>, MotionAddStatus> MotionAdd(
|
||||
Guid userId,
|
||||
Guid accountId,
|
||||
MotionAddUpdate motion
|
||||
)
|
||||
{
|
||||
if (motion == null)
|
||||
throw new ArgumentNullException(nameof(motion));
|
||||
if (motion.Item == null)
|
||||
throw new ArgumentNullException(nameof(motion.Item));
|
||||
|
||||
var result = new Exec<List<MotionDto>, MotionAddStatus>(MotionAddStatus.success);
|
||||
|
||||
var account = _accountRepository.Get(userId, accountId);
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(MotionAddStatus.account_not_found);
|
||||
}
|
||||
|
||||
var itemExec = _itemService.GetOrCreate(userId, motion.Item);
|
||||
if (itemExec.Status != ItemGetOrAddResult.success)
|
||||
{
|
||||
return result.Set(MotionAddStatus.failure);
|
||||
}
|
||||
|
||||
var motionDb = new Motion
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
CreatedOn = DateTime.UtcNow,
|
||||
DateTime = motion.Date,
|
||||
AccountId = account.Id,
|
||||
ItemId = itemExec.Result!.Id,
|
||||
Description = motion.Description,
|
||||
AmountPlus = motion.Plus,
|
||||
AmountMinus = motion.Minus,
|
||||
};
|
||||
|
||||
if (!_motionRepository.Add(motionDb))
|
||||
{
|
||||
return result.Set(MotionAddStatus.failure);
|
||||
}
|
||||
|
||||
result.Set(new List<MotionDto>());
|
||||
result.Result!.Add(_mapper.Map<MotionDto>(motionDb));
|
||||
|
||||
if (motion.AccountId.IsPresent() && motion.AmountBalancing != 0)
|
||||
{
|
||||
var accountBalancing = _accountRepository.Get(userId, motion.AccountId!.AsGuid());
|
||||
if (accountBalancing != null)
|
||||
{
|
||||
var balancingName = $"+{account.Name}";
|
||||
var itemBalancingExec = _itemService.GetOrCreate(userId, balancingName);
|
||||
var plus = motion.AmountBalancing;
|
||||
var minus = 0m;
|
||||
if (motion.Plus != 0)
|
||||
{
|
||||
plus = 0;
|
||||
minus = motion.AmountBalancing;
|
||||
}
|
||||
var motionBalancing = new Motion
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
CreatedOn = DateTime.UtcNow,
|
||||
DateTime = motion.Date,
|
||||
AccountId = accountBalancing.Id,
|
||||
ItemId = itemBalancingExec.Result!.Id,
|
||||
Description = motion.Description,
|
||||
AmountPlus = plus,
|
||||
AmountMinus = minus,
|
||||
};
|
||||
|
||||
if (_motionRepository.Add(motionBalancing))
|
||||
{
|
||||
result.Result!.Add(_mapper.Map<MotionDto>(motionBalancing));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
motionDb.Item = itemExec.Result!;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Exec<MotionDto, MotionUpdateStatus> MotionUpdate(
|
||||
Guid userId,
|
||||
Guid accountId,
|
||||
Guid motionId,
|
||||
MotionAddUpdate motion
|
||||
)
|
||||
{
|
||||
if (motion == null)
|
||||
throw new ArgumentNullException(nameof(motion));
|
||||
if (motion.Item == null)
|
||||
throw new ArgumentNullException(nameof(motion.Item));
|
||||
|
||||
var result = new Exec<MotionDto, MotionUpdateStatus>(MotionUpdateStatus.success);
|
||||
|
||||
var exists = _motionRepository.Get(userId, motionId);
|
||||
if (exists == null || exists.AccountId != accountId)
|
||||
{
|
||||
return result.Set(MotionUpdateStatus.not_found);
|
||||
}
|
||||
|
||||
var itemExec = _itemService.GetOrCreate(userId, motion.Item);
|
||||
if (itemExec.Status != ItemGetOrAddResult.success)
|
||||
{
|
||||
return result.Set(MotionUpdateStatus.failure);
|
||||
}
|
||||
|
||||
exists.Item.Id = itemExec.Result!.Id;
|
||||
exists.DateTime = motion.Date;
|
||||
exists.Description = motion.Description;
|
||||
exists.AmountPlus = motion.Plus;
|
||||
exists.AmountMinus = motion.Minus;
|
||||
|
||||
if (!_motionRepository.Update(exists))
|
||||
{
|
||||
return result.Set(MotionUpdateStatus.failure);
|
||||
|
||||
}
|
||||
|
||||
return result.Set(_mapper.Map<MotionDto>(exists));
|
||||
}
|
||||
|
||||
public Exec<List<Motion>, GeneralExecStatus> GetMotions(
|
||||
Guid userId,
|
||||
Guid accountId,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo
|
||||
)
|
||||
{
|
||||
var result = new Exec<List<Motion>, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var account = _accountRepository.Get(userId, accountId);
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
var motions = _motionRepository.GetByAccount(accountId, dateFrom.ToUtc(), dateTo.ToUtc());
|
||||
|
||||
return result.Set(motions);
|
||||
}
|
||||
|
||||
public Exec<Motion, MotionDeleteStatus> MotionRemove(
|
||||
Guid userId,
|
||||
Guid accountId,
|
||||
Guid motionId
|
||||
)
|
||||
{
|
||||
var result = new Exec<Motion, MotionDeleteStatus>(MotionDeleteStatus.success);
|
||||
|
||||
var exists = _motionRepository.Get(userId, motionId);
|
||||
if (exists == null || exists.AccountId != accountId)
|
||||
{
|
||||
return result.Set(MotionDeleteStatus.not_found);
|
||||
}
|
||||
|
||||
if (!_motionRepository.Remove(exists))
|
||||
{
|
||||
return result.Set(MotionDeleteStatus.failure);
|
||||
}
|
||||
|
||||
return result.Set(exists);
|
||||
}
|
||||
|
||||
public List<Account> FindAccounts(Guid userId, string term)
|
||||
{
|
||||
return _accountRepository.FindAccounts(userId, term);
|
||||
}
|
||||
|
||||
public Exec<AccountAccessInvite, AccessInviteStatus> AccessInvite(Guid userId, Guid accountId, string email, bool isAllowWrite)
|
||||
{
|
||||
if (email == null)
|
||||
throw new ArgumentNullException(nameof(email));
|
||||
|
||||
var result = new Exec<AccountAccessInvite, AccessInviteStatus>(AccessInviteStatus.success);
|
||||
|
||||
var account = _accountRepository.Get(userId, accountId);
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(AccessInviteStatus.account_not_found);
|
||||
}
|
||||
|
||||
if (account.AccessRights!.Any(x => x.User!.Email.EqualsIgnoreCase(email)))
|
||||
{
|
||||
return result.Set(AccessInviteStatus.access_exists);
|
||||
}
|
||||
|
||||
var access = _accountAccessInviteRepository.Get(userId, email);
|
||||
if (access != null)
|
||||
{
|
||||
return result.Set(AccessInviteStatus.invite_exists);
|
||||
}
|
||||
|
||||
var invite = new AccountAccessInvite
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
CreatedOn = DateTime.UtcNow,
|
||||
UserId = userId,
|
||||
AccountId = account.Id,
|
||||
Email = email.SafeTrim()!,
|
||||
IsAllowWrite = isAllowWrite,
|
||||
};
|
||||
|
||||
_accountAccessInviteRepository.Add(invite);
|
||||
|
||||
return result.Set(invite);
|
||||
}
|
||||
|
||||
public Exec<AccountDto, GeneralExecStatus> AccessUpdate(Guid userId, Guid accountId, List<AccountAccessDto> accesses)
|
||||
{
|
||||
if (accesses == null)
|
||||
throw new ArgumentNullException(nameof(accesses));
|
||||
|
||||
var result = new Exec<AccountDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var account = _accountRepository.Get(userId, accountId);
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
foreach (var access in account.AccessRights!)
|
||||
{
|
||||
var newAccess = accesses.FirstOrDefault(x => x.UserId == access.UserId);
|
||||
if (newAccess != null && newAccess.IsAllowWrite != access.IsAllowWrite)
|
||||
{
|
||||
access.IsAllowWrite = newAccess.IsAllowWrite;
|
||||
_accountAccessRepository.Update(access);
|
||||
}
|
||||
}
|
||||
|
||||
account = _accountRepository.Get(userId, accountId);
|
||||
|
||||
return result.Set(_mapper.Map<AccountDto>(account));
|
||||
}
|
||||
|
||||
public Exec<AccountDto, GeneralExecStatus> AccessDelete(Guid userId, Guid accountId, Guid accessUserId)
|
||||
{
|
||||
var result = new Exec<AccountDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var account = _accountRepository.Get(userId, accountId);
|
||||
if (account == null || !account.AccessRights!.Any() || account.AccessRights!.Count() == 1)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
var access = account.AccessRights!.FirstOrDefault(x => x.UserId == accessUserId);
|
||||
if (access == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
if (access.OwnerId == access.UserId)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
_accountAccessRepository.Delete(access);
|
||||
|
||||
account = _accountRepository.Get(userId, accountId);
|
||||
|
||||
return result.Set(_mapper.Map<AccountDto>(account));
|
||||
|
||||
}
|
||||
|
||||
public List<AccountAccessInviteDto> InvitesGet(string email)
|
||||
{
|
||||
return _mapper.Map<List<AccountAccessInviteDto>>(_accountAccessInviteRepository.GetActive(email).ToList());
|
||||
}
|
||||
|
||||
public Exec<AccountDto, InviteAcceptStatus> InviteAccept(Guid userId, Guid id, string name)
|
||||
{
|
||||
var result = new Exec<AccountDto, InviteAcceptStatus>(InviteAcceptStatus.success);
|
||||
|
||||
var invite = _accountAccessInviteRepository.Get(id);
|
||||
if (invite == null
|
||||
|| !invite.Email.EqualsIgnoreCase(_contextProvider.User.Email)
|
||||
|| invite.AcceptedOn.HasValue
|
||||
|| invite.RejectedOn.HasValue
|
||||
)
|
||||
{
|
||||
return result.Set(InviteAcceptStatus.invite_not_found);
|
||||
}
|
||||
|
||||
var account = _accountRepository.Get(invite.UserId, invite.AccountId);
|
||||
if (account == null)
|
||||
{
|
||||
return result.Set(InviteAcceptStatus.account_not_found);
|
||||
}
|
||||
|
||||
if (account.AccessRights!.Any(x => x.UserId == userId))
|
||||
{
|
||||
result.Set(InviteAcceptStatus.already_accepted);
|
||||
}
|
||||
else
|
||||
{
|
||||
_accountAccessRepository.Add(new AccountAccess
|
||||
{
|
||||
UserId = userId,
|
||||
AccountId = account.Id,
|
||||
OwnerId = invite.UserId,
|
||||
Name = name,
|
||||
IsAllowWrite = invite.IsAllowWrite,
|
||||
Type = AccountAccessTypeEnum.external,
|
||||
});
|
||||
}
|
||||
|
||||
invite.AcceptedOn = DateTime.UtcNow;
|
||||
_accountAccessInviteRepository.Update(invite);
|
||||
|
||||
account = _accountRepository.Get(userId, account.Id);
|
||||
|
||||
return result.Set(_mapper.Map<AccountDto>(account));
|
||||
}
|
||||
|
||||
public Exec<AccountAccessInviteDto, GeneralExecStatus> InviteReject(Guid id)
|
||||
{
|
||||
var result = new Exec<AccountAccessInviteDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var invite = _accountAccessInviteRepository.Get(id);
|
||||
if (invite == null
|
||||
|| !invite.Email.EqualsIgnoreCase(_contextProvider.User.Email)
|
||||
|| invite.AcceptedOn.HasValue
|
||||
|| invite.RejectedOn.HasValue
|
||||
)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
invite.RejectedOn = DateTime.UtcNow;
|
||||
_accountAccessInviteRepository.Update(invite);
|
||||
|
||||
return result.Set(_mapper.Map<AccountAccessInviteDto>(invite));
|
||||
}
|
||||
_logger = logger;
|
||||
_mapper = mapper;
|
||||
_accountCategoryRepository = accountCategoryRepository;
|
||||
_accountAccessRepository = accountAccessRepository;
|
||||
_accountAccessInviteRepository = accountAccessInviteRepository;
|
||||
_accountRepository = accountRepository;
|
||||
_currencyRepository = currencyRepository;
|
||||
_accountAccountCategoryRepository = accountAccountCategoryRepository;
|
||||
_motionRepository = motionRepository;
|
||||
_itemRepository = itemRepository;
|
||||
_itemGlobalRepository = itemGlobalRepository;
|
||||
_itemService = itemService;
|
||||
_contextProvider = contextProvider;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
|
||||
using Core.Attributes;
|
||||
using AutoMapper;
|
||||
using Data.Models.Accounts;
|
||||
using Data.Models.Users;
|
||||
using Mapper;
|
||||
using MyOffice.Services.Identity;
|
||||
|
||||
[Link(typeof(AccountAccess))]
|
||||
[Link(typeof(AccountServiceProfile))]
|
||||
public class AccountAccessDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Current user
|
||||
/// </summary>
|
||||
public Guid CurrenUserId { get; set; }
|
||||
|
||||
public Guid AccountId { get; set; }
|
||||
public AccountDto? Account { get; set; }
|
||||
|
||||
@@ -21,15 +13,41 @@ public class AccountAccessDto
|
||||
/// User can access to account
|
||||
/// </summary>
|
||||
public Guid UserId { get; set; }
|
||||
public User? User { get; set; }
|
||||
/// <summary>
|
||||
/// Who add access
|
||||
/// </summary>
|
||||
public Guid OwnerId { get; set; }
|
||||
public User? Owner { get; set; }
|
||||
public UserDto? User { get; set; }
|
||||
|
||||
public bool IsAllowRead { get; set; }
|
||||
public bool IsAllowWrite { get; set; }
|
||||
public bool IsAllowManage { get; set; }
|
||||
public bool IsOwner { get; set; }
|
||||
public AccountAccessTypeEnum Type { get; set; }
|
||||
/// <summary>
|
||||
/// Who add access
|
||||
/// </summary>
|
||||
public Guid OwnerId { get; set; }
|
||||
public UserDto? Owner { get; set; }
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
|
||||
public class AccountAccessDtoProfile : Profile
|
||||
{
|
||||
public AccountAccessDtoProfile()
|
||||
{
|
||||
CreateMap<AccountAccess, AccountAccessDto>()
|
||||
.AfterMap<AccountAccessDtoMappingAction>()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
public class AccountAccessDtoMappingAction : IMappingAction<AccountAccess, AccountAccessDto>
|
||||
{
|
||||
private readonly IContextProvider _contextProvider;
|
||||
public AccountAccessDtoMappingAction(IContextProvider contextProvider)
|
||||
{
|
||||
_contextProvider = contextProvider;
|
||||
}
|
||||
|
||||
public void Process(AccountAccess source, AccountAccessDto destination, ResolutionContext context)
|
||||
{
|
||||
destination.IsOwner = destination.OwnerId == _contextProvider.UserId;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,22 @@
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
/// <see cref="MyOffice.Data.Models.Accounts.AccountAccessInvite"/>
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
|
||||
using Core.Attributes;
|
||||
using AutoMapper;
|
||||
using Data.Models.Accounts;
|
||||
|
||||
[Link(typeof(AccountAccessInvite))]
|
||||
public class AccountAccessInviteDto
|
||||
{
|
||||
public string Id { get; set; } = null!;
|
||||
public string Account { get; set; } = null!;
|
||||
public bool IsAllowWrite { get; set; }
|
||||
}
|
||||
|
||||
public class AccountAccessInviteDtoProfile: Profile
|
||||
{
|
||||
public AccountAccessInviteDtoProfile()
|
||||
{
|
||||
CreateMap<AccountAccessInvite, AccountAccessInviteDto>()
|
||||
.ForMember(x => x.Account, o => o.MapFrom(x => x.Account!.Name))
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,19 @@
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
/// <see cref="MyOffice.Data.Models.Accounts.AccountAccountCategory"/>
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
|
||||
using AutoMapper;
|
||||
using MyOffice.Data.Models.Accounts;
|
||||
|
||||
public class AccountAccountCategoryDto
|
||||
{
|
||||
public Guid CategoryId { get; set; }
|
||||
public AccountCategoryDto? Category { get; set; } = null!;
|
||||
}
|
||||
|
||||
public class AccountAccountCategoryDtoProfile: Profile
|
||||
{
|
||||
public AccountAccountCategoryDtoProfile()
|
||||
{
|
||||
CreateMap<AccountAccountCategory, AccountAccountCategoryDto>();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
/// <see cref="MyOffice.Data.Models.Accounts.AccountCategory"/>
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
|
||||
using AutoMapper;
|
||||
using MyOffice.Data.Models.Accounts;
|
||||
|
||||
public class AccountCategoryDto
|
||||
{
|
||||
@@ -6,4 +10,15 @@ public class AccountCategoryDto
|
||||
public Guid UserId { get; set; }
|
||||
public string Name { get; set; } = null!;
|
||||
public bool AllowDelete { get; set; }
|
||||
}
|
||||
|
||||
public class AccountCategoryDtoProfile: Profile
|
||||
{
|
||||
public AccountCategoryDtoProfile()
|
||||
{
|
||||
CreateMap<AccountCategory, AccountCategoryDto>()
|
||||
.ForMember(x => x.Id, o => o.MapFrom(x => x.Id))
|
||||
.ForMember(x => x.AllowDelete, o => o.MapFrom(x => !x.Accounts!.Any()))
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,22 @@
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
/// <see cref="MyOffice.Data.Models.Accounts.Account"/>
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
|
||||
public class AccountDetailedDto
|
||||
using AutoMapper;
|
||||
using MyOffice.Core;
|
||||
using MyOffice.Data.Models.Accounts;
|
||||
|
||||
public class AccountDetailedDto: IDataModelDto<AccountDetailed>
|
||||
{
|
||||
public AccountDto Account { get; set; } = null!;
|
||||
public decimal TotalPlus { get; set; }
|
||||
public decimal TotalMinus { get; set; }
|
||||
public decimal Rest => TotalPlus - TotalMinus;
|
||||
}
|
||||
|
||||
public class AccountDetailedDtoProfile: Profile
|
||||
{
|
||||
public AccountDetailedDtoProfile()
|
||||
{
|
||||
CreateMap<AccountDetailed, AccountDetailedDto>();
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,79 @@
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
|
||||
using MyOffice.Data.Models.Currencies;
|
||||
using System;
|
||||
using Data.Models.Accounts;
|
||||
using MyOffice.Services.Currency.Domain;
|
||||
using AutoMapper;
|
||||
using MyOffice.Services.Identity;
|
||||
using MyOffice.Core;
|
||||
using MyOffice.Services.Mapper;
|
||||
|
||||
public class AccountDto
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false)]
|
||||
public class GenerateMappedDtoAttribute: Attribute
|
||||
{
|
||||
public GenerateMappedDtoAttribute()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[GenerateMappedDto]
|
||||
public class AccountDto : IDataModelDto<Account>
|
||||
{
|
||||
#region Account properties
|
||||
|
||||
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 CurrencyGlobalDto? CurrencyGlobal { get; set; }
|
||||
public string Name { get; set; } = null!;
|
||||
public Guid OwnerId { get; set; }
|
||||
public UserDto? Owner { get; set; }
|
||||
public string Name { get; set; } = null!;
|
||||
public bool HasMotions { get; set; }
|
||||
|
||||
#endregion Account properties
|
||||
|
||||
#region Dto properties
|
||||
|
||||
public Guid CurrencyId { get; set; }
|
||||
public CurrencyDto? Currency { get; set; }
|
||||
public string Type { get; set; } = null!;
|
||||
public List<AccountAccessDto>? AccessRights { get; set; }
|
||||
public List<AccountAccountCategoryDto>? Categories { get; set; }
|
||||
|
||||
public bool HasMotions { get; set; }
|
||||
|
||||
public Guid CurrentUserId { get; set; }
|
||||
public AccountAccess? AccountAccess { get; set; }
|
||||
#endregion Dto properties
|
||||
|
||||
#region Permissions
|
||||
|
||||
public List<AccountAccessDto>? AccessRights { get; set; }
|
||||
public bool AllowRead { get; set; }
|
||||
public bool AllowWrite { get; set; }
|
||||
public bool AllowDelete { get; set; }
|
||||
public bool AllowManage { get; set; }
|
||||
|
||||
#endregion Permissions
|
||||
}
|
||||
|
||||
public class AccountDtoProfile : BaseProfile<Account, AccountDto>
|
||||
{
|
||||
public AccountDtoProfile()
|
||||
{
|
||||
Mapping
|
||||
.ForMember(x => x.HasMotions, o => o.MapFrom(x => x.Motions!.Any()))
|
||||
.AfterMap<AccountDtoMappingAction>();
|
||||
}
|
||||
}
|
||||
|
||||
public class AccountDtoMappingAction : BaseMappingAction, IMappingAction<Account, AccountDto>
|
||||
{
|
||||
public AccountDtoMappingAction(IContextProvider contextProvider) : base(contextProvider) { }
|
||||
|
||||
public void Process(Account source, AccountDto destination, ResolutionContext context)
|
||||
{
|
||||
var accessRight = destination.AccessRights?.FirstOrDefault(x => x.UserId == ContextProvider.UserId);
|
||||
destination.AllowRead = accessRight?.IsAllowRead ?? false;
|
||||
destination.AllowWrite = accessRight?.IsAllowWrite ?? false;
|
||||
destination.AllowManage = accessRight?.IsAllowManage ?? false;
|
||||
destination.AllowDelete = (accessRight?.IsOwner ?? false) && !destination.HasMotions;
|
||||
destination.Name = accessRight?.Name ?? destination.Name;
|
||||
destination.Type = accessRight?.Name ?? destination.Type;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,23 @@
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
/// <see cref="MyOffice.Data.Models.Items.ItemCategory"/>
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
|
||||
using MyOffice.Data.Models.Users;
|
||||
using AutoMapper;
|
||||
using MyOffice.Data.Models.Items;
|
||||
|
||||
public class ItemCategoryDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public User User { get; set; } = null!;
|
||||
public UserDto User { get; set; } = null!;
|
||||
public string Name { get; set; } = null!;
|
||||
public List<ItemDto> Items { get; set; } = null!;
|
||||
public bool IsInternal { get; set; }
|
||||
}
|
||||
|
||||
public class ItemCategoryDtoProfile: Profile
|
||||
{
|
||||
public ItemCategoryDtoProfile()
|
||||
{
|
||||
CreateMap<ItemCategory, ItemCategoryDto>();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
/// <see cref="MyOffice.Data.Models.Items.Item"/>
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
|
||||
using AutoMapper;
|
||||
using MyOffice.Data.Models.Items;
|
||||
|
||||
public class ItemDto
|
||||
@@ -11,3 +13,15 @@ public class ItemDto
|
||||
public Guid CategoryId { get; set; }
|
||||
public ItemCategoryDto? Category { get; set; }
|
||||
}
|
||||
|
||||
public class ItemDtoProfile: Profile
|
||||
{
|
||||
public ItemDtoProfile()
|
||||
{
|
||||
CreateMap<Item, ItemDto>()
|
||||
.ForMember(x => x.Id, o => o.MapFrom(x => x.ItemGlobalId))
|
||||
.ForMember(x => x.Name, o => o.MapFrom(x => x.ItemGlobal.Name))
|
||||
.ForMember(x => x.AllowDelete, o => o.MapFrom(x => !x.Motions!.Any()))
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,22 @@
|
||||
namespace MyOffice.Services.Account.Domain
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
|
||||
using AutoMapper;
|
||||
|
||||
public class MotionAddUpdate
|
||||
{
|
||||
public class MotionAddUpdate
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
public string Item { get; set; } = null!;
|
||||
public string? ItemId { get; set; } = null!;
|
||||
public string? AccountId { get; set; } = null!;
|
||||
public string? Description { get; set; }
|
||||
public decimal Plus { get; set; }
|
||||
public decimal Minus { get; set; }
|
||||
public decimal AmountBalancing { get; set; }
|
||||
}
|
||||
public DateTime Date { get; set; }
|
||||
public string Item { get; set; } = null!;
|
||||
public string? ItemId { get; set; } = null!;
|
||||
public string? AccountId { get; set; } = null!;
|
||||
public string? Description { get; set; }
|
||||
public decimal Plus { get; set; }
|
||||
public decimal Minus { get; set; }
|
||||
public decimal AmountBalancing { get; set; }
|
||||
}
|
||||
|
||||
public class MotionAddUpdateProfile: Profile
|
||||
{
|
||||
public MotionAddUpdateProfile()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
|
||||
using AutoMapper;
|
||||
using MyOffice.Data.Models.Accounts;
|
||||
|
||||
public class MotionDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
@@ -13,4 +16,12 @@ public class MotionDto
|
||||
public decimal AmountPlus { get; set; }
|
||||
public decimal AmountMinus { get; set; }
|
||||
public DateTime? DeletedOn { get; set; }
|
||||
}
|
||||
|
||||
public class MotionDtoProfile: Profile
|
||||
{
|
||||
public MotionDtoProfile()
|
||||
{
|
||||
CreateMap<Motion, MotionDto>();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
/// <see cref="MyOffice.Data.Models.Users.User"/>
|
||||
namespace MyOffice.Services.Account.Domain;
|
||||
|
||||
using Data.Models.Currencies;
|
||||
using AutoMapper;
|
||||
using MyOffice.Data.Models.Users;
|
||||
using MyOffice.Services.Currency.Domain;
|
||||
|
||||
public class UserDto
|
||||
{
|
||||
@@ -13,5 +16,13 @@ public class UserDto
|
||||
public string? Phone { get; set; }
|
||||
|
||||
public string CurrencyId { get; set; } = null!;
|
||||
public CurrencyGlobal? Currency { get; set; }
|
||||
public CurrencyGlobalDto? Currency { get; set; }
|
||||
}
|
||||
|
||||
public class UserDtoProfile : Profile
|
||||
{
|
||||
public UserDtoProfile()
|
||||
{
|
||||
CreateMap<User, UserDto>();
|
||||
}
|
||||
}
|
||||
@@ -80,8 +80,8 @@ public class CurrencyService
|
||||
}
|
||||
|
||||
public Exec<CurrencyDto, CurrencyEditStatus> CurrencyUpdate(
|
||||
Guid userId,
|
||||
Guid currencyId,
|
||||
Guid userId,
|
||||
Guid currencyId,
|
||||
CurrencyEdit currency
|
||||
)
|
||||
{
|
||||
@@ -163,4 +163,22 @@ public class CurrencyService
|
||||
|
||||
return result.Set(_mapper.Map<CurrencyRateDto>(rate));
|
||||
}
|
||||
|
||||
public Exec<CurrencyDto, GeneralExecStatus> Remove(Guid userId, Guid id)
|
||||
{
|
||||
var result = new Exec<CurrencyDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var currency = _currencyRepository.Get(userId, id);
|
||||
if (currency == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
if (!_currencyRepository.Remove(currency))
|
||||
{
|
||||
return result.Set(GeneralExecStatus.failure);
|
||||
}
|
||||
|
||||
return result.Set(_mapper.Map<CurrencyDto>(currency));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,32 @@
|
||||
namespace MyOffice.Services.Currency.Domain;
|
||||
/// <see cref="MyOffice.Data.Models.Currencies.Currency"/>
|
||||
namespace MyOffice.Services.Currency.Domain;
|
||||
|
||||
using AutoMapper;
|
||||
using MyOffice.Data.Models.Currencies;
|
||||
using MyOffice.Data.Models.Users;
|
||||
using MyOffice.Services.Account.Domain;
|
||||
|
||||
public class CurrencyDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string CurrencyGlobalId { get; set; } = null!;
|
||||
public CurrencyGlobal? CurrencyGlobal { get; set; }
|
||||
public CurrencyGlobalDto? CurrencyGlobal { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public User? User { get; set; }
|
||||
public UserDto? User { get; set; }
|
||||
|
||||
public string Name { get; set; } = null!;
|
||||
public string ShortName { get; set; } = null!;
|
||||
public IEnumerable<CurrencyRate>? Rates { get; set; }
|
||||
public List<CurrencyRateDto>? Rates { get; set; }
|
||||
|
||||
public int? CurrentRateId { get; set; }
|
||||
public CurrencyRate? CurrentRate { get; set; }
|
||||
public CurrencyRateDto? CurrentRate { get; set; }
|
||||
|
||||
public bool IsPrimary { get; set; }
|
||||
}
|
||||
|
||||
public class CurrencyDtoProfile: Profile
|
||||
{
|
||||
public CurrencyDtoProfile()
|
||||
{
|
||||
CreateMap<Currency, CurrencyDto>();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
namespace MyOffice.Services.Currency.Domain;
|
||||
/// <see cref="MyOffice.Data.Models.Currencies.CurrencyGlobal"/>
|
||||
namespace MyOffice.Services.Currency.Domain;
|
||||
|
||||
using AutoMapper;
|
||||
using MyOffice.Data.Models.Currencies;
|
||||
|
||||
public class CurrencyGlobalDto
|
||||
{
|
||||
@@ -7,3 +11,11 @@ public class CurrencyGlobalDto
|
||||
public string Symbol { get; set; } = null!;
|
||||
public int DefaultQuantity { get; set; }
|
||||
}
|
||||
|
||||
public class CurrencyGlobalDtoProfile: Profile
|
||||
{
|
||||
public CurrencyGlobalDtoProfile()
|
||||
{
|
||||
CreateMap<CurrencyGlobal, CurrencyGlobalDto>();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
namespace MyOffice.Services.Currency.Domain;
|
||||
/// <see cref="MyOffice.Data.Models.Currencies.CurrencyRate"/>
|
||||
namespace MyOffice.Services.Currency.Domain;
|
||||
|
||||
using AutoMapper;
|
||||
using MyOffice.Data.Models.Currencies;
|
||||
|
||||
public class CurrencyRateDto
|
||||
{
|
||||
@@ -8,5 +12,13 @@ public class CurrencyRateDto
|
||||
public DateTime DateTime { get; set; }
|
||||
public int Quantity { get; set; }
|
||||
public decimal Rate { get; set; }
|
||||
public IEnumerable<CurrencyDto>? Currencies { get; set; }
|
||||
public List<CurrencyDto>? Currencies { get; set; }
|
||||
}
|
||||
|
||||
public class CurrencyRateDtoProfile : Profile
|
||||
{
|
||||
public CurrencyRateDtoProfile()
|
||||
{
|
||||
CreateMap<CurrencyRate, CurrencyRateDto>();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
namespace MyOffice.Services.Currency.Domain;
|
||||
|
||||
using MyOffice.Data.Models.Currencies;
|
||||
|
||||
public class CurrencyWithRateDto
|
||||
{
|
||||
public CurrencyDto Currency { get; set; } = null!;
|
||||
public CurrencyRateDto? Rate { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ using Core.Extensions;
|
||||
using Data.Repositories.Account;
|
||||
using Data.Repositories.Currency;
|
||||
using MyOffice.Data.Models.Accounts;
|
||||
using System.Xml.Linq;
|
||||
|
||||
public class DashboardService
|
||||
{
|
||||
@@ -52,8 +53,8 @@ public class DashboardService
|
||||
Id = x.Id,
|
||||
Name = x.Name,
|
||||
Balance = x.Balance,
|
||||
CurrencyName = x.CurrencyName,
|
||||
CurrencyShortName = x.CurrencyShortName,
|
||||
CurrencyName = x.CurrencyName!,
|
||||
CurrencyShortName = x.CurrencyShortName!,
|
||||
CurrencyRate = x.CurrencyRate,
|
||||
CurrencyQuantity = x.CurrencyQuantity,
|
||||
})
|
||||
@@ -70,14 +71,64 @@ public class DashboardService
|
||||
? _accountRepository.GetIncomeByCategory(userId, category.Value, from.ToUtc(), to.ToUtc())
|
||||
: _accountRepository.GetIncomeByCategories(userId, from.ToUtc(), to.ToUtc());
|
||||
|
||||
data = data
|
||||
.Where(x => x.Amount != 0)
|
||||
.ToList();
|
||||
|
||||
var currencies = data
|
||||
.Select(x => x.CurrencyId)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
var rates = _currencyRateRepository
|
||||
.GetLastRates(userId, currencies, to.ToUtc())
|
||||
.ToDictionary(x => x.Key, x => x.Value.Rate * x.Value.Quantity);
|
||||
|
||||
return new DashboardIncomeData
|
||||
{
|
||||
Data = data.Select(x => new DashboardIncomeDataItem
|
||||
Data = data.Select(x => new
|
||||
{
|
||||
Id = x.Id?.ToShort(),
|
||||
Id = x.Id.ToShort(),
|
||||
Name = x.Name,
|
||||
Value = x.Amount,
|
||||
}).ToList()
|
||||
ValueRaw = x.Amount,
|
||||
Value = (x.Amount * rates.FirstOrDefault(r => r.Key == x.CurrencyId).Value),
|
||||
})
|
||||
.GroupBy(x => new
|
||||
{
|
||||
x.Id,
|
||||
x.Name,
|
||||
})
|
||||
.Select(x => new DashboardIncomeDataItem
|
||||
{
|
||||
Id = x.Key.Id,
|
||||
Name = x.Key.Name,
|
||||
Value = x.Sum(s => s.Value),
|
||||
ValueRaw = x.Sum(s => s.ValueRaw),
|
||||
})
|
||||
.OrderBy(x => x.Name)
|
||||
.ToList(),
|
||||
|
||||
Details = data.Select(x => new
|
||||
{
|
||||
Id = x.CurrencyId,
|
||||
Name = x.CurrencyName,
|
||||
ValueRaw = x.Amount,
|
||||
Value = (x.Amount * rates.FirstOrDefault(r => r.Key == x.CurrencyId).Value),
|
||||
})
|
||||
.GroupBy(x => new
|
||||
{
|
||||
x.Id,
|
||||
x.Name,
|
||||
})
|
||||
.Select(x => new DashboardIncomeDataItem
|
||||
{
|
||||
Id = x.Key.Id,
|
||||
Name = x.Key.Name,
|
||||
Value = x.Sum(s => s.Value),
|
||||
ValueRaw = x.Sum(s => s.ValueRaw),
|
||||
})
|
||||
.OrderBy(x => x.Name)
|
||||
.ToList(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -87,14 +138,64 @@ public class DashboardService
|
||||
? _accountRepository.GetOutcomeByCategory(userId, category.Value, from.ToUtc(), to.ToUtc())
|
||||
: _accountRepository.GetOutcomeByCategories(userId, from.ToUtc(), to.ToUtc());
|
||||
|
||||
data = data
|
||||
.Where(x => x.Amount != 0)
|
||||
.ToList();
|
||||
|
||||
var currencies = data
|
||||
.Select(x => x.CurrencyId)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
var rates = _currencyRateRepository
|
||||
.GetLastRates(userId, currencies, to.ToUtc())
|
||||
.ToDictionary(x => x.Key, x => x.Value.Rate * x.Value.Quantity);
|
||||
|
||||
return new DashboardIncomeData
|
||||
{
|
||||
Data = data.Select(x => new DashboardIncomeDataItem
|
||||
{
|
||||
Id = x.Id?.ToShort(),
|
||||
Name = x.Name,
|
||||
Value = x.Amount,
|
||||
}).ToList()
|
||||
Data = data.Select(x => new
|
||||
{
|
||||
Id = x.Id.ToShort(),
|
||||
Name = x.Name,
|
||||
ValueRaw = x.Amount,
|
||||
Value = (x.Amount * rates.FirstOrDefault(r => r.Key == x.CurrencyId).Value),
|
||||
})
|
||||
.GroupBy(x => new
|
||||
{
|
||||
x.Id,
|
||||
x.Name,
|
||||
})
|
||||
.Select(x => new DashboardIncomeDataItem
|
||||
{
|
||||
Id = x.Key.Id,
|
||||
Name = x.Key.Name,
|
||||
Value = x.Sum(s => s.Value),
|
||||
ValueRaw = x.Sum(s => s.ValueRaw),
|
||||
})
|
||||
.OrderBy(x => x.Name)
|
||||
.ToList(),
|
||||
|
||||
Details = data.Select(x => new
|
||||
{
|
||||
Id = x.CurrencyId,
|
||||
Name = x.CurrencyName,
|
||||
ValueRaw = x.Amount,
|
||||
Value = (x.Amount * rates.FirstOrDefault(r => r.Key == x.CurrencyId).Value),
|
||||
})
|
||||
.GroupBy(x => new
|
||||
{
|
||||
x.Id,
|
||||
x.Name,
|
||||
})
|
||||
.Select(x => new DashboardIncomeDataItem
|
||||
{
|
||||
Id = x.Key.Id,
|
||||
Name = x.Key.Name,
|
||||
Value = x.Sum(s => s.Value),
|
||||
ValueRaw = x.Sum(s => s.ValueRaw),
|
||||
})
|
||||
.OrderBy(x => x.Name)
|
||||
.ToList(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
namespace MyOffice.Services.Dashboard.Domain;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using Data.Models.Accounts;
|
||||
|
||||
public class DashboardData
|
||||
{
|
||||
@@ -32,11 +30,14 @@ public class DashboardRestData
|
||||
public class DashboardIncomeData
|
||||
{
|
||||
public List<DashboardIncomeDataItem> Data { get; set; } = null!;
|
||||
public List<DashboardIncomeDataItem> Details { get; set; } = null!;
|
||||
}
|
||||
|
||||
public class DashboardIncomeDataItem
|
||||
{
|
||||
public string? Id { get; set; } = null!;
|
||||
public string? Id { get; set; }
|
||||
public string Currency { get; set; } = null!;
|
||||
public string Name { get; set; } = null!;
|
||||
public decimal Value { get; set; }
|
||||
public decimal ValueRaw { get; set; }
|
||||
}
|
||||
@@ -30,7 +30,6 @@ public class ItemService
|
||||
_itemRepository = itemRepository;
|
||||
_itemGlobalRepository = itemGlobalRepository;
|
||||
_mapper = mapper;
|
||||
|
||||
}
|
||||
|
||||
public List<ItemCategoryDto> GetAllCategories(Guid userId)
|
||||
@@ -130,6 +129,17 @@ public class ItemService
|
||||
return _mapper.Map<List<ItemDto>>(_itemRepository.GetByCategory(userId, categoryId));
|
||||
}
|
||||
|
||||
public List<ItemDto> GetByUncategorized(Guid userId)
|
||||
{
|
||||
var itemGlobals = _itemGlobalRepository.GetAvailableToUser(userId);
|
||||
foreach (var itemGlobal in itemGlobals)
|
||||
{
|
||||
GetOrCreate(userId, itemGlobal);
|
||||
}
|
||||
|
||||
return GetByCategory(userId, userId);
|
||||
}
|
||||
|
||||
public Exec<ItemDto, GeneralExecStatus> Update(Guid userId, Guid motionId, Guid categoryId)
|
||||
{
|
||||
var result = new Exec<ItemDto, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
@@ -204,4 +214,25 @@ public class ItemService
|
||||
|
||||
return _mapper.Map<List<ItemDto>>(_itemRepository.Find(userId, term, limit));
|
||||
}
|
||||
|
||||
public GeneralExecStatus UpdateItemsCategory(Guid userId, Guid categoryId, List<Guid> items)
|
||||
{
|
||||
var category = _itemCategoryRepository.Get(userId, categoryId);
|
||||
if (category == null)
|
||||
{
|
||||
return GeneralExecStatus.not_found;
|
||||
}
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
var dbItem = _itemRepository.GetByGlobal(userId, item);
|
||||
if (dbItem != null)
|
||||
{
|
||||
dbItem.CategoryId = category.Id;
|
||||
_itemRepository.Update(dbItem);
|
||||
}
|
||||
}
|
||||
|
||||
return GeneralExecStatus.success;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
namespace MyOffice.Services.Mapper;
|
||||
|
||||
using Account.Domain;
|
||||
using AutoMapper;
|
||||
using Data.Models.Accounts;
|
||||
using Data.Models.Currencies;
|
||||
using Data.Models.Items;
|
||||
using Data.Models.Users;
|
||||
using MyOffice.Services.Currency.Domain;
|
||||
|
||||
public class AccountServiceProfile : Profile
|
||||
{
|
||||
public AccountServiceProfile()
|
||||
{
|
||||
MapUser();
|
||||
|
||||
MapAccount();
|
||||
|
||||
MapCurrency();
|
||||
|
||||
MapItems();
|
||||
|
||||
CreateMap<Motion, MotionDto>();
|
||||
}
|
||||
|
||||
private void MapUser()
|
||||
{
|
||||
CreateMap<User, UserDto>();
|
||||
}
|
||||
|
||||
private void MapAccount()
|
||||
{
|
||||
CreateMap<Account, AccountDto>()
|
||||
.ForMember(x => x.HasMotions, o => o.MapFrom(x => x.Motions!.Any()))
|
||||
.ForMember(x => x.CurrentUserId, o => o.MapFrom<UserIdResolver>())
|
||||
.ForMember(x => x.AccountAccess, o =>
|
||||
{
|
||||
o.MapFrom((src, dst) => src.AccessRights!.FirstOrDefault(x => x.UserId == dst.CurrentUserId));
|
||||
})
|
||||
.ForMember(x => x.Type, o =>
|
||||
{
|
||||
o.SetMappingOrder(1);
|
||||
o.MapFrom((src, dst) => dst.AccountAccess?.Type.ToString());
|
||||
})
|
||||
.ForMember(x => x.Name, o =>
|
||||
{
|
||||
o.SetMappingOrder(1);
|
||||
o.MapFrom((src, dst) => dst.AccountAccess?.Name ?? src.Name);
|
||||
})
|
||||
;
|
||||
|
||||
CreateMap<AccountDetailed, AccountDetailedDto>();
|
||||
|
||||
CreateMap<AccountAccess, AccountAccessDto>();
|
||||
|
||||
CreateMap<AccountAccountCategory, AccountAccountCategoryDto>();
|
||||
|
||||
CreateMap<AccountCategory, AccountCategoryDto>()
|
||||
.ForMember(x => x.Id, o => o.MapFrom(x => x.Id))
|
||||
.ForMember(x => x.AllowDelete, o => o.MapFrom(x => !x.Accounts!.Any()))
|
||||
;
|
||||
|
||||
CreateMap<AccountAccessInvite, AccountAccessInviteDto>()
|
||||
.ForMember(x => x.Account, o => o.MapFrom(x => x.Account!.Name))
|
||||
;
|
||||
}
|
||||
|
||||
private void MapCurrency()
|
||||
{
|
||||
CreateMap<CurrencyGlobal, CurrencyGlobalDto>();
|
||||
|
||||
CreateMap<Currency, CurrencyDto>();
|
||||
|
||||
CreateMap<CurrencyRate, CurrencyRateDto>();
|
||||
}
|
||||
|
||||
private void MapItems()
|
||||
{
|
||||
CreateMap<ItemCategory, ItemCategoryDto>();
|
||||
|
||||
CreateMap<Item, ItemDto>()
|
||||
.ForMember(x => x.Id, o => o.MapFrom(x => x.ItemGlobalId))
|
||||
.ForMember(x => x.Name, o => o.MapFrom(x => x.ItemGlobal.Name))
|
||||
.ForMember(x => x.AllowDelete, o => o.MapFrom(x => !x.Motions!.Any()))
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using AutoMapper;
|
||||
using MyOffice.Core;
|
||||
|
||||
namespace MyOffice.Services;
|
||||
|
||||
public static class AutomapperExtensions
|
||||
{
|
||||
public static List<TTo> ToDto<TTo>(this IEnumerable<IDataModel> list, IMapper mapper)
|
||||
{
|
||||
return mapper.Map<List<TTo>>(list);
|
||||
}
|
||||
|
||||
public static TTo ToDto<TTo>(this IDataModel item, IMapper mapper)
|
||||
{
|
||||
return mapper.Map<TTo>(item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using MyOffice.Services.Identity;
|
||||
|
||||
namespace MyOffice.Services.Mapper;
|
||||
|
||||
public class BaseMappingAction
|
||||
{
|
||||
protected readonly IContextProvider ContextProvider;
|
||||
public BaseMappingAction(IContextProvider contextProvider)
|
||||
{
|
||||
ContextProvider = contextProvider;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using AutoMapper;
|
||||
|
||||
namespace MyOffice.Services.Mapper;
|
||||
|
||||
public class BaseProfile<TSource, TDestination> : Profile
|
||||
{
|
||||
protected IMappingExpression<TSource, TDestination> Mapping;
|
||||
|
||||
public BaseProfile()
|
||||
{
|
||||
Mapping = CreateMap<TSource, TDestination>();
|
||||
}
|
||||
}
|
||||
@@ -14,5 +14,4 @@
|
||||
<ProjectReference Include="..\MyOffice.Core\MyOffice.Core.csproj" />
|
||||
<ProjectReference Include="..\MyOffice.Data.Repositories\MyOffice.Data.Repositories.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
namespace MyOffice.Services.Notifications;
|
||||
|
||||
using MyOffice.Core;
|
||||
using MyOffice.Data.Models.Notifications;
|
||||
using MyOffice.Data.Models.Users;
|
||||
using MyOffice.Data.Models.Verifications;
|
||||
using MyOffice.Data.Repositories.Item;
|
||||
using MyOffice.Services.Verifications;
|
||||
|
||||
public class EmailNotificationService
|
||||
{
|
||||
private readonly VerificationService _verificationService;
|
||||
|
||||
public EmailNotificationService(
|
||||
VerificationService verificationService
|
||||
)
|
||||
{
|
||||
_verificationService = verificationService;
|
||||
}
|
||||
|
||||
public void PasswordResetEmail(User user)
|
||||
{
|
||||
var code = _verificationService.Add(
|
||||
user,
|
||||
user.Email,
|
||||
VerificationCodeTemplateEnum.password_restore,
|
||||
VerificationCodeTypeEnum.email
|
||||
);
|
||||
|
||||
var subject = "";
|
||||
var body = "";
|
||||
}
|
||||
}
|
||||
|
||||
public class TemplateSevice
|
||||
{
|
||||
private readonly IEmailTemplateRepository _emailTemplateRepository;
|
||||
|
||||
public TemplateSevice(
|
||||
IEmailTemplateRepository emailTemplateRepository
|
||||
)
|
||||
{
|
||||
_emailTemplateRepository = emailTemplateRepository;
|
||||
}
|
||||
|
||||
public Exec<EmailTemplateFormated, GeneralExecStatus> GetTemplate(
|
||||
EmailTemplateEnum template,
|
||||
Dictionary<string, string> tokens
|
||||
)
|
||||
{
|
||||
var result = new Exec<EmailTemplateFormated, GeneralExecStatus>(GeneralExecStatus.success);
|
||||
|
||||
var emailTemplate = _emailTemplateRepository.Get(template);
|
||||
if (emailTemplate == null)
|
||||
{
|
||||
return result.Set(GeneralExecStatus.not_found);
|
||||
}
|
||||
|
||||
result.Result = new EmailTemplateFormated
|
||||
{
|
||||
Subject = emailTemplate.Subject
|
||||
Body = emailTemplate.Template,
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class EmailTemplateFormated
|
||||
{
|
||||
public string Sender { get; set; }
|
||||
public string SenderName { get; set; }
|
||||
public string Subject { get; set; }
|
||||
public string Body { get; set; }
|
||||
}
|
||||
|
||||
public interface IEmailSender
|
||||
{
|
||||
//Exec<bool, GeneralExecStatus> Send(string from, string[] to, string subject, string body);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
namespace MyOffice.Services.Verifications;
|
||||
|
||||
using MyOffice.Core.Helpers;
|
||||
using MyOffice.Data.Models.Users;
|
||||
using MyOffice.Data.Models.Verifications;
|
||||
using MyOffice.Data.Repositories.Item;
|
||||
|
||||
public class VerificationService
|
||||
{
|
||||
private readonly TimeSpan _defaultExpires = TimeSpan.FromDays(1);
|
||||
|
||||
private readonly IVerificationCodeRepository _verificationCodeRepository;
|
||||
|
||||
public VerificationService(
|
||||
IVerificationCodeRepository verificationCodeRepository
|
||||
)
|
||||
{
|
||||
_verificationCodeRepository = verificationCodeRepository;
|
||||
}
|
||||
|
||||
public VerificationCode Add(
|
||||
User user,
|
||||
string destination,
|
||||
VerificationCodeTemplateEnum template,
|
||||
VerificationCodeTypeEnum type,
|
||||
DateTime? expiresOn = null,
|
||||
string? metadata = null
|
||||
)
|
||||
{
|
||||
if (user == null)
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
if (destination == null)
|
||||
throw new ArgumentNullException(nameof(destination));
|
||||
|
||||
var verificationCode = new VerificationCode
|
||||
{
|
||||
UserId = user.Id,
|
||||
Code = RandomizationHelper.Generate(40),
|
||||
CreatedOn = DateTime.UtcNow,
|
||||
ExpiresOn = expiresOn ?? DateTime.UtcNow.Add(_defaultExpires),
|
||||
Template = template.ToString(),
|
||||
DestinationType = type.ToString(),
|
||||
Destination = destination,
|
||||
Metadata = metadata,
|
||||
};
|
||||
|
||||
_verificationCodeRepository.Add(verificationCode);
|
||||
|
||||
return verificationCode;
|
||||
}
|
||||
}
|
||||
@@ -9,13 +9,13 @@ using Microsoft.Extensions.Logging;
|
||||
using Models.Account;
|
||||
using Models.Item;
|
||||
using Models.Motion;
|
||||
using MyOffice.Web.Infrastructure.Attributes;
|
||||
using Services.Account;
|
||||
using Services.Account.Domain;
|
||||
using Services.Item;
|
||||
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
[DefaultFromBody]
|
||||
public class AccountController : BaseApiController
|
||||
{
|
||||
private readonly ILogger<AccountController> _logger;
|
||||
@@ -36,7 +36,6 @@ public class AccountController : BaseApiController
|
||||
_itemService = itemService;
|
||||
}
|
||||
|
||||
[HttpGet("~/api/accounts")]
|
||||
public ObjectResult AccountsGet(string category)
|
||||
{
|
||||
var list = _accountService.GetByCategoryDetailed(UserId, category!.AsGuid());
|
||||
@@ -44,7 +43,6 @@ public class AccountController : BaseApiController
|
||||
return OkResponse(_mapper.Map<List<AccountDetailedViewModel>>(list.OrderBy(x => x.Account.Name).ToList()));
|
||||
}
|
||||
|
||||
[HttpGet("~/api/accounts/{id}")]
|
||||
public ObjectResult AccountGet(string id)
|
||||
{
|
||||
var exec = _accountService.GetByIdDetailed(UserId, id!.AsGuid());
|
||||
@@ -63,7 +61,6 @@ public class AccountController : BaseApiController
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("~/api/accounts/{id}/motions")]
|
||||
public ObjectResult MotionsGet(string id, [FromQuery] MotionsGetRequest request)
|
||||
{
|
||||
var exec = _accountService.GetMotions(UserId, id!.AsGuid(), request.From.StartOfDay(), request.To.EndOfDay());
|
||||
@@ -82,7 +79,6 @@ public class AccountController : BaseApiController
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("~/api/accounts/{id}/motions")]
|
||||
public object MotionsPost(string id, MotionRequest motion)
|
||||
{
|
||||
var exec = _accountService.MotionAdd(UserId, id.AsGuid(), _mapper.Map<MotionAddUpdate>(motion));
|
||||
@@ -101,7 +97,6 @@ public class AccountController : BaseApiController
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut("~/api/accounts/{id}/motions/{motionId}")]
|
||||
public ObjectResult MotionsPut(string id, string motionId, MotionRequest motion)
|
||||
{
|
||||
var exec = _accountService.MotionUpdate(UserId, id.AsGuid(), motionId.AsGuid(), _mapper.Map<MotionAddUpdate>(motion));
|
||||
@@ -120,7 +115,6 @@ public class AccountController : BaseApiController
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("~/api/accounts/{id}/motions/{motionId}")]
|
||||
public ObjectResult MotionsDelete(string id, string motionId)
|
||||
{
|
||||
var exec = _accountService.MotionRemove(UserId, id.AsGuid(), motionId.AsGuid());
|
||||
@@ -139,7 +133,6 @@ public class AccountController : BaseApiController
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("~/api/items")]
|
||||
public ObjectResult FindItems(string term)
|
||||
{
|
||||
var itemsDto = _itemService.FindItems(UserId, term);
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
namespace MyOffice.Web.Controllers;
|
||||
|
||||
using System.Security.Authentication;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Core.Extensions;
|
||||
using IdentityModel;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MyOffice.Web.Infrastructure.Attributes;
|
||||
using MyOffice.Web.Models;
|
||||
using static IdentityServer4.Models.IdentityResources;
|
||||
|
||||
[DefaultFromBody]
|
||||
public class BaseApiController : ControllerBase
|
||||
{
|
||||
public Guid UserId
|
||||
|
||||
@@ -1,51 +1,52 @@
|
||||
namespace MyOffice.Web.Controllers;
|
||||
|
||||
using AutoMapper;
|
||||
using Core.Extensions;
|
||||
using Infrastructure.Attributes;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MyOffice.Web.Models.Dashboard;
|
||||
using Services.Dashboard;
|
||||
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
[DefaultFromBody]
|
||||
public class DashboardController : BaseApiController
|
||||
{
|
||||
private readonly ILogger<DashboardController> _logger;
|
||||
private readonly DashboardService _dashboardService;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public DashboardController(
|
||||
ILogger<DashboardController> logger,
|
||||
DashboardService dashboardService
|
||||
DashboardService dashboardService,
|
||||
IMapper mapper
|
||||
)
|
||||
{
|
||||
_logger = logger;
|
||||
_dashboardService = dashboardService;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("~/api/dashboard")]
|
||||
public object Index()
|
||||
public ObjectResult Index()
|
||||
{
|
||||
var data = _dashboardService.GetDashboardRestData(UserId);
|
||||
|
||||
return data;
|
||||
return OkResponse(_mapper.Map<DashboardViewModel>(data));
|
||||
}
|
||||
|
||||
[HttpGet("~/api/dashboard/income")]
|
||||
public object Income(DateTime from, DateTime to, [AsGuid(true)] string? category)
|
||||
public ObjectResult Income(DateTime from, DateTime to, [AsGuid(true)] string? category)
|
||||
{
|
||||
var data = _dashboardService.GetDashboardIncomeData(UserId, from.StartOfDay(), to.EndOfDay(), category?.AsGuidNull());
|
||||
|
||||
return data;
|
||||
return OkResponse(_mapper.Map<DashboardIncomeDataViewModel>(data));
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("~/api/dashboard/outcome")]
|
||||
public object Outcome(DateTime from, DateTime to, [AsGuid(true)] string? category)
|
||||
public ObjectResult Outcome(DateTime from, DateTime to, [AsGuid(true)] string? category)
|
||||
{
|
||||
var data = _dashboardService.GetDashboardOutcomeData(UserId, from.StartOfDay(), to.EndOfDay(), category?.AsGuidNull());
|
||||
|
||||
return data;
|
||||
return OkResponse(_mapper.Map<DashboardIncomeDataViewModel>(data));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Models.Currency;
|
||||
using Services.Currency;
|
||||
using MyOffice.Web.Infrastructure.Attributes;
|
||||
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
[DefaultFromBody]
|
||||
public class GeneralController : BaseApiController
|
||||
{
|
||||
private readonly CurrencyService _currencyService;
|
||||
@@ -23,8 +23,7 @@ public class GeneralController : BaseApiController
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
[HttpGet("~/api/general/currencies")]
|
||||
public ObjectResult Get()
|
||||
public ObjectResult GetGlobalCurrencies()
|
||||
{
|
||||
var list = _currencyService.GetGlobalAll();
|
||||
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
namespace MyOffice.Web.Controllers;
|
||||
|
||||
using AutoMapper;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
using Core;
|
||||
using Core.Extensions;
|
||||
using Models.Account;
|
||||
using Services.Account;
|
||||
using Services.Account.Domain;
|
||||
using Infrastructure.Attributes;
|
||||
using Services.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
[Authorize]
|
||||
[DefaultFromBody]
|
||||
public class SettingsAccountCategoryController : BaseApiController
|
||||
{
|
||||
private readonly ILogger<SettingsAccountController> _logger;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly AccountService _accountService;
|
||||
private readonly IContextProvider _contextProvider;
|
||||
|
||||
public SettingsAccountCategoryController(
|
||||
ILogger<SettingsAccountController> logger,
|
||||
IMapper mapper,
|
||||
AccountService accountService,
|
||||
IContextProvider contextProvider
|
||||
)
|
||||
{
|
||||
_logger = logger;
|
||||
_mapper = mapper;
|
||||
_accountService = accountService;
|
||||
_contextProvider = contextProvider;
|
||||
}
|
||||
|
||||
public ObjectResult AccountCategories()
|
||||
{
|
||||
var list = _accountService.GetAllCategories(UserId);
|
||||
|
||||
return OkResponse(_mapper.Map<List<AccountCategoryViewModel>>(list).OrderBy(x => x.Name));
|
||||
}
|
||||
|
||||
public ObjectResult AccountCategory([AsGuid] string id)
|
||||
{
|
||||
var exec = _accountService.GetCategory(UserId, id.AsGuid());
|
||||
|
||||
switch (exec.Status)
|
||||
{
|
||||
case GeneralExecStatus.not_found:
|
||||
case GeneralExecStatus.failure:
|
||||
return ProblemBadResponse("Account category not found.");
|
||||
|
||||
case GeneralExecStatus.success:
|
||||
return OkResponse(_mapper.Map<AccountCategoryViewModel>(exec.Result!));
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectResult AccountCategoriesAdd(AccountCategoryViewModel request)
|
||||
{
|
||||
var exec = _accountService.CategoryAdd(UserId, new AccountCategoryDto { Name = request.Name! });
|
||||
switch (exec.Status)
|
||||
{
|
||||
case GeneralExecStatus.success:
|
||||
return OkResponse(_mapper.Map<AccountCategoryViewModel>(exec.Result!));
|
||||
|
||||
case GeneralExecStatus.failure:
|
||||
case GeneralExecStatus.not_found:
|
||||
return ProblemBadResponse("Adding account category failed.");
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectResult AccountCategoriesUpdate([AsGuid] string id, AccountCategoryViewModel request)
|
||||
{
|
||||
var exec = _accountService.CategoryUpdate(UserId, id.AsGuid(), new AccountCategoryDto { Name = request.Name! });
|
||||
switch (exec.Status)
|
||||
{
|
||||
case GeneralExecStatus.success:
|
||||
return OkResponse(_mapper.Map<AccountCategoryViewModel>(exec.Result!));
|
||||
|
||||
case GeneralExecStatus.failure:
|
||||
case GeneralExecStatus.not_found:
|
||||
return ProblemBadResponse("Update account category failed.");
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectResult AccountCategoriesDelete([AsGuid] string id)
|
||||
{
|
||||
var exec = _accountService.CategoryRemove(UserId, id.AsGuid());
|
||||
switch (exec.Status)
|
||||
{
|
||||
case AccountCategoryRemoveResult.success:
|
||||
return OkResponse(_mapper.Map<AccountCategoryViewModel>(exec.Result!));
|
||||
|
||||
case AccountCategoryRemoveResult.failure:
|
||||
return ProblemBadResponse("Remove account category failed.");
|
||||
case AccountCategoryRemoveResult.not_found:
|
||||
return ProblemBadResponse("Account category not found.");
|
||||
case AccountCategoryRemoveResult.accounts_exists:
|
||||
return ProblemBadResponse("Account category have accounts.");
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,7 @@ using Infrastructure.Attributes;
|
||||
using Services.Identity;
|
||||
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
[DefaultFromBody]
|
||||
public class SettingsAccountController : BaseApiController
|
||||
{
|
||||
private readonly ILogger<SettingsAccountController> _logger;
|
||||
@@ -35,102 +34,16 @@ public class SettingsAccountController : BaseApiController
|
||||
_contextProvider = contextProvider;
|
||||
}
|
||||
|
||||
[HttpGet("~/api/settings/account-categories")]
|
||||
public object AccountCategories()
|
||||
{
|
||||
var list = _accountService.GetAllCategories(UserId);
|
||||
|
||||
return _mapper.Map<AccountCategoryViewModel[]>(list).OrderBy(x => x.Name);
|
||||
}
|
||||
|
||||
[HttpGet("~/api/settings/account-categories/{id}")]
|
||||
public object AccountCategory([AsGuid] string id)
|
||||
{
|
||||
var exec = _accountService.GetCategory(UserId, id.AsGuid());
|
||||
|
||||
switch (exec.Status)
|
||||
{
|
||||
case GeneralExecStatus.not_found:
|
||||
case GeneralExecStatus.failure:
|
||||
return ProblemBadResponse("Account category not found.");
|
||||
|
||||
case GeneralExecStatus.success:
|
||||
return _mapper.Map<AccountCategoryViewModel>(exec.Result!);
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("~/api/settings/account-categories")]
|
||||
public object AccountCategoriesAdd(AccountCategoryViewModel request)
|
||||
{
|
||||
var exec = _accountService.CategoryAdd(UserId, new AccountCategoryDto { Name = request.Name! });
|
||||
switch (exec.Status)
|
||||
{
|
||||
case GeneralExecStatus.success:
|
||||
return exec.Result!;
|
||||
|
||||
case GeneralExecStatus.failure:
|
||||
case GeneralExecStatus.not_found:
|
||||
return ProblemBadResponse("Adding account category failed.");
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut("~/api/settings/account-categories/{id}")]
|
||||
public object AccountCategoriesEdit([AsGuid] string id, AccountCategoryViewModel request)
|
||||
{
|
||||
var exec = _accountService.CategoryUpdate(UserId, id.AsGuid(), new AccountCategoryDto { Name = request.Name! });
|
||||
switch (exec.Status)
|
||||
{
|
||||
case GeneralExecStatus.success:
|
||||
return exec.Result!;
|
||||
|
||||
case GeneralExecStatus.failure:
|
||||
case GeneralExecStatus.not_found:
|
||||
return ProblemBadResponse("Update account category failed.");
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("~/api/settings/account-categories/{id}")]
|
||||
public object AccountCategoriesDelete([AsGuid] string id)
|
||||
{
|
||||
var exec = _accountService.CategoryRemove(UserId, id.AsGuid());
|
||||
switch (exec.Status)
|
||||
{
|
||||
case AccountCategoryRemoveResult.success:
|
||||
return exec.Result!;
|
||||
|
||||
case AccountCategoryRemoveResult.failure:
|
||||
return ProblemBadResponse("Remove account category failed.");
|
||||
case AccountCategoryRemoveResult.not_found:
|
||||
return ProblemBadResponse("Account category not found.");
|
||||
case AccountCategoryRemoveResult.accounts_exists:
|
||||
return ProblemBadResponse("Account category have accounts.");
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("~/api/settings/accounts")]
|
||||
public List<AccountViewModel> AccountsGet([AsGuid(true)] string? category)
|
||||
public ObjectResult AccountsGet([AsGuid(true)] string? category)
|
||||
{
|
||||
var list = category.IsPresent()
|
||||
? _accountService.GetByCategory(UserId, category!.AsGuid())
|
||||
: _accountService.GetAllAccounts(UserId);
|
||||
|
||||
return _mapper.Map<List<AccountViewModel>>(list.OrderBy(x => x.Name));
|
||||
return OkResponse(_mapper.Map<List<AccountViewModel>>(list.OrderBy(x => x.Name)));
|
||||
}
|
||||
|
||||
[HttpPost("~/api/settings/accounts")]
|
||||
public object AccountsAdd(AccountViewModel request)
|
||||
public ObjectResult AccountsAdd(AccountViewModel request)
|
||||
{
|
||||
var exec = _accountService.AccountAdd(UserId, new AccountAdd
|
||||
{
|
||||
@@ -149,16 +62,14 @@ public class SettingsAccountController : BaseApiController
|
||||
case AccountAddStatus.failure:
|
||||
return ProblemBadResponse("Adding account failed.");
|
||||
case AccountAddStatus.success:
|
||||
return exec.Result!;
|
||||
return OkResponse(_mapper.Map<AccountViewModel>(exec.Result!));
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpPut("~/api/settings/accounts/{id}")]
|
||||
public object AccountsAdd([AsGuid] string id, AccountEditRequestModel request)
|
||||
public ObjectResult AccountsUpdate([AsGuid] string id, AccountEditRequestModel request)
|
||||
{
|
||||
var exec = _accountService.AccountUpdate(UserId, id.AsGuid(), new AccountEdit
|
||||
{
|
||||
@@ -180,15 +91,14 @@ public class SettingsAccountController : BaseApiController
|
||||
case AccountEditStatus.failure:
|
||||
return ProblemBadResponse("Adding account failed.");
|
||||
case AccountEditStatus.success:
|
||||
return exec.Result!;
|
||||
return OkResponse(_mapper.Map<AccountViewModel>(exec.Result!));
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("~/api/settings/accounts/{id}")]
|
||||
public object AccountsDelete([AsGuid] string id)
|
||||
public ObjectResult AccountsDelete([AsGuid] string id)
|
||||
{
|
||||
var exec = _accountService.AccountDelete(UserId, id);
|
||||
switch (exec.Status)
|
||||
@@ -196,15 +106,14 @@ public class SettingsAccountController : BaseApiController
|
||||
case GeneralExecStatus.not_found:
|
||||
return ProblemBadResponse("Account not found.");
|
||||
case GeneralExecStatus.success:
|
||||
return exec.Result!;
|
||||
return OkResponse(_mapper.Map<AccountViewModel>(exec.Result!));
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("~/api/settings/accounts/{id}/category/{categoryId}")]
|
||||
public object AccountsCategoryRemove([AsGuid] string id, [AsGuid] string categoryId)
|
||||
public ObjectResult AccountsCategoryDelete([AsGuid] string id, [AsGuid] string categoryId)
|
||||
{
|
||||
var exec = _accountService.AccountCategoryRemove(UserId, id.AsGuid(), categoryId.AsGuid());
|
||||
|
||||
@@ -215,15 +124,14 @@ public class SettingsAccountController : BaseApiController
|
||||
return ProblemBadResponse("Category not found.");
|
||||
|
||||
case GeneralExecStatus.success:
|
||||
return exec.Result!;
|
||||
return OkResponse(_mapper.Map<AccountViewModel>(exec.Result!));
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("~/api/settings/accounts/{id}/access")]
|
||||
public object AccountsAdd([AsGuid] string id, AccountAccessViewModel request)
|
||||
public ObjectResult AccountsAccessAdd([AsGuid] string id, AccountAccessViewModel request)
|
||||
{
|
||||
var model = _mapper.Map<List<AccountAccessDto>>(request.Accesses);
|
||||
|
||||
@@ -244,7 +152,7 @@ public class SettingsAccountController : BaseApiController
|
||||
|
||||
if (!request.Email.IsPresent())
|
||||
{
|
||||
return exec.Result!;
|
||||
return OkResponse(_mapper.Map<AccountViewModel>(exec.Result!));
|
||||
}
|
||||
|
||||
var inviteExec = _accountService.AccessInvite(UserId, id.AsGuid(), request.Email!, request.AllowWrite);
|
||||
@@ -257,15 +165,14 @@ public class SettingsAccountController : BaseApiController
|
||||
case AccessInviteStatus.access_exists:
|
||||
case AccessInviteStatus.invite_exists:
|
||||
case AccessInviteStatus.success:
|
||||
return exec.Result!;
|
||||
return OkResponse(_mapper.Map<AccountViewModel>(exec.Result!));
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("~/api/settings/accounts/{id}/access/{userId}")]
|
||||
public object AccountsAdd([AsGuid] string id, [AsGuid] string userId)
|
||||
public ObjectResult AccountsAccessDelete([AsGuid] string id, [AsGuid] string userId)
|
||||
{
|
||||
var exec = _accountService.AccessDelete(UserId, id.AsGuid(), userId.AsGuid());
|
||||
|
||||
@@ -276,23 +183,21 @@ public class SettingsAccountController : BaseApiController
|
||||
return ProblemBadResponse("Account not found.");
|
||||
|
||||
case GeneralExecStatus.success:
|
||||
return exec.Result!;
|
||||
return OkResponse(_mapper.Map<AccountViewModel>(exec.Result!));
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("~/api/settings/accounts/invites")]
|
||||
public List<AccountAccessInviteViewModel> AccountInvites()
|
||||
public ObjectResult AccountInvites()
|
||||
{
|
||||
var invites = _accountService.InvitesGet(_contextProvider.User.Email);
|
||||
|
||||
return _mapper.Map<List<AccountAccessInviteViewModel>>(invites);
|
||||
return OkResponse(_mapper.Map<List<AccountAccessInviteViewModel>>(invites));
|
||||
}
|
||||
|
||||
[HttpPost("~/api/settings/accounts/invites/{id}/accept")]
|
||||
public object AccountInviteAccept([AsGuid]string id, AccountInviteAcceptRequest request)
|
||||
public ObjectResult AccountInviteAccept([AsGuid] string id, AccountInviteAcceptRequest request)
|
||||
{
|
||||
var exec = _accountService.InviteAccept(UserId, id.AsGuid(), request.Name);
|
||||
|
||||
@@ -305,15 +210,14 @@ public class SettingsAccountController : BaseApiController
|
||||
|
||||
case InviteAcceptStatus.already_accepted:
|
||||
case InviteAcceptStatus.success:
|
||||
return _mapper.Map<AccountViewModel>(exec.Result!);
|
||||
return OkResponse(_mapper.Map<AccountViewModel>(exec.Result!));
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("~/api/settings/accounts/invites/{id}/reject")]
|
||||
public object AccountInviteReject([AsGuid] string id)
|
||||
public ObjectResult AccountInviteReject([AsGuid] string id)
|
||||
{
|
||||
var exec = _accountService.InviteReject(id.AsGuid());
|
||||
|
||||
@@ -324,7 +228,7 @@ public class SettingsAccountController : BaseApiController
|
||||
return ProblemBadResponse("Invite not found.");
|
||||
|
||||
case GeneralExecStatus.success:
|
||||
return _mapper.Map<AccountAccessInviteViewModel>(exec.Result!);
|
||||
return OkResponse(_mapper.Map<AccountAccessInviteViewModel>(exec.Result!));
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(exec.Status.ToString());
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user