Exemplo n.º 1
0
        public Operation <BitLevel> Demote(string userRef, int units, string haxh)
        => _authorizer.AuthorizeAccess(this.PermissionProfile(UserContext.CurrentUser()), () =>
        {
            Haxher.IsValidHash(haxh).ThrowIf(_v => !_v, "Access Denied");

            var @ref       = _refQuery.GetReferalNode(userRef);
            var targetUser = new User {
                EntityId = @ref.UserId
            };
            var currentLevel = _query.CurrentBitLevel(targetUser).ThrowIfNull("User has not begun cycling");
            var newLevel     = BitCycle.Create(currentLevel.Cycle, currentLevel.Level).Decrement(units);

            currentLevel.Cycle = newLevel.Cycle;
            currentLevel.Level = newLevel.Level;
            _pcommand.Update(currentLevel);

            currentLevel.Donation.Amount = GetUpgradeAmount(newLevel.Level + 1);
            _pcommand.Update(currentLevel.Donation);

            //move all current donnors to the next available beneficiary
            _query.GetDonorLevels(targetUser)
            .Where(_lvl => newLevel > new BitCycle {
                Cycle = _lvl.Cycle, Level = _lvl.Level
            })
            .Select(_lvl =>
            {
                var nextLevel = new BitCycle {
                    Cycle = _lvl.Cycle, Level = _lvl.Level
                }.Increment(1);
                var beneficiary = NextUpgradeBeneficiary(targetUser, nextLevel.Level, nextLevel.Cycle);
                var address     = _query.GetActiveBitcoinAddress(beneficiary);

                _lvl.Donation.ReceiverId = address.Id;

                return(_pcommand.Update(_lvl.Donation));
            })
            .ThrowIf(_ops => !_ops.Any(_op => _op.Succeeded), "failed to reassign some donors");

            return(currentLevel);
        });
Exemplo n.º 2
0
        public Operation <ReferralNode> AffixNewUser(string userId, string refereeCode)
        => _authorizer.AuthorizeAccess(UserContext.CurrentProcessPermissionProfile(), () =>
        {
            //lock because referal placement is not thread safe!
            lock (UniversalLock)
            {
                var referee   = _query.GetReferalNode(refereeCode).ThrowIfNull("invalid referee code");
                var downlines = _query.AllDownlines(referee);
                var user      = _query.GetUserById(userId);

                //affix to the referee if he has no downlines
                if (downlines.Count() == 0)
                {
                    var @ref = new ReferralNode
                    {
                        UplineCode    = refereeCode,
                        ReferrerCode  = refereeCode,
                        ReferenceCode = ReferralHelper.GenerateCode(userId),
                        User          = user
                    };

                    return(_pcommand.Add(@ref));
                }

                //generate a map for each downline referal node, with its reference code as key
                var hierarchyMap = GenerateHierarchyMap(downlines);

                //calculate and assign levels based on distance from the referee node in the hierarchy
                hierarchyMap.ForAll((cnt, duo) => duo.Value.Level = DistanceFromReferee(referee, duo.Key, hierarchyMap));

                //rearrange and order the downlines, then get the first incomplete duo, and place the new referal in the slot
                return(hierarchyMap
                       .Values
                       .OrderBy(_duo => _duo.Level)
                       .ThenBy(_duo => _duo.Count)
                       .FirstOrDefault(_duo => _duo.Count < 2)
                       .Pipe(_duo =>
                {
                    var @ref = new ReferralNode
                    {
                        UplineCode = _duo.UplineCode,
                        ReferrerCode = refereeCode,
                        ReferenceCode = ReferralHelper.GenerateCode(userId),
                        User = user
                    };

                    return _pcommand.Add(@ref);
                }));
            }
        });