/// <summary>
        /// Create a partner call and it's associated work item object that tracks replies
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public PartnerCall CreatePartnerCall(PartnerCall obj)
        {
            CreatePartnerCallAuthorization(obj);

            var user = CfPerfCache.GetClimber(CfIdentity.UserID);

            obj.ID = Guid.NewGuid();
            obj.UserID = user.ID;
            obj.CreatedUtc = DateTime.UtcNow;

            //-- Sanitize the call subscription based on place type
            var place = CfCacheIndex.Get(obj.PlaceID);
            if (place.Type.ToPlaceCateogry() == PlaceCategory.IndoorClimbing) { obj.ForOutdoor = false; }
            else if (place.Type.ToPlaceCateogry() == PlaceCategory.OutdoorClimbing) { obj.ForIndoor = false; }

            //-- default start time to midday if not set
            if (obj.StartDateTime == obj.StartDateTime.Date) { obj.StartDateTime = obj.StartDateTime.AddHours(12); }
            if (obj.EndDateTime == default(DateTime)) { obj.EndDateTime = obj.StartDateTime.AddHours(5); }

            pcRepo.Create(obj);

            postSvc.CreatePartnerCallPost(obj, user.PrivacyPostsDefaultIsPublic);

            new AlertsService().EnquePartnerCallWorkItem(CfIdentity.UserID, obj.PlaceID, obj.ID);

            return obj;
        }
예제 #2
0
        private void FixupPartnerCall(PartnerCall previousValue)
        {
            if (previousValue != null && previousValue.PartnerCallReplys.Contains(this))
            {
                previousValue.PartnerCallReplys.Remove(this);
            }

            if (PartnerCall != null)
            {
                if (!PartnerCall.PartnerCallReplys.Contains(this))
                {
                    PartnerCall.PartnerCallReplys.Add(this);
                }
                if (PartnerCallID != PartnerCall.ID)
                {
                    PartnerCallID = PartnerCall.ID;
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ci"></param>
        /// <param name="place"></param>
        /// <returns></returns>
        public dynamic CreateTemplateDynamicData(PartnerCall obj, CfCacheIndexEntry place)
        {
            var commentData = "";
            if (!string.IsNullOrEmpty(obj.Comment))
            {
                if (obj.Comment.Length < 255) { commentData = obj.Comment; }
                else { commentData = obj.Comment.Excerpt(255) + " ..."; }
            }

            string level = ((ClimbingLevelGeneral)obj.PreferredLevel).ToString();

            string start = obj.StartDateTime.ToString("dd MMM HH:mm");
            if (obj.StartDateTime == obj.StartDateTime.Date) { start = obj.StartDateTime.ToString("dd MMM"); }

            bool isLoc = (place.Type != CfType.City && place.Type != CfType.ClimbingArea);

            dynamic data = new { Place = Sanitize(place.Name),
                Comment = Sanitize(commentData), Start = start, Level = level, Indoor = obj.ForIndoor, Outdoor = obj.ForOutdoor, IsLoc = isLoc };
            return data;
        }
예제 #4
0
 public PartnerCallDto(CfCacheIndexEntry p, PartnerCall pc, IUserBasicDetail user)
 {
     ID = pc.ID.ToString("N");
     PlaceID = p.ID.ToString("N");
     Type = (byte)p.Type;
     Country = p.CountryID;
     PlaceName = p.Name;
     Indoor = pc.ForIndoor;
     Outdoor = pc.ForOutdoor;
     CreatedUtc = pc.CreatedUtc.ToEpochTimeString();
     StartDateTime = pc.StartDateTime.ToString("h:mm tt ddd MMM dd");
     if (!pc.HasDefaultEndDate)
     {
         EndDateTime = pc.EndDateTime.ToString("h:mm tt ddd MMM dd");
     }
     PerferredLevel = pc.PreferredLevel;
     Comment = pc.Comment;
     ByID = user.ID.ToString("N");
     By = user.DisplayName;
     ByPic = user.Avatar;
 }
        private void CreatePartnerCallAuthorization(PartnerCall obj)
        {
            var place = CfCacheIndex.Get(obj.PlaceID);

            if (place.Type == CfType.Country || place.Type == CfType.Province)
            {
                throw new Exception("You can not post for a country or a province as this will cause too many people to receive an alert about your partner call.");
            }
            if (place.Type == CfType.ClimbingArea)
            {
                var area = new AreaRepository().GetByID(place.ID);
                if (area.DisallowPartnerCalls)
                {
                    throw new Exception("You can not post for "+area.Name+" as it has been disallowed by admin probably because it will too many people to receive an alert about your partner call. Please choose a smaller related area.");
                }
            }

            ////-- Check user isn't submitting multiple within 1 hour
            var usersMostRecentCalls = GetUsersLatestPartnerCalls(CfIdentity.UserID, 3).ToList();
            var similarInLastHour = usersMostRecentCalls.Where(pc => pc.ID == obj.ID && pc.CreatedUtc > DateTime.UtcNow.AddHours(-1));
            if (similarInLastHour.Count() > 0) { throw new Exception("You can only post once every hour for the same place other wise you will cause too many people to receive alerts about your calls."); }

            if (!obj.ForIndoor && !obj.ForOutdoor) { throw new ArgumentOutOfRangeException("Cannot create a partner call with neither indoor or outdoor climbing specified"); }
            if (obj.StartDateTime < DateTime.Now.AddDays(-1)) { throw new ArgumentOutOfRangeException("Cannot create a partner call with the start date " + obj.StartDateTime + " as it is in the past"); }
        }
        /// <summary>
        /// Increments the reply counter for a partner call (to keep track of how well Climbfind/P.C's are going)
        /// </summary>
        /// <param name="pc"></param>
        /// <param name="pcr"></param>
        private void AddPartnerCallSubscriptionWorkItemReply(PartnerCall pc, PartnerCallReply pcr)
        {
            var item = pcWRepo.GetAll().Where(i => i.PartnerCallID == pc.ID).SingleOrDefault();
            if (item != default(PartnerCallNotificationWorkItem))
            {
                item.ReplyCount++;
                pcWRepo.Update(item);
            }

            var p = pcRepo.GetAll().Where(i => i.ID == pc.ID).SingleOrDefault();
            p.PartnerCallReplys.Add(pcr);
            pcRepo.Update(p);
        }
        /// <summary>
        /// Log when someone responds to a partner call by private message
        /// </summary>
        /// <param name="pc"></param>
        /// <param name="message"></param>
        public void LogPartnerCallMessageReply(PartnerCall pc, Message message)
        {
            if (pc.UserID == message.SenderID) { throw new ArgumentException("Cannot reply to your own partner call!!"); }

            var pcr = new PartnerCallReply() { ID = Guid.NewGuid(), Message = message.Content, PartnerCallID = pc.ID,
                 TypeID = (byte)PartnerCallReplyType.Message, Utc = DateTime.UtcNow, UserID = message.SenderID };

            AddPartnerCallSubscriptionWorkItemReply(pc, pcr);
        }
        /// <summary>
        /// Delete a partner call and it's associated work item.
        /// ** TODO Does that make sense to delete both?
        /// </summary>
        /// <param name="obj"></param>
        public void DeletePartnerCall(PartnerCall obj)
        {
            if (obj.UserID != CfIdentity.UserID) { throw new UnauthorizedAccessException("Cannot delete a partner call that does not belong to you"); }

            var workItem = pcWRepo.GetAll().Where(i => i.PartnerCallID == obj.ID).SingleOrDefault();

            if (workItem == null) { pcRepo.Delete(obj.ID); }
            else if (workItem.NotificationsSent == 0)
            {
                pcWRepo.Delete(workItem.ID);
                pcRepo.Delete(obj.ID);
            }
            else
            {
                obj.UserDeleted = true;
                pcRepo.Update(obj);
            }

            postSvc.DeletePartnerCallPost(obj);
        }
예제 #9
0
 internal Post UpdatePartnerCallPost(PartnerCall o)
 {
     return UpdateTypedPost(o.ID, new { PartnerCall = o, Place = GetPostPlace(o.PlaceID) });
 }
예제 #10
0
 internal void DeletePartnerCallPost(PartnerCall o)
 {
     DeleteTypedPost(postRepo.GetByID(o.ID));
 }
예제 #11
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ci"></param>
 /// <returns></returns>
 internal Post CreatePartnerCallPost(PartnerCall obj, bool isPublic)
 {
     var place = GetPostPlace(obj.PlaceID);
     var postMgr = new cf.Content.Feed.V0.PartnerCallPostManager();
     dynamic data = postMgr.CreateTemplateDynamicData(obj, place);
     return postMgr.CreatePost(obj.ID, obj.UserID, place, isPublic, data);
 }
        /// <summary>
        /// Send a message that basically originated from a partner call post
        /// </summary>
        /// <param name="pc"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public Message PrivatePartnerCallReply(PartnerCall pc, string content)
        {
            var msg = SendMessage(pc.UserID, content);

            //-- Log reply to partner calls! (JSK - hehe breakin architecture rules :p)
            new cf.Services.PartnerCallService().LogPartnerCallMessageReply(pc, msg);

            return msg;
        }