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 async Task, MotionAddStatus>> MotionAddAsync( Guid userId, Guid accountId, MotionAddUpdate motion, CancellationToken cancellationToken = default ) { if (motion == null) throw new ArgumentNullException(nameof(motion)); if (motion.Item == null) throw new ArgumentNullException(nameof(motion.Item)); var result = new Exec, MotionAddStatus>(MotionAddStatus.success); var account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); if (account == null) { return result.Set(MotionAddStatus.account_not_found); } if (!CanWrite(account, userId)) { return result.Set(MotionAddStatus.forbidden); } var itemExec = await _itemService.GetOrCreateAsync(userId, motion.Item, cancellationToken); 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 (!await _motionRepository.AddAsync(motionDb, cancellationToken)) { return result.Set(MotionAddStatus.failure); } result.Set(new List()); result.Result!.Add(_mapper.Map(motionDb)); if (motion.AccountId.IsPresent() && motion.AmountBalancing != 0) { var accountBalancing = await _accountRepository.GetAsync( userId, motion.AccountId!.AsGuid(), cancellationToken); if (accountBalancing != null && CanWrite(accountBalancing, userId)) { var balancingName = AccountMotionBalancing.BalancingItemName(account.Name); var itemBalancingExec = await _itemService.GetOrCreateAsync( userId, balancingName, cancellationToken); var (plus, minus) = AccountMotionBalancing.ResolveAmounts(motion.Plus, 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 (await _motionRepository.AddAsync(motionBalancing, cancellationToken)) { result.Result!.Add(_mapper.Map(motionBalancing)); } } } motionDb.Item = itemExec.Result!; return result; } public async Task> MotionUpdateAsync( Guid userId, Guid accountId, Guid motionId, MotionAddUpdate motion, CancellationToken cancellationToken = default ) { if (motion == null) throw new ArgumentNullException(nameof(motion)); if (motion.Item == null) throw new ArgumentNullException(nameof(motion.Item)); var result = new Exec(MotionUpdateStatus.success); var exists = await _motionRepository.GetAsync(userId, motionId, cancellationToken); if (exists == null || exists.AccountId != accountId) { return result.Set(MotionUpdateStatus.not_found); } var account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); if (account == null) { return result.Set(MotionUpdateStatus.not_found); } if (!CanWrite(account, userId)) { return result.Set(MotionUpdateStatus.forbidden); } var itemExec = await _itemService.GetOrCreateAsync(userId, motion.Item, cancellationToken); 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 (!await _motionRepository.UpdateAsync(exists, cancellationToken)) { return result.Set(MotionUpdateStatus.failure); } return result.Set(_mapper.Map(exists)); } public async Task, GeneralExecStatus>> GetMotionsAsync( Guid userId, Guid accountId, DateTime dateFrom, DateTime dateTo, CancellationToken cancellationToken = default ) { var result = new Exec, GeneralExecStatus>(GeneralExecStatus.success); var account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); if (account == null) { return result.Set(GeneralExecStatus.not_found); } var motions = await _motionRepository.GetByAccountAsync( accountId, dateFrom.ToUtc(), dateTo.ToUtc(), cancellationToken); return result.Set(_mapper.Map>(motions)); } public async Task> MotionRemoveAsync( Guid userId, Guid accountId, Guid motionId, CancellationToken cancellationToken = default ) { var result = new Exec(MotionDeleteStatus.success); var exists = await _motionRepository.GetAsync(userId, motionId, cancellationToken); if (exists == null || exists.AccountId != accountId) { return result.Set(MotionDeleteStatus.not_found); } var account = await _accountRepository.GetAsync(userId, accountId, cancellationToken); if (account == null) { return result.Set(MotionDeleteStatus.not_found); } if (!CanWrite(account, userId)) { return result.Set(MotionDeleteStatus.forbidden); } if (!await _motionRepository.RemoveAsync(exists, cancellationToken)) { return result.Set(MotionDeleteStatus.failure); } return result.Set(_mapper.Map(exists)); } }