public override IDictionary <string, object> GetInfoDictionaryForMember(Character member)
        {
            var result = base.GetInfoDictionaryForMember(member);

            //add members if it's a private corporation and it's active
            if (IsActive)
            {
                result.Add(k.members, Members.ToDictionary());
                result.Add(k.maxMemberCount, MaxMemberCount);
            }

            if (member != CEO)
            {
                var leaveEnd = CorporationManager.GetLeaveTime(member, out bool isLeaveActive);
                if (isLeaveActive)
                {
                    result.Add(k.leaveEnd, leaveEnd);
                }

                var joinEnd = CorporationManager.GetJoinEnd(member, Eid, out bool isJoinActive);
                if (isJoinActive)
                {
                    result.Add(k.joinEnd, joinEnd);
                }
            }

            if (HasRole(member, PresetCorporationRoles.CAN_LIST_TECHTREE))
            {
                _techTreeService.AddInfoToDictionary(Eid, result);
            }

            return(result);
        }
        public void PayOut(Character member, double amount, Character issuer)
        {
            if (amount <= 0)
            {
                return;
            }

            CanPayOut(issuer).ThrowIfFalse(ErrorCodes.InsufficientPrivileges);
            IsMember(member).ThrowIfFalse(ErrorCodes.NotMemberOfCorporation);

            var ceo = CEO;

            if (ceo != issuer)
            {
                CorporationManager.IsJoinPeriodExpired(member, Eid).ThrowIfFalse(ErrorCodes.corporationTransactionsFrozen);
            }

            var builder = TransactionLogEvent.Builder().SetCorporation(this).SetTransactionType(TransactionType.characterPayOut);

            var corporationWallet = new CorporationWallet(this);

            corporationWallet.Balance -= amount;
            LogTransaction(builder.SetCreditBalance(corporationWallet.Balance)
                           .SetCreditChange(-amount)
                           .SetCharacter(issuer)
                           .SetInvolvedCharacter(member).Build());

            var memberWallet = _characterWalletFactory(member, TransactionType.characterPayOut);

            memberWallet.Balance += amount;
            member.LogTransaction(builder.SetCreditBalance(memberWallet.Balance)
                                  .SetCreditChange(amount)
                                  .SetCharacter(member)
                                  .SetInvolvedCharacter(issuer).Build());
        }
        public void Leave(Character character)
        {
            //is it still valid? (not cancelled)
            if (!CorporationManager.IsInLeavePeriod(character))
            {
                Logger.Info("leaveCorporation: leave cancelled. characterID: " + character.Id);
                return;
            }

            if (character == CEO)
            {
                //ceo is leaving the corp, it's allowed only when he is the last one
                if (GetCharacterMembers().Count() > 1)
                {
                    Logger.Info("leaveCorporation: corporation has members leave cancelled for characterID:" + character.Id);
                    return;
                }

                //he is the last one = corp closing
                Logger.Info("leaveCorporation: corporation is closing: eid:" + Eid);
            }



            //freelancer corporation eid
            if (DefaultCorporation.IsFreelancerCorporation(Eid))
            {
                Logger.Info("leaveCorporation: character is in private corporation. characterID:" + character.Id);
                return;
            }

            var newCorporation = DefaultCorporation.GetFreelancerCorporation();

            newCorporation.AddMember(character, CorporationRole.NotDefined, this);

            RemoveMember(character);

            //remove from documents
            CorporationDocumentHelper.OnCorporationLeave(character, Eid);

            _channelManager.LeaveChannel(ChannelName, character);
            _channelManager.JoinChannel(newCorporation.ChannelName, character, CorporationRole.NotDefined);

            Transaction.Current.OnCommited(() =>
            {
                CorporationManager.InformCorporationMemberTransferred(this, newCorporation, character);

                character.GetPlayerRobotFromZone()?.UpdateCorporationOnZone(newCorporation.Eid);
                var info = new Dictionary <string, object>
                {
                    { k.from, Eid },
                    { k.to, newCorporation.Eid },
                    { k.characterID, character.Id },
                };

                ZoneManager.Value.Zones.ForEach(z => z.UpdateCorporation(CorporationCommand.TransferMember, info));
            });

            Logger.Info("characterID: " + character.Id + " left corporation: eid:" + Eid + " default corporation: eid:" + newCorporation.Eid);
        }
        public void AddRecruitedMember(Character newMember, Character recruiterMember)
        {
            IsActive.ThrowIfFalse(ErrorCodes.AccessDenied);
            IsAvailableFreeSlot.ThrowIfFalse(ErrorCodes.CorporationMaxMembersReached);

            var oldCorporation = newMember.GetCorporation();

            //this protects the alliance board member complication and default corp situation
            var role = GetRoleFromSql(newMember);

            role.ThrowIfNotEqual(CorporationRole.NotDefined, ErrorCodes.MemberHasRolesError);

            CorporationManager.IsJoinAllowed(newMember).ThrowIfFalse(ErrorCodes.CorporationChangeTooOften);

            AddMember(newMember, CorporationRole.NotDefined, oldCorporation);
            oldCorporation.RemoveMember(newMember);

            newMember.GetCorporationApplications().DeleteAll();

            _channelManager.LeaveChannel(oldCorporation.ChannelName, newMember);
            _channelManager.JoinChannel(ChannelName, newMember, GetMemberRole(newMember));

            Transaction.Current.OnCommited(() =>
            {
                CorporationManager.InformCorporationMemberTransferred(oldCorporation, this, newMember);

                newMember.GetPlayerRobotFromZone()?.UpdateCorporationOnZone(Eid);
                var info = new Dictionary <string, object>
                {
                    { k.@from, oldCorporation.Eid },
                    { k.to, Eid },
                    { k.characterID, newMember.Id },
                };

                ZoneManager.Value.Zones.ForEach(z => z.UpdateCorporation(CorporationCommand.TransferMember, info));

                CorporationData.RemoveFromCache(oldCorporation.Eid);
                CorporationData.RemoveFromCache(Eid);

                if (_characterProfiles is CachedReadOnlyRepository <int, CharacterProfile> c)
                {
                    c.Remove(newMember.Id);
                }
            });
        }
        protected override void OnMemberRemoved(Character member)
        {
            base.OnMemberRemoved(member);

            //clean up insurances
            var deletedInsurances = InsuranceHelper.CleanUpOnCorporationLeave(member, Eid);

            InsuranceHelper.SendEmptyCorporationInsuranceList(member);

            //remove market orders
            CancelAllCorporationOrders(member);

            //last member leaving
            if (Members.Length <= 0)
            {
                //set the corp inactive
                IsActive = false;
                CorporationManager.DeleteYellowPages(Eid);

                //... do other corp closing cleanup
                Transaction.Current.OnCommited(() =>
                {
                    ZoneManager.Value.Zones.ForEach(z => z.UpdateCorporation(CorporationCommand.Close, new Dictionary <string, object>
                    {
                        { k.corporationEID, Eid }
                    }));
                });
            }
            else
            {
                if (deletedInsurances > 0)
                {
                    //refresh insurance list
                    SendInsuranceList();
                }
            }
        }