示例#1
0
        public ActionResult AcceptPlayerGrid(int page, string offerId)
        {
            Guid offerGuid;

            if (Guid.TryParse(offerId, out offerGuid))
            {
                ViewData["Page"] = page;


                var app       = new FacebookWebClient();
                var fbContext = FacebookWebContext.Current;

                TennisUserModel existingUser = ModelUtils.GetTennisUsers(this.DB).Where(tu => tu.FacebookId == fbContext.UserId).FirstOrDefault();
                var             model        = new AcceptPlayersDataGridModel(offerGuid, existingUser, this.DB);
                model.IsPostBack = false;

                return(Json
                       (
                           new
                {
                    PlayerGrid = RenderPartialViewToString("PlayerGrid", model)
                }
                       ));
            }
            else
            {
                // BUGBUG: return error
            }
            return(Json(""));
        }
示例#2
0
        public CalendarModel(DateTime startDateP, TennisUserModel tennisUserP, SportsLinkDB dbP)
            : base(tennisUserP)
        {
            this.UserStartDate = IndexModel.GetLocalDate(startDateP.ToUniversalTime(), tennisUserP.TimeZoneOffset);
            this.UserStartDate = this.UserStartDate.AddDays(-(int)this.UserStartDate.DayOfWeek);
            this.StartDate = IndexModel.GetUtcDate(this.UserStartDate, tennisUserP.TimeZoneOffset);
            this.EndDate = this.StartDate.AddDays(7);

            if (null == CachedQuery)
            {
                var offers = ModelUtils.GetOffersFunc();

                Expression<Func<SportsLinkDB, TennisUserModel, DateTime, DateTime, IQueryable<OfferModel>>> results =
                (SportsLinkDB db, TennisUserModel tennisUser, DateTime startDate, DateTime endDate) =>
                    offers.Invoke(db, tennisUser)
                    .Where(o => o.RequestUser.FacebookId != tennisUser.FacebookId)
                    .Where(o => o.SpecificOpponent == null || o.SpecificOpponent.FacebookId == tennisUser.FacebookId || o.RequestUser.FacebookId == tennisUser.FacebookId)
                    .Where(o => o.ConfirmedUser == null || o.ConfirmedUser.FacebookId == tennisUser.FacebookId || o.RequestUser.FacebookId == tennisUser.FacebookId)
                    .Where(o => o.MatchDateUtc >= startDate)
                    .Where(o => o.MatchDateUtc < endDate)
                    .Where(o => o.MatchDateUtc >= DateTime.UtcNow || null != o.ConfirmedUser)
                    .OrderBy(o => o.MatchDateUtc);

                CachedQuery = CompiledQuery.Compile<SportsLinkDB, TennisUserModel, DateTime, DateTime, IQueryable<OfferModel>>
                (
                    results.Expand()
                );
            }

            this.Offers = CachedQuery(dbP, tennisUserP, this.StartDate, this.EndDate);
        }
        public AcceptPlayersDataGridModel(Guid offerGuid, TennisUserModel tennisUser, SportsLinkDB db)
            : base(null, tennisUser, db)
        {
            // No need for a header
            this.ShowHeader = true;

            // Get list of users who have accepted the offer
            IQueryable<Accept> accepts = db.Accept.Where(a => a.OfferId == offerGuid);

            IQueryable<TennisUserModel> tennisUsers = ModelUtils.GetTennisUsers(db);

            var acceptUsers = from a in accepts
                              join tu in tennisUsers
                              on a.FacebookId equals tu.FacebookId
                              where a.Accepted
                              select tu;

            this.Data = acceptUsers;
            this.Rows = acceptUsers;

            this.AddColumn("FacebookId", "", "PlayerGrid/UserPicture", null);
            this.AddColumn("Name", "Name");
            this.AddColumn("Rating", "Rating", (o) => IndexModel.FormatRating((double)o));
            this.AddColumn("Birthday", "Age", (o) => IndexModel.FormatAge((DateTime)o));
            this.AddColumn("City.Name", "Location");
            this.AddColumn("FacebookId", "Select Opponent", "PlayerGrid/UserSelect", null);
        }
        public PotentialOffersModel(TennisUserModel tennisUserP, SportsLinkDB dbP)
            : base(tennisUserP)
        {
            // BUGBUG: get rid of the hard-coded values
            if (null == CachedQuery)
            {
                var offers = ModelUtils.GetOffersFunc();

                Expression<Func<SportsLinkDB, TennisUserModel, IQueryable<OfferModel>>> results =
                (SportsLinkDB db, TennisUserModel tennisUser) =>
                    offers.Invoke(db, tennisUser)
                    .Where
                    (o =>
                        o.ConfirmedUser == null &&
                        (o.SpecificOpponent == null || o.SpecificOpponent.FacebookId == tennisUser.FacebookId) &&
                        o.RequestUser.FacebookId != tennisUser.FacebookId &&
                        o.MatchDateUtc >= DateTime.UtcNow &&
                        Math.Abs(tennisUser.Rating - o.RequestUser.Rating) <= 0.25 &&
                        db.CoordinateDistanceMiles(o.City.Latitude, o.City.Longitude, tennisUser.City.Latitude, tennisUser.City.Longitude) < 15
                ).OrderBy(o => Math.Abs(tennisUser.Rating - o.RequestUser.Rating)).Take(20);

                CachedQuery = CompiledQuery.Compile<SportsLinkDB, TennisUserModel, IQueryable<OfferModel>>
                (
                    results.Expand()
                );
            }

            this.PotentialOffers = CachedQuery(dbP, tennisUserP);
        }
示例#5
0
        public ActionResult PlayerDetails(long id)
        {
            TennisUserModel model = ModelUtils.GetTennisUsers(this.DB).Where(u => u.FacebookId == id).FirstOrDefault();

            if (null != model)
            {
                ViewData["PlayerModel"] = model;

                if (!Request.IsAjaxRequest())
                {
                    return(View());
                }

                return(Json
                       (
                           new
                {
                    PlayerDetails = RenderPartialViewToString("PlayerDetails", ModelUtils.GetModel <ModuleModel>(FacebookWebContext.Current.UserId, this.DB))
                },
                           JsonRequestBehavior.AllowGet
                       ));
            }

            return(Json(""));
        }
        public ConfirmedMatchesModel(TennisUserModel tennisUserP, SportsLinkDB dbP)
            : base(tennisUserP)
        {
            // Select confirmed matchs which do not have a score yet where the current user is either a requestor or an acceptor
            // BUGBUG: we might want to eliminate confirmed matches that way older than current time (user might have forgotten to enter a score)
            if (null == CachedQuery)
            {
                var offers = ModelUtils.GetOffersFunc();

                Expression<Func<SportsLinkDB, TennisUserModel, IQueryable<OfferModel>>> results =
                (SportsLinkDB db, TennisUserModel tennisUser) =>
                    offers.Invoke(db, tennisUser)
                    .Where(o => o.ConfirmedUser != null)
                    .Where(o => (o.ConfirmedUser.FacebookId == tennisUser.FacebookId || o.RequestUser.FacebookId == tennisUser.FacebookId))
                    .Where(o => (o.Score == null || o.Score == ""))
                    .OrderByDescending(o => o.MatchDateUtc);

                CachedQuery = CompiledQuery.Compile<SportsLinkDB, TennisUserModel, IQueryable<OfferModel>>
                (
                    results.Expand()
                );
            }

            this.ConfirmedMatches = CachedQuery(dbP, tennisUserP);
        }
示例#7
0
        /// <summary>
        /// This method will send a cancellation mail to both players in a confirmed match
        /// </summary>
        /// <param name="offer"></param>
        private void SendMatchCancellation(Offer offer)
        {
            var             fbContext   = FacebookWebContext.Current;
            var             tennisUsers = ModelUtils.GetTennisUsers(this.DB);
            TennisUserModel tennisUser1 = tennisUsers.Where(u => u.FacebookId == offer.FacebookId).FirstOrDefault();
            TennisUserModel tennisUser2 = tennisUsers.Where(u => u.FacebookId == offer.AcceptedById).FirstOrDefault();

            string location = OfferModel.GetLocationLink(LocationModel.Create(offer));

            Dictionary <string, string> tokens = new Dictionary <string, string>();

            tokens.Add("FacebookId1", tennisUser1.FacebookId.ToString());
            tokens.Add("Rating1", IndexModel.FormatRating(tennisUser1.Rating));
            tokens.Add("Name1", tennisUser1.Name.ToString());
            tokens.Add("FacebookId2", tennisUser2.FacebookId.ToString());
            tokens.Add("Rating2", IndexModel.FormatRating(tennisUser2.Rating));
            tokens.Add("Name2", tennisUser2.Name.ToString());

            tokens.Add("Date", IndexModel.FormatLongDate(offer.MatchDateUtc, tennisUser1.TimeZoneOffset));
            tokens.Add("Location", location);
            tokens.Add("Comments", offer.Message);
            tokens.Add("OfferId", offer.OfferId.ToString());

            string subject  = string.Format("TennisLoop: Match Cancelled");
            string template = Server.MapPath("/content/matchcancelled.htm");

            SendMessage(new long[] { tennisUser1.FacebookId, tennisUser2.FacebookId }, subject, template, tokens);
        }
示例#8
0
        public ActionResult DataGrid()
        {
            var app       = new FacebookWebClient();
            var fbContext = FacebookWebContext.Current;

            TennisUserModel existingUser = ModelUtils.GetTennisUsers(this.DB).Where(tu => tu.FacebookId == fbContext.UserId).FirstOrDefault();

            //ViewData.Model = new PlayersDataGridModel(existingUser, this.DB);

            return(View("DataGrid"));
        }
示例#9
0
        public DataGridModel(string filters, TennisUserModel tennisUser, SportsLinkDB db)
            : base(tennisUser)
        {
            this.Columns = new List<ColumnDefinition>();
            this.FilterValues = new Dictionary<string, List<string>>();

            if (!string.IsNullOrEmpty(filters))
            {
                foreach (string filter in filters.Split(new string[] { ",," }, StringSplitOptions.RemoveEmptyEntries))
                {
                    string[] filterPieces = filter.Split('=');
                    string filterName = filterPieces[0];
                    string[] filterValues = filterPieces[1].Split(new string[] { "||" }, StringSplitOptions.RemoveEmptyEntries);

                    this.FilterValues.Add(filterName, new List<string>(filterValues));
                }
            }
        }
示例#10
0
        public ActionResult Calendar(int page)
        {
            ViewData["Page"] = page;

            var app       = new FacebookWebClient();
            var fbContext = FacebookWebContext.Current;

            TennisUserModel existingUser = ModelUtils.GetTennisUsers(this.DB).Where(tu => tu.FacebookId == fbContext.UserId).FirstOrDefault();

            var calendarModel = new CalendarModel(DateTime.Now.AddDays(7 * page), existingUser, this.DB);

            return(Json
                   (
                       new
            {
                Calendar = RenderPartialViewToString("Calendar", calendarModel)
            }
                   ));
        }
示例#11
0
        public ActionResult SendMessage(long userId, string comments)
        {
            var             fbContext  = FacebookWebContext.Current;
            TennisUserModel tennisUser = ModelUtils.GetTennisUsers(this.DB).Where(u => u.FacebookId == fbContext.UserId).FirstOrDefault();
            TennisUserModel sendToUser = ModelUtils.GetTennisUsers(this.DB).Where(u => u.FacebookId == userId).FirstOrDefault();

            if (null != tennisUser && null != sendToUser)
            {
                string template = Server.MapPath("/content/usermessage.htm");
                Dictionary <string, string> tokens = new Dictionary <string, string>();
                tokens.Add("From.Id", tennisUser.FacebookId.ToString());
                tokens.Add("From.Rating", IndexModel.FormatRating(tennisUser.Rating));
                tokens.Add("Message", comments);

                SendMessage(new long[] { userId }, string.Format("TennisLoop: Message from <fb:name uid='{0}' capitalize='true'></fb:name>", tennisUser.FacebookId), template, tokens);
            }

            return(Json(""));
        }
示例#12
0
        public ActionResult PlayerGrid(int page, string filter)
        {
            ViewData["Page"] = page;


            var app       = new FacebookWebClient();
            var fbContext = FacebookWebContext.Current;

            TennisUserModel existingUser = ModelUtils.GetTennisUsers(this.DB).Where(tu => tu.FacebookId == fbContext.UserId).FirstOrDefault();
            var             model        = new PlayersDataGridModel(filter, existingUser, this.DB);

            model.IsPostBack = !string.IsNullOrEmpty(filter);

            return(Json
                   (
                       new
            {
                PlayerGrid = RenderPartialViewToString("PlayerGrid", model)
            }
                   ));
        }
示例#13
0
        public UserOffersModel(TennisUserModel tennisUserP, SportsLinkDB dbP)
            : base(tennisUserP)
        {
            // BUGBUG: what about offers which were not confirmed and where the offer time is past - we need to eliminate those from the db
            if (null == CachedQuery)
            {
                var offers = ModelUtils.GetOffersFunc();

                Expression<Func<SportsLinkDB, TennisUserModel, IQueryable<OfferModel>>> results =
                (SportsLinkDB db, TennisUserModel tennisUser) =>
                    offers.Invoke(db, tennisUser)
                    .Where(o => o.ConfirmedUser == null)
                    .Where(o => o.RequestUser.FacebookId == tennisUser.FacebookId  && o.MatchDateUtc > DateTime.UtcNow)
                    .OrderBy(o => o.MatchDateUtc);

                CachedQuery = CompiledQuery.Compile<SportsLinkDB, TennisUserModel, IQueryable<OfferModel>>
                (
                    results.Expand()
                );
            }

            this.UserOffers = CachedQuery(dbP, tennisUserP);
        }
示例#14
0
        public ResultsModel(TennisUserModel tennisUserP, SportsLinkDB dbP)
            : base(tennisUserP)
        {
            if (null == CachedQuery)
            {
                var offers = ModelUtils.GetOffersFunc();

                Expression<Func<SportsLinkDB, TennisUserModel, IQueryable<OfferModel>>> results =
                (SportsLinkDB db, TennisUserModel tennisUser) =>
                    offers.Invoke(db, tennisUser)
                    .Where(o => o.ConfirmedUser != null)
                    .Where(o => (o.ConfirmedUser.FacebookId == tennisUser.FacebookId || o.RequestUser.FacebookId == tennisUser.FacebookId))
                    .Where(o => (o.Score != null && o.Score != ""))
                    .OrderByDescending(o => o.MatchDateUtc);

                CachedQuery = CompiledQuery.Compile<SportsLinkDB, TennisUserModel, IQueryable<OfferModel>>
                (
                    results.Expand()
                );
            }

            this.UserResults = CachedQuery(dbP, tennisUserP);
        }
示例#15
0
        public PlayersModel(TennisUserModel tennisUserP, SportsLinkDB dbP)
            : base(tennisUserP)
        {
            if (null == CachedQuery)
            {
                var tennisUsers = ModelUtils.GetTennisUsersFunc();
                Expression<Func<SportsLinkDB, TennisUserModel, IQueryable<TennisUserModel>>> players =
                (SportsLinkDB db, TennisUserModel tennisUser) => tennisUsers.Invoke(db).Where
                    (p =>
                        Math.Abs(p.Rating - tennisUser.Rating) <= 0.25 &&
                        db.CoordinateDistanceMiles(p.City.Latitude, p.City.Longitude, tennisUser.City.Latitude, tennisUser.City.Longitude) < 15 &&
                        p.FacebookId != tennisUser.FacebookId &&
                        p.Gender == tennisUser.Gender
                    );

                CachedQuery = CompiledQuery.Compile<SportsLinkDB, TennisUserModel, IQueryable<TennisUserModel>>
                (
                    players.Expand()
                );
            }

            this.Players = CachedQuery(dbP, tennisUserP);
        }
示例#16
0
 public ModuleModel(TennisUserModel tennisUser)
 {
     this.TennisUser = tennisUser;
 }
示例#17
0
        public ActionResult CreateOffer(DateTime date, long[] locations, string courtData, string comments, long?opponentId)
        {
            var fbContext = FacebookWebContext.Current;

            TennisUserModel tennisUser = ModelUtils.GetTennisUsers(this.DB).Where(u => u.FacebookId == fbContext.UserId).FirstOrDefault();

            if (null != tennisUser)
            {
                List <long> pushIds = new List <long>();
                Court       court   = ProcessCourtData(courtData);

                if (!string.IsNullOrEmpty(courtData))
                {
                    CourtJson courtJson = JsonSerializer.Current.DeserializeObject <CourtJson>(courtData);

                    if (null != courtJson && !string.IsNullOrEmpty(courtJson.name))
                    {
                        court = this.DB.Court.Where(c => c.CourtId == courtJson.GuidId).FirstOrDefault();

                        if (null == court)
                        {
                            court           = new Court();
                            court.CourtId   = courtJson.GuidId;
                            court.Name      = courtJson.name;
                            court.Latitude  = courtJson.latitude;
                            court.Longitude = courtJson.longitude;

                            this.DB.Court.InsertOnSubmit(court);
                        }
                    }
                }

                //Add the entry, send out the messages
                Offer offer = new Offer();
                offer.OfferId             = Guid.NewGuid();
                offer.FacebookId          = tennisUser.FacebookId;
                offer.MatchDateUtc        = IndexModel.GetUtcDate(date, tennisUser.TimeZoneOffset);
                offer.PostDateUtc         = DateTime.UtcNow;
                offer.Message             = comments;
                offer.PreferredLocationId = tennisUser.City.LocationId;
                offer.Court = court;
                // BUGBUG: we dont' seem to set the completed flag anywhere currently
                offer.Completed = false;

                User opponent = null;

                if (opponentId.HasValue && opponentId.Value != 0)
                {
                    opponent = this.DB.User.Where(u => u.FacebookId == opponentId.Value).FirstOrDefault();
                }

                if (null != opponent)
                {
                    offer.SpecificOpponentId = opponent.FacebookId;
                    pushIds.Add(opponent.FacebookId);
                }
                else
                {
                    var tennisUsers = ModelUtils.GetTennisUsers(this.DB);
                    var matchUsers  = tennisUsers.Where
                                          (u =>
                                          this.DB.CoordinateDistanceMiles(u.City.Latitude, u.City.Longitude, tennisUser.City.Latitude, tennisUser.City.Longitude) < 15 &&
                                          Math.Abs(tennisUser.Rating - u.Rating) <= 0.25 &&
                                          u.Gender == tennisUser.Gender &&
                                          u.FacebookId != tennisUser.FacebookId &&
                                          u.EmailOffers
                                          );

                    foreach (var tu in matchUsers)
                    {
                        pushIds.Add(tu.FacebookId);
                    }
                }

                this.DB.Offer.InsertOnSubmit(offer);
                this.DB.SubmitChanges();

                string template = Server.MapPath("/content/matchrequest.htm");
                string subject  = string.Format("TennisLoop: Match Requested from <fb:name uid='{0}' capitalize='true'></fb:name>", tennisUser.FacebookId);
                SendMessage(pushIds, subject, template, offer, tennisUser);

                // Send out messages to all matching users

                return(Json
                       (
                           new
                {
                    UserOffers = RenderPartialViewToString("UserOffers", ModelUtils.GetModel <UserOffersModel>(FacebookWebContext.Current.UserId, this.DB)),
                    UserChallenges = RenderPartialViewToString("UserChallenges", ModelUtils.GetModel <UserOffersModel>(FacebookWebContext.Current.UserId, this.DB))
                }
                       ));
            }

            return(Json(""));
        }
示例#18
0
        private static bool SendMessage(IEnumerable <long> pushIds, string subject, string templatePath, Offer offer, TennisUserModel tennisUser)
        {
            string location = OfferModel.GetLocationLink(LocationModel.Create(offer));

            Dictionary <string, string> tokens = new Dictionary <string, string>();

            tokens.Add("FacebookId", tennisUser.FacebookId.ToString());
            tokens.Add("Rating", IndexModel.FormatRating(tennisUser.Rating));
            tokens.Add("Date", IndexModel.FormatLongDate(offer.MatchDateUtc, tennisUser.TimeZoneOffset).Replace(",", " @ "));
            tokens.Add("Name", tennisUser.Name.ToString());
            tokens.Add("Location", location);
            tokens.Add("Comments", offer.Message);
            tokens.Add("OfferId", offer.OfferId.ToString());

            return(SendMessage(pushIds, subject, templatePath, tokens));
        }
示例#19
0
        private static bool SendMessage(IEnumerable<long> pushIds, string subject, string templatePath, Offer offer, TennisUserModel tennisUser)
        {
            string location = OfferModel.GetLocationLink(LocationModel.Create(offer));

            Dictionary<string, string> tokens = new Dictionary<string, string>();
            tokens.Add("FacebookId", tennisUser.FacebookId.ToString());
            tokens.Add("Rating", IndexModel.FormatRating(tennisUser.Rating));
            tokens.Add("Date", IndexModel.FormatLongDate(offer.MatchDateUtc, tennisUser.TimeZoneOffset).Replace(",", " @ "));
            tokens.Add("Name", tennisUser.Name.ToString());
            tokens.Add("Location", location);
            tokens.Add("Comments", offer.Message);
            tokens.Add("OfferId", offer.OfferId.ToString());

            return SendMessage(pushIds, subject, templatePath, tokens);
        }
示例#20
0
 public ModuleModel(TennisUserModel tennisUser, SportsLinkDB db)
     : this(tennisUser)
 {
 }
示例#21
0
        public ActionResult Index()
        {
            var app       = new FacebookWebClient();
            var fbContext = FacebookWebContext.Current;

            ViewData["FirstRun"] = false;

            TennisUserModel existingUser = ModelUtils.GetTennisUsers(this.DB).Where(tu => tu.FacebookId == fbContext.UserId).FirstOrDefault();

            if (null == existingUser && null != fbContext.SignedRequest)
            {
                if (!fbContext.SignedRequest.Data.ContainsKey("registration"))
                {
                    return(new RedirectResult("/home/register"));
                }

                var regInfo = (JsonObject)fbContext.SignedRequest.Data["registration"];

                long locationId;
                City city = GetCity(regInfo, out locationId);

                double timeZoneOffset = 0;

                JsonArray users = (JsonArray)app.Query("SELECT timezone FROM user WHERE uid = " + fbContext.UserId);

                if (null != users && users.Count > 0)
                {
                    dynamic userData = users[0];
                    timeZoneOffset = Convert.ToDouble(userData.timezone);
                }

                if (null == city)
                {
                    JsonArray places = (JsonArray)app.Query("SELECT latitude,longitude FROM place WHERE page_id = " + locationId);

                    if (null != places && places.Count > 0)
                    {
                        JsonObject location = regInfo.GetValue <JsonObject>("location");
                        dynamic    place    = places[0];
                        city            = new City();
                        city.LocationId = location.GetValue <long>("id");
                        city.Name       = location.GetValue <string>("name");
                        city.Latitude   = Convert.ToDouble(place.latitude);
                        city.Longitude  = Convert.ToDouble(place.longitude);
                        this.DB.City.InsertOnSubmit(city);
                    }
                }

                User user = new User();
                user.FacebookId     = fbContext.UserId;
                user.Name           = regInfo.GetValue <string>("name");
                user.Email          = regInfo.GetValue <string>("email");
                user.Birthday       = regInfo.GetValue <DateTime>("birthday");
                user.Gender         = regInfo.GetValue <string>("gender") == "male";
                user.City           = city;
                user.TimeZoneOffset = timeZoneOffset;
                user.EmailOffers    = true;

                TennisUser tennisUser = new TennisUser();
                tennisUser.FacebookId          = fbContext.UserId;
                tennisUser.Rating              = regInfo.GetValue <double>("NTRPRating");
                tennisUser.SinglesDoubles      = regInfo.GetValue <string>("SinglesDoubles");
                tennisUser.CurrentAvailability = true;

                this.DB.User.InsertOnSubmit(user);
                this.DB.TennisUser.InsertOnSubmit(tennisUser);

                this.DB.SubmitChanges();

                return(new RedirectResult(Facebook.FacebookApplication.Current.ReturnUrlPath + "?fr=1"));
            }

            if (null == existingUser)
            {
                return(new RedirectResult("/home/register"));
            }

            if (!string.IsNullOrEmpty(Request["fr"]))
            {
                ViewData["FirstRun"] = true;
            }

            ViewData.Model     = new IndexModel(existingUser, this.DB);
            ViewData["Action"] = "Index";

            return(View("~/Views/Home/Index.aspx"));
        }
示例#22
0
        /// <summary>
        /// This method is called from the client (or from an email link) to accept an offer
        /// </summary>
        /// <param name="id"></param>
        /// <param name="uid"></param>
        /// <returns></returns>
        public ActionResult RejectOffer(string id, long?uid)
        {
            Guid offerGuid;

            if (Guid.TryParse(id, out offerGuid))
            {
                // Select this offer id if not confirmed yet
                Offer offer = this.DB.Offer.Where(o => o.OfferId == offerGuid && null == o.AcceptedById).FirstOrDefault();

                if (null != offer)
                {
                    var fbContext = FacebookWebContext.Current;

                    if (null != uid && fbContext.UserId != uid.Value)
                    {
                        ViewData.Model = "Wrong User Account...";
                        return(View("Redirect"));
                    }

                    TennisUserModel tennisUser = ModelUtils.GetTennisUsers(this.DB).Where(u => u.FacebookId == fbContext.UserId).FirstOrDefault();
                    string          message    = "Unknown Error";

                    // Check if this was an offer for a specific opponent
                    if (offer.SpecificOpponentId != null)
                    {
                        // Confirm it is the specific opponent who is accepting
                        if (fbContext.UserId == offer.SpecificOpponentId)
                        {
                            offer.AcceptedById = offer.SpecificOpponentId;
                            SendMatchCancellation(offer);

                            this.DB.Offer.DeleteOnSubmit(offer);
                            this.DB.SubmitChanges();
                        }
                        else
                        {
                            // Unexpected since this offer id was meant for a different opponent
                            message = "This offer is not valid. Please submit feedback if you keep getting this message.";
                        }
                    }
                    else
                    {
                        if (!DB.Accept.Any(a => a.FacebookId == fbContext.UserId && a.OfferId == offer.OfferId))
                        {
                            // Create an accept entry and add to the accept table
                            Accept accept = new Accept();
                            accept.FacebookId = fbContext.UserId;
                            accept.OfferId    = offer.OfferId;
                            accept.Accepted   = false;

                            this.DB.Accept.InsertOnSubmit(accept);
                            this.DB.SubmitChanges();

                            message = "Match requestor notified.  You will be contacted if he/she accepts...";
                        }
                        else
                        {
                            message = "You have accepted this offer already - please wait for confirmation from match requestor. Redirecting you to homepage.";
                        }
                    }

                    // BUGBUG: when will it not be an ajax request?
                    if (!Request.IsAjaxRequest())
                    {
                        ViewData.Model = message;
                        return(View("Redirect"));
                    }

                    return(Json
                           (
                               new
                    {
                        PotentialOffers = RenderPartialViewToString("PotentialOffers", ModelUtils.GetModel <PotentialOffersModel>(FacebookWebContext.Current.UserId, this.DB)),
                        ConfirmedMatches = RenderPartialViewToString("ConfirmedMatches", ModelUtils.GetModel <ConfirmedMatchesModel>(FacebookWebContext.Current.UserId, this.DB))
                    }
                           ));
                }
                else
                {
                    // BUGBUG: return message that the offer might have already been taken or might have been revoked
                    ViewData.Model = "Invalid offer - the offer might have been revoked or no longer exists";
                    return(View("Redirect"));
                }
            }
            else // Unparseable offer id
            {
                if (!Request.IsAjaxRequest())
                {
                    ViewData.Model = "This offer is not valid. Please submit feedback if you keep getting this message.";
                    return(View("Redirect"));
                }

                return(Json(""));
            }
        }