private async Task <Guid> UpgradeMatrixForUser(MatrixPosition adminPosition, AdminStructureSide adminStructure) { MatrixPosition upgradedPosition; if (!_multiAccount.SponsorId.HasValue) { throw new ValidationException("FATAL! User does not have sponsor"); } var userAccount = await _userAccountDataRepository.GetAsync(_multiAccount.UserAccountDataId); var userMultiAccountIds = userAccount.UserMultiAccounts.Select(x => x.Id).ToList(); // Need for cycles in the future var sponsorPositionOnUpgradedMatrix = await _matrixPositionHelper.GetPositionForAccountAtLevelAsync(_multiAccount.SponsorId.Value, _command.MatrixLevel); if (sponsorPositionOnUpgradedMatrix is null) { upgradedPosition = await _matrixPositionHelper.FindTheNearestEmptyPositionFromGivenAccountWhereInParentsMatrixThereIsNoAnyMultiAccountAsync( adminPosition.UserMultiAccountId.Value, userMultiAccountIds, _command.MatrixLevel, adminStructure); } else { upgradedPosition = await _matrixPositionHelper.FindTheNearestEmptyPositionFromGivenAccountWhereInParentsMatrixThereIsNoAnyMultiAccountAsync( _multiAccount.SponsorId.Value, userMultiAccountIds, _command.MatrixLevel); } if (upgradedPosition is null) { throw new ValidationException($"There is no empty space in the structure level - {_command.MatrixLevel} - where account can be assigned"); } upgradedPosition.AssignMultiAccount(_multiAccount.Id); await _matrixPositionRepository.UpdateAsync(upgradedPosition); _backgroundJobClient.Enqueue <MatrixPositionHasBeenUpgradedJob>( job => job.Execute(upgradedPosition.Id, null)); _backgroundJobClient.Enqueue <InitWithdrawalJob>( job => job.Execute(new InitWithdrawalModel { MatrixPositionId = upgradedPosition.Id, WithdrawalFor = WithdrawalForHelper.UpgradedMatrix }, null)); return(upgradedPosition.Id); }
public async Task <MatrixPosition> FindTheNearestEmptyPositionFromGivenAccountWhereInParentsMatrixThereIsNoAnyMultiAccountAsync( Guid userMultiAccountId, IReadOnlyCollection <Guid> multiAccountIds, int matrixLevel, AdminStructureSide adminStructureSide = AdminStructureSide.Skipped) { var userMatrixPosition = await GetPositionForAccountAtLevelAsync(userMultiAccountId, matrixLevel); if (userMatrixPosition is null) { throw new ArgumentNullException(nameof(userMatrixPosition)); } userMatrixPosition = await GetMatrixPositionUnderAdminBasedOnStructureSide(matrixLevel, adminStructureSide, userMatrixPosition); var allEmptyPositions = await _context.Set <MatrixPosition>() .Where(x => x.Left >= userMatrixPosition.Left) .Where(x => x.Right <= userMatrixPosition.Right) .Where(x => x.DepthLevel >= userMatrixPosition.DepthLevel) .Where(x => x.MatrixLevel == matrixLevel) .Where(x => x.UserMultiAccountId == null) .ToListAsync(); foreach (var emptyPosition in allEmptyPositions) { var matrix = await GetMatrixPositionWhereGivenPositionIsInLineBAsync(emptyPosition, matrixLevel); if (!CheckIfAnyAccountExistInMatrix(matrix, multiAccountIds)) { return(emptyPosition); } } return(null); }
private async Task <MatrixPosition> GetMatrixPositionUnderAdminBasedOnStructureSide(int matrixLevel, AdminStructureSide adminStructureSide, MatrixPosition topAdmin) { if (adminStructureSide == AdminStructureSide.Skipped) { return(topAdmin); } MatrixPosition position = topAdmin; switch (adminStructureSide) { case AdminStructureSide.Left: topAdmin = await _context.Set <MatrixPosition>() .Where(x => x.Left == position.Left + 1) .Where(x => x.ParentId == position.Id) .Where(x => x.MatrixLevel == matrixLevel) .SingleAsync(); break; case AdminStructureSide.Right: topAdmin = await _context.Set <MatrixPosition>() .Where(x => x.Right == position.Right - 1) .Where(x => x.ParentId == position.Id) .Where(x => x.MatrixLevel == matrixLevel) .SingleAsync(); break; } return(topAdmin); }