public void Add(Activity value)
        {
            if (value.Created == null || value.ChallengeID == 0)
                return;

            if (value.RowKey == null)
                value.RowKey = value.Created.ToString();

            if (value.PartitionKey == null)
                value.PartitionKey = "Chal" + value.ChallengeID;

            context.AttachTo(TableName, value);
            context.UpdateObject(value);
            context.SaveChangesWithRetries();
            context.Detach(value);
        }
        public Challenge New(NewChallenge value)
        {
            if (value.Description.Equals(""))
            {
                Trace.WriteLine("EXCEPTION: You must specify a description for a challenge", "ChallengeController::New");

                throw new DaremetoResponseException("You have to specify a description.", System.Net.HttpStatusCode.InternalServerError);
            }

            Customer cust = CustRepo.GetWithID(((DareyaIdentity)HttpContext.Current.User.Identity).CustomerID);

            IBillingProcessor processor = BillingSystem.BillingProcessorFactory.GetBillingProcessor((BillingSystem.BillingProcessorFactory.SupportedBillingProcessor)cust.BillingType);
            if (processor == null)
            {
                // No billing processor exists to service this request. All challenges must originate from customers
                // that have set up their billing. Therefore we must reject this request outright.

                // let's be naughty and throw a "reserved for future use" HTTP status code.
                throw new DaremetoResponseException("The current customer hasn't provided any credit card information.", System.Net.HttpStatusCode.PaymentRequired);
            }

            Trace.WriteLine("Creating a new challenge for customer " + ((DareyaIdentity)HttpContext.Current.User.Identity).CustomerID.ToString(), "ChallengeController::New");

            value.CustomerID = ((DareyaIdentity)HttpContext.Current.User.Identity).CustomerID;

            decimal firstBid = (decimal)value.CurrentBid;

            value.ID=ChalRepo.Add(value);

            decimal approxFees = Billing.GetFeesForBounty(processor, value.CurrentBid);

            Trace.WriteLine("Adding a bid of " + firstBid.ToString() + " to challenge ID " + value.ID.ToString(), "ChallengeController::New");
            ChalRepo.AddBidToChallenge(value, value.CustomerID, firstBid, approxFees);

            value.CurrentBid = (firstBid - approxFees);

            bool createTargetStatus=false;

            Trace.WriteLine("The target customer type for challenge " + value.ID.ToString() + " is " + value.ForeignNetworkType.ToString());

            // Try using a supplied email address to target the challenge first...
            if (value.EmailAddress != null && !value.EmailAddress.Equals(""))
            {
                value.EmailAddress = value.EmailAddress.ToLower().Trim();

                Customer tryEMail = CustRepo.GetWithEmailAddress(value.EmailAddress);
                if (tryEMail != null && tryEMail.EmailAddress.Equals(value.EmailAddress))
                {
                    Trace.WriteLine("Found the email customer " + value.EmailAddress + " for new challenge " + value.ID.ToString(), "ChallengeController::New");
                    value.TargetCustomerID = tryEMail.ID;
                }
                else
                {
                    Trace.WriteLine("Couldn't find the email customer " + value.EmailAddress + " for new challenge " + value.ID.ToString(), "ChallengeController::New");
                    Customer unclaimedEmail = new Customer();
                    unclaimedEmail.EmailAddress = value.EmailAddress;
                    unclaimedEmail.Type = (int)Customer.TypeCodes.Unclaimed;
                    value.TargetCustomerID = CustRepo.Add(unclaimedEmail);
                }
                createTargetStatus = true;
            }
            else // then try using a supplied foreign network connection...
            {
                if (value.ForeignNetworkType != Customer.ForeignUserTypes.Undefined)
                {
                    long fnCustID = CustRepo.GetIDForForeignUserID(value.ForeignNetworkUserID, value.ForeignNetworkType);
                    if (fnCustID > 0)
                    {
                        Trace.WriteLine("Found the foreign network customer " + value.ForeignNetworkUserID + " as customer ID " + fnCustID.ToString());
                        value.TargetCustomerID = fnCustID;
                    }
                    else
                    {
                        Customer unclaimedCust = new Customer
                        {
                            FirstName = value.FirstName,
                            LastName = value.LastName,
                            Type = (int)Customer.TypeCodes.Unclaimed,
                            ForeignUserType = (int)value.ForeignNetworkType
                        };

                        value.TargetCustomerID = CustRepo.Add(unclaimedCust);

                        Trace.WriteLine("Created a new foreign network customer " + value.ForeignNetworkUserID + " as customer ID " + value.TargetCustomerID.ToString());

                        CustRepo.AddForeignNetworkForCustomer(value.TargetCustomerID, value.ForeignNetworkUserID, value.ForeignNetworkType);
                    }

                    createTargetStatus = true;
                }
            }

            ChalRepo.Update(value);

            Activity activity = new Activity(value.ID, DateTime.UtcNow) { Type = (int)Activity.ActivityType.ActivityCreateDare, CustomerID=value.CustomerID };
            RepoFactory.GetActivityRepo().Add(activity);

            if (createTargetStatus)
            {
                // notify the receipient of the new challenge.
                CustomerNotifier.NotifyNewChallenge(value.CustomerID, value.TargetCustomerID, value.ID);
            }

            return PrepOutboundChallenge(value);
        }
        public ChallengeStatus Take(long id)
        {
            Trace.WriteLine("Customer " + ((DareyaIdentity)HttpContext.Current.User.Identity).CustomerID.ToString() + " wants to take challenge "+id.ToString(), "ChallengeController::Take");

            Challenge c = ChalRepo.Get(id);

            if (c == null)
                throw new DaremetoResponseException("The requested Challenge resource doesn't exist.", System.Net.HttpStatusCode.NotFound);

            if (!Security.CanManipulateContent(c))
                throw new DaremetoResponseException("This Challenge can't be taken by this customer.", System.Net.HttpStatusCode.Forbidden);

            /*
            if (c.TargetCustomerID == ((DareyaIdentity)HttpContext.Current.User.Identity).CustomerID)
                throw new DaremetoResponseException("This Challenge was sent to the current user; call /challengestatus/accept instead", System.Net.HttpStatusCode.Conflict);
            */

            if (c.CustomerID == ((DareyaIdentity)HttpContext.Current.User.Identity).CustomerID)
                throw new DaremetoResponseException("This Challenge originated from the current user; you can't take your own dare", System.Net.HttpStatusCode.Conflict);

            if (c.TargetCustomerID == ((DareyaIdentity)HttpContext.Current.User.Identity).CustomerID)
            {
                // if this dare was sent directly to the customer,
                // we can go ahead and mark it Accepted since it's no
                // longer open for additional takers.
                c.State = (int)Challenge.ChallengeState.Accepted;
                ChalRepo.Update(c);
            }

            ChallengeStatus s = new ChallengeStatus();
            s.ChallengeID = c.ID;
            s.ChallengeOriginatorCustomerID = c.CustomerID;
            s.CustomerID = ((DareyaIdentity)HttpContext.Current.User.Identity).CustomerID;
            s.Status = (int)ChallengeStatus.StatusCodes.Accepted;

            Trace.WriteLine("Adding 'taking this dare' status for customer " + ((DareyaIdentity)HttpContext.Current.User.Identity).CustomerID.ToString() + " and challenge " + id.ToString(), "ChallengeController::Take");
            StatusRepo.Add(s);

            CustomerNotifier.NotifyChallengeAccepted(s.ChallengeOriginatorCustomerID, s.CustomerID, c.ID);

            Activity activity = new Activity(s.ChallengeID, DateTime.UtcNow) { Type = (int)Activity.ActivityType.ActivityTakeDare, CustomerID = s.CustomerID };
            RepoFactory.GetActivityRepo().Add(activity);

            return s;
        }
        public void Bid(ChallengeBid value)
        {
            Challenge c = ChalRepo.Get(value.ChallengeID);
            Customer cust=CustRepo.GetWithID(((DareyaIdentity)HttpContext.Current.User.Identity).CustomerID);

            if (c == null)
                throw new HttpResponseException("The requested Challenge resource doesn't exist.", System.Net.HttpStatusCode.NotFound);

            if (c.Privacy == (int)Challenge.ChallengePrivacy.FriendsOnly)
            {
                if (Security.DetermineAudience(c) < Security.Audience.Friends)
                    throw new HttpResponseException("This item is friends-only.", System.Net.HttpStatusCode.Forbidden);
            }

            if (BidRepo.CustomerDidBidOnChallenge(cust.ID, c.ID) != null)
                throw new HttpResponseException("You already bid on this challenge.", System.Net.HttpStatusCode.Conflict);

            IBillingProcessor processor = BillingSystem.BillingProcessorFactory.
                GetBillingProcessor((BillingSystem.BillingProcessorFactory.SupportedBillingProcessor)cust.BillingType);

            if (processor == null)
            {
                // the customer doesn't have a valid billing provider. don't accept the bid.
                throw new HttpResponseException(System.Net.HttpStatusCode.PaymentRequired);
            }

            decimal approximateFees = Billing.GetFeesForBounty(processor, value.Amount);

            ChalRepo.AddBidToChallenge(c, ((DareyaIdentity)HttpContext.Current.User.Identity).CustomerID, value.Amount, approximateFees);

            CustomerNotifier.NotifyChallengeBacked(((DareyaIdentity)HttpContext.Current.User.Identity).CustomerID, c.CustomerID, c.ID);

            Activity activity = new Activity(c.ID, DateTime.UtcNow) { Type = (int)Activity.ActivityType.ActivityBackDare, CustomerID = ((DareyaIdentity)HttpContext.Current.User.Identity).CustomerID };
            RepoFactory.GetActivityRepo().Add(activity);
        }