public async Task <IActionResult> Merge(IList <CategorieViewModel> categorieViewModels)
        {
            var categorieIds = categorieViewModels.Where(c => c.Selected).Select(c => c.CategorieId).ToList();

            if (categorieIds.Count < 2)
            {
                //Kan niet mergen met minder dat 2 categorieën
                return(RedirectToAction(nameof(Index)));
            }
            var categorieen = await _categorieenService.GetRawListByIdsAsync(categorieIds);

            if (categorieen.Count != categorieIds.Count)
            {
                //Niet alle aangegeven categorieën konden gevonden worden
                return(NotFound());
            }

            var mergeViewModel = new MergeViewModel
            {
                CategorieIds = categorieIds,
                Omschrijving = string.Join(", ", categorieen.Select(c => c.Omschrijving))
            };

            await SetSaldoAsync(mergeViewModel);

            return(View(mergeViewModel));
        }
        private async Task SetSaldoAsync(MergeViewModel mergeViewModel)
        {
            List <Task <decimal> > saldoTasks = new List <Task <decimal> >();

            foreach (var categorieId in mergeViewModel.CategorieIds)
            {
                var saldoTask = _categorieenService.GetSaldoAsync(new Categorie {
                    CategorieId = categorieId
                });
                saldoTasks.Add(saldoTask);
            }
            var saldos = await Task.WhenAll(saldoTasks);

            mergeViewModel.Saldo = saldos.Sum();
        }
        public async Task <IActionResult> CompleteMerge(MergeViewModel mergeViewModel)
        {
            await PerformExtraValidationsAsync(mergeViewModel);

            if (ModelState.IsValid)
            {
                var categorieen = await _categorieenService.GetRawListByIdsAsync(mergeViewModel.CategorieIds);

                if (categorieen.Count != mergeViewModel.CategorieIds.Count)
                {
                    //Niet alle aangegeven categorieën konden gevonden worden
                    return(NotFound());
                }

                //Alles naar de eerste toe zetten
                var uiteindelijkeCategorie = categorieen.First();
                var overigeCategorieen     = categorieen.Skip(1).ToList();
                _mapper.Map(mergeViewModel, uiteindelijkeCategorie);
                List <Task> moveTasks = new List <Task>();
                foreach (var overigeCategorie in overigeCategorieen)
                {
                    moveTasks.Add(MoveTransactiesAsync(uiteindelijkeCategorie, overigeCategorie));
                    moveTasks.Add(MoveRekeningenAsync(uiteindelijkeCategorie, overigeCategorie));
                }
                await Task.WhenAll(moveTasks);

                await _categorieenService.SaveChangesAsync();

                //Splits verwijderen en verplaatsen in twee SaveChanges
                //Transacties nullificeren de Categorie ipv verplaatsen indien voor de Remove niet eerst een SaveChanges wordt gedaan.
                //Rekeningen hebben dit issue niet, alleen Transacties. Nog uitzoeken wat hier mee aan de hand is.
                //Dit heeft nu als bijeffect dat de uiteindelijke omschijving niet een van de te verwijderen mag hebben (unique constraint exception)
                foreach (var overigeCategorie in overigeCategorieen)
                {
                    _categorieenService.Remove(overigeCategorie);
                }
                await _categorieenService.SaveChangesAsync();

                return(RedirectToAction(nameof(Details), new { id = uiteindelijkeCategorie.CategorieId }));
            }
            return(View(nameof(Merge), mergeViewModel));
        }
 private async Task PerformExtraValidationsAsync(MergeViewModel mergeViewModel)
 {
     await ValidateOmschrijvingInUseAsync(mergeViewModel.Omschrijving, mergeViewModel.CategorieIds);
 }