namespace MyOffice.Services.Account { 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 _logger; private readonly IAccountCategoryRepository _accountCategoryRepository; 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 logger, IAccountCategoryRepository accountCategoryRepository, IAccountRepository accountRepository, ICurrencyRepository currencyRepository, IAccountAccountCategoryRepository accountAccountCategoryRepository, IMotionRepository motionRepository, IItemRepository itemRepository, IItemGlobalRepository itemGlobalRepository, ItemService itemService ) { _logger = logger; _accountCategoryRepository = accountCategoryRepository; _accountRepository = accountRepository; _currencyRepository = currencyRepository; _accountAccountCategoryRepository = accountAccountCategoryRepository; _motionRepository = motionRepository; _itemRepository = itemRepository; _itemGlobalRepository = itemGlobalRepository; _itemService = itemService; } public List GetAllCategories(Guid userId) { return _accountCategoryRepository.GetAll(userId); } public Exec GetCategory(Guid userId, Guid id) { var result = new Exec(GeneralExecStatus.success); var category = _accountCategoryRepository.Get(userId, id); if (category == null) { return result.Set(GeneralExecStatus.not_found); } return result.Set(category); } public Exec CategoryAdd(Guid userId, AccountCategory category) { if (category == null) throw new ArgumentNullException(nameof(category)); var result = new Exec(GeneralExecStatus.success); category.Id = Guid.NewGuid(); category.UserId = userId; if (!_accountCategoryRepository.Add(category)) { return result.Set(GeneralExecStatus.failure); } return result.Set(category); } public Exec CategoryUpdate(Guid userId, Guid id, AccountCategory category) { if (category == null) throw new ArgumentNullException(nameof(category)); var result = new Exec(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 CategoryRemove(Guid userId, Guid id) { var result = new Exec(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 GetAllAccounts(Guid userId) { return _accountRepository.GetAll(userId); } public List GetByCategory(Guid userId, Guid categoryId) { return _accountRepository.GetByCategory(userId, categoryId); } public List GetByCategoryDetailed(Guid userId, Guid categoryId) { return _accountRepository.GetByCategoryDetailed(userId, categoryId); } public Exec GetByIdDetailed(Guid userId, Guid id) { var result = new Exec(GeneralExecStatus.success); var account = _accountRepository.GetByIdDetailed(userId, id); if (account == null) { return result.Set(GeneralExecStatus.not_found); } return result.Set(account); } public Exec AccountAdd(Guid userId, AccountAdd input) { if (input == null) throw new ArgumentNullException(nameof(input)); var result = new Exec(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 { new() { AccountId = account.Id, CategoryId = category.Id, } }; account.AccessRights = new List { new() { AccountId = account.Id, UserId = userId, IsAllowManage = true, IsAllowRead = true, IsAllowWrite = true, } }; if (!_accountRepository.Add(account)) { return result.Set(AccountAddResult.failure); } return result.Set(account); } public Exec AccountUpdate(Guid userId, Guid accountId, AccountEdit input) { if (input == null) throw new ArgumentNullException(nameof(input)); var result = new Exec(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 { new() { AccountId = account.Id, CategoryId = category.Id, } }; } if (!_accountRepository.Update(account)) { return result.Set(AccountEditResult.failure); } return result.Set(account); } public Exec, GeneralExecStatus> AccountCategoryRemove(Guid userId, Guid accountId, Guid categoryId) { var result = new Exec, 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 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(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, AmountPlus = motion.Plus, AmountMinus = motion.Minus, Description = motion.Description, }; if (!_motionRepository.Add(motionDb)) { return result.Set(MotionAddResult.failure); } motionDb.Item = itemExec.Result!; return result.Set(motionDb); } public Exec 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(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, GeneralExecStatus> GetMotions( Guid userId, Guid accountId, DateTime dateFrom, DateTime dateTo ) { var result = new Exec, 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 MotionRemove( Guid userId, Guid accountId, Guid motionId ) { var result = new Exec(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 FindAccounts(Guid userId, string term) { return _accountRepository.FindAccounts(userId, term); } } }