Files
myoffice/MyOffice.Services/Account/AccountService.cs
T
2023-07-25 22:10:03 +03:00

507 lines
14 KiB
C#

namespace MyOffice.Services.Account
{
using AutoMapper;
using Core;
using Core.Extensions;
using Core.Helpers;
using Data.Models.Accounts;
using Data.Models.Items;
using Data.Repositories.Account;
using Data.Repositories.Currency;
using Data.Repositories.Item;
using Item;
using Item.Domain;
using Microsoft.Extensions.Logging;
using MyOffice.Services.Account.Domain;
public class AccountService
{
private ILogger<AccountService> _logger;
private readonly IMapper _mapper;
private readonly IAccountCategoryRepository _accountCategoryRepository;
private readonly IAccountAccessRepository _accountAccessRepository;
private readonly IAccountRepository _accountRepository;
private readonly ICurrencyRepository _currencyRepository;
private readonly IAccountAccountCategoryRepository _accountAccountCategoryRepository;
private readonly IMotionRepository _motionRepository;
private readonly IItemRepository _itemRepository;
private readonly IItemGlobalRepository _itemGlobalRepository;
private readonly ItemService _itemService;
public AccountService(
ILogger<AccountService> logger,
IMapper mapper,
IAccountCategoryRepository accountCategoryRepository,
IAccountAccessRepository accountAccessRepository,
IAccountRepository accountRepository,
ICurrencyRepository currencyRepository,
IAccountAccountCategoryRepository accountAccountCategoryRepository,
IMotionRepository motionRepository,
IItemRepository itemRepository,
IItemGlobalRepository itemGlobalRepository,
ItemService itemService
)
{
_logger = logger;
_mapper = mapper;
_accountCategoryRepository = accountCategoryRepository;
_accountAccessRepository = accountAccessRepository;
_accountRepository = accountRepository;
_currencyRepository = currencyRepository;
_accountAccountCategoryRepository = accountAccountCategoryRepository;
_motionRepository = motionRepository;
_itemRepository = itemRepository;
_itemGlobalRepository = itemGlobalRepository;
_itemService = itemService;
}
public List<AccountCategory> GetAllCategories(Guid userId)
{
return _accountCategoryRepository.GetAll(userId);
}
public Exec<AccountCategory, GeneralExecStatus> GetCategory(Guid userId, Guid id)
{
var result = new Exec<AccountCategory, GeneralExecStatus>(GeneralExecStatus.success);
var category = _accountCategoryRepository.Get(userId, id);
if (category == null)
{
return result.Set(GeneralExecStatus.not_found);
}
return result.Set(category);
}
public Exec<AccountCategory, GeneralExecStatus> CategoryAdd(Guid userId, AccountCategory category)
{
if (category == null)
throw new ArgumentNullException(nameof(category));
var result = new Exec<AccountCategory, GeneralExecStatus>(GeneralExecStatus.success);
category.Id = Guid.NewGuid();
category.UserId = userId;
if (!_accountCategoryRepository.Add(category))
{
return result.Set(GeneralExecStatus.failure);
}
return result.Set(category);
}
public Exec<AccountCategory, GeneralExecStatus> CategoryUpdate(Guid userId, Guid id, AccountCategory category)
{
if (category == null)
throw new ArgumentNullException(nameof(category));
var result = new Exec<AccountCategory, GeneralExecStatus>(GeneralExecStatus.success);
var exists = _accountCategoryRepository.Get(userId, id);
if (exists == null)
{
return result.Set(GeneralExecStatus.not_found);
}
exists.Name = category.Name;
if (!_accountCategoryRepository.Update(exists))
{
return result.Set(GeneralExecStatus.failure);
}
return result.Set(exists);
}
public Exec<AccountCategory, AccountCategoryRemoveResult> CategoryRemove(Guid userId, Guid id)
{
var result = new Exec<AccountCategory, 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(exists);
}
public List<AccountDto> GetAllAccounts(Guid userId)
{
return _mapper.Map<List<AccountDto>>(_accountRepository.GetAll(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, AccountAddResult> AccountAdd(Guid userId, AccountAdd input)
{
if (input == null)
throw new ArgumentNullException(nameof(input));
var result = new Exec<Account, AccountAddResult>(AccountAddResult.success);
var category = _accountCategoryRepository.Get(userId, input.CategoryId);
if (category == null)
{
return result.Set(AccountAddResult.category_not_found);
}
var currency = _currencyRepository.GetByGlobalCurrency(userId, input.CurrencyId);
if (currency == null)
{
return result.Set(AccountAddResult.currency_not_found);
}
var account = new Account
{
Id = Guid.NewGuid(),
Name = input.Name,
CurrencyGlobalId = currency.CurrencyGlobalId,
};
account.Categories = new List<AccountAccountCategory>
{
new()
{
AccountId = account.Id,
CategoryId = category.Id,
}
};
account.AccessRights = new List<AccountAccess>
{
new()
{
AccountId = account.Id,
UserId = userId,
IsAllowManage = true,
IsAllowRead = true,
IsAllowWrite = true,
}
};
if (!_accountRepository.Add(account))
{
return result.Set(AccountAddResult.failure);
}
var access = account.AccessRights!.FirstOrDefault(x => x.UserId == userId);
if (access != null && access.Type.ToString() != input.Type)
{
if (Enum.TryParse<AccountAccessTypeEnum>(input.Type, out var enumType))
{
access.Type = enumType;
_accountAccessRepository.Update(access);
}
}
return result.Set(account);
}
public Exec<Account, GeneralExecStatus> AccountDelete(Guid userId, string id)
{
var result = new Exec<Account, GeneralExecStatus>(GeneralExecStatus.success);
var account = _accountRepository.Get(userId, id.AsGuid());
if (account == null)
{
return result.Set(GeneralExecStatus.not_found);
}
if (account.Motions!.Any())
{
return result.Set(GeneralExecStatus.not_found);
}
_accountRepository.Delete(account);
result.Set(account);
return result;
}
public Exec<Account, AccountEditResult> AccountUpdate(Guid userId, Guid accountId, AccountEdit input)
{
if (input == null)
throw new ArgumentNullException(nameof(input));
var result = new Exec<Account, AccountEditResult>(AccountEditResult.success);
AccountCategory? category = null;
if (input.CategoryId.HasValue)
{
category = _accountCategoryRepository.Get(userId, input.CategoryId.Value);
if (category == null)
{
return result.Set(AccountEditResult.category_not_found);
}
}
var currency = _currencyRepository.GetByGlobalCurrency(userId, input.CurrencyId);
if (currency == null)
{
return result.Set(AccountEditResult.currency_not_found);
}
var account = _accountRepository.Get(userId, accountId);
if (account == null)
{
return result.Set(AccountEditResult.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))
{
account.Categories = new List<AccountAccountCategory>
{
new()
{
AccountId = account.Id,
CategoryId = category.Id,
}
};
}
if (!_accountRepository.Update(account))
{
return result.Set(AccountEditResult.failure);
}
var access = account.AccessRights!.FirstOrDefault(x => x.UserId == userId);
if (access != null && access.Type.ToString() != input.Type)
{
if (Enum.TryParse<AccountAccessTypeEnum>(input.Type, out var enumType))
{
access.Type = enumType;
_accountAccessRepository.Update(access);
}
}
return result.Set(account);
}
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<Motion>, MotionAddResult> 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<Motion>, MotionAddResult>(MotionAddResult.success);
var account = _accountRepository.Get(userId, accountId);
if (account == null)
{
return result.Set(MotionAddResult.account_not_found);
}
var itemExec = _itemService.GetOrCreate(userId, motion.Item);
if (itemExec.Status != ItemGetOrAddResult.success)
{
return result.Set(MotionAddResult.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(MotionAddResult.failure);
}
result.Set(new List<Motion>());
result.Result!.Add(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(motionBalancing);
}
}
}
motionDb.Item = itemExec.Result!;
return result;
}
public Exec<Motion, MotionUpdateResult> 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<Motion, MotionUpdateResult>(MotionUpdateResult.success);
var exists = _motionRepository.Get(userId, motionId);
if (exists == null || exists.AccountId != accountId)
{
return result.Set(MotionUpdateResult.not_found);
}
var itemExec = _itemService.GetOrCreate(userId, motion.Item);
if (itemExec.Status != ItemGetOrAddResult.success)
{
return result.Set(MotionUpdateResult.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(MotionUpdateResult.failure);
}
return result.Set(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, MotionDeleteResult> MotionRemove(
Guid userId,
Guid accountId,
Guid motionId
)
{
var result = new Exec<Motion, MotionDeleteResult>(MotionDeleteResult.success);
var exists = _motionRepository.Get(userId, motionId);
if (exists == null || exists.AccountId != accountId)
{
return result.Set(MotionDeleteResult.not_found);
}
if (!_motionRepository.Remove(exists))
{
return result.Set(MotionDeleteResult.failure);
}
return result.Set(exists);
}
public List<Account> FindAccounts(Guid userId, string term)
{
return _accountRepository.FindAccounts(userId, term);
}
}
}