/// <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; }
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; }
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); }
internal Post UpdatePartnerCallPost(PartnerCall o) { return UpdateTypedPost(o.ID, new { PartnerCall = o, Place = GetPostPlace(o.PlaceID) }); }
internal void DeletePartnerCallPost(PartnerCall o) { DeleteTypedPost(postRepo.GetByID(o.ID)); }
/// <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; }