public async Task <ActionResult> TipUser(int id, int?amount, int?tx) { using (var db = new ZapContext()) { var receiver = await db.Users .Include(usr => usr.Funds) .Include(usr => usr.EarningEvents) .Include(usr => usr.Settings) .Where(u => u.Id == id).FirstOrDefaultAsync(); if (receiver == null) { Response.StatusCode = (int)HttpStatusCode.BadRequest; return(Json(new { Result = "Failure", Message = "User not found." })); } if (tx == null) { var userId = User.Identity.GetUserId(); if (userId == null) { return(Json(new { Result = "Failure", Message = "User not found." })); } var user = await db.Users .Include(usr => usr.Funds) .Include(usr => usr.SpendingEvents) .Where(u => u.AppId == userId).FirstOrDefaultAsync(); // Ensure user has the funds available. if (user.Funds.Balance < amount) { Response.StatusCode = (int)HttpStatusCode.Forbidden; return(Json(new { Result = "Failure", Message = "Not enough funds." })); } // All requirements are met - make payment user.Funds.Balance -= amount.Value; receiver.Funds.Balance += amount.Value; // Add Earning Event var ea = new EarningEvent() { Amount = amount.Value, OriginType = 2, TimeStamp = DateTime.UtcNow, Type = 0, }; receiver.EarningEvents.Add(ea); var spendingEvent = new SpendingEvent() { Amount = amount.Value, TimeStamp = DateTime.UtcNow, }; user.SpendingEvents.Add(spendingEvent); // Notify receiver var alert = new UserAlert() { TimeStamp = DateTime.Now, Title = "You received a tip!", Content = "From: <a href='" + @Url.Action(actionName: "Index", controllerName: "User", routeValues: new { username = user.Name }) + "'>" + user.Name + "</a><br/> Amount: " + amount.ToString() + " Satoshi.", IsDeleted = false, IsRead = false, To = receiver, }; receiver.Alerts.Add(alert); await db.SaveChangesAsync(); try { if (receiver.Settings == null) { receiver.Settings = new UserSettings(); } if (receiver.Settings.NotifyOnReceivedTip) { string receiverEmail = UserManager.FindById(receiver.AppId).Email; MailingService.Send(user: "******", message: new UserEmailModel() { Subject = "You received a tip!", Body = "From: " + user.Name + "<br/> Amount: " + amount.ToString() + " Satoshi.<br/><br/><a href='http://www.zapread.com'>zapread.com</a>", Destination = receiverEmail, Email = "", Name = "ZapRead.com Notify" }); } } catch (Exception e) { // Send an email. MailingService.Send(new UserEmailModel() { Destination = "*****@*****.**", Body = " Exception: " + e.Message + "\r\n Stack: " + e.StackTrace + "\r\n user: "******"", Name = "zapread.com Exception", Subject = "Send NotifyOnReceivedTip error.", }); } return(Json(new { Result = "Success" })); } else { // Anonymous tip var vtx = await db.LightningTransactions.FirstOrDefaultAsync(txn => txn.Id == tx); if (vtx == null || vtx.IsSpent == true) { Response.StatusCode = (int)HttpStatusCode.Forbidden; return(Json(new { Result = "Failure", Message = "Transaction not found" })); } vtx.IsSpent = true; receiver.Funds.Balance += amount.Value;// vtx.Amount;//amount; // Notify receiver var alert = new UserAlert() { TimeStamp = DateTime.Now, Title = "You received a tip!", Content = "From: anonymous <br/> Amount: " + amount.ToString() + " Satoshi.", IsDeleted = false, IsRead = false, To = receiver, }; receiver.Alerts.Add(alert); await db.SaveChangesAsync(); if (receiver.Settings == null) { receiver.Settings = new UserSettings(); } if (receiver.Settings.NotifyOnReceivedTip) { string receiverEmail = UserManager.FindById(receiver.AppId).Email; MailingService.Send(user: "******", message: new UserEmailModel() { Subject = "You received a tip!", Body = "From: anonymous <br/> Amount: " + amount.ToString() + " Satoshi.<br/><br/><a href='http://www.zapread.com'>zapread.com</a>", Destination = receiverEmail, Email = "", Name = "ZapRead.com Notify" }); } return(Json(new { Result = "Success" })); } } }
public async Task <ActionResult> Post(Vote v) { if (!ModelState.IsValid) { return(Json(new { result = "error", message = "Invalid" })); } if (v.a < 1) { return(Json(new { result = "error", message = "Invalid" })); } var userId = User.Identity.GetUserId(); // if userId is null, then it is anonymous using (var db = new ZapContext()) { var post = db.Posts .Include("VotesUp") .Include("VotesDown") .Include(p => p.UserId) .Include(p => p.UserId.Funds) .FirstOrDefault(p => p.PostId == v.Id); if (post == null) { return(Json(new { result = "error", message = "Invalid Post" })); } Models.User user = null; if (userId == null)// Anonymous vote { // Check if vote tx has been claimed if (v.tx != -1337) //debugging secret { var vtx = db.LightningTransactions.FirstOrDefault(tx => tx.Id == v.tx); if (vtx == null || vtx.IsSpent == true) { return(Json(new { result = "error", message = "No transaction to vote with" })); } vtx.IsSpent = true; await db.SaveChangesAsync(); } } else { user = db.Users .Include(usr => usr.Funds) .Include(usr => usr.EarningEvents) .Include(usr => usr.SpendingEvents) .FirstOrDefault(u => u.AppId == userId); if (user == null) { return(Json(new { result = "error", message = "Invalid User" })); } if (user.Funds.Balance < v.a) { return(Json(new { result = "error", message = "Insufficient Funds." })); } user.Funds.Balance -= v.a; } var spendingEvent = new SpendingEvent() { Amount = v.a, Post = post, TimeStamp = DateTime.UtcNow, }; double userBalance = 0.0; if (user != null) { userBalance = user.Funds.Balance; user.SpendingEvents.Add(spendingEvent); } if (v.d == 1) { // Voted up if (user != null && post.VotesUp.Contains(user)) { // Already voted - remove upvote? //post.VotesUp.Remove(user); //user.PostVotesUp.Remove(post); //post.Score = post.VotesUp.Count() - post.VotesDown.Count(); //return Json(new { result = "success", message = "Already Voted", delta = 0, score = post.Score, balance = user.Funds.Balance }); } else if (user != null) { post.VotesUp.Add(user); user.PostVotesUp.Add(post); } //post.VotesDown.Remove(user); //user.PostVotesDown.Remove(post); //post.Score = post.VotesUp.Count() - post.VotesDown.Count(); post.Score += v.a; // Record and assign earnings // Related to post owner post.TotalEarned += 0.6 * v.a; var ea = new EarningEvent() { Amount = 0.6 * v.a, OriginType = 0, TimeStamp = DateTime.UtcNow, Type = 0, }; var webratio = 0.1; var comratio = 0.1; //post.EarningEvents.Add(ea); var owner = post.UserId; if (owner != null) { owner.Reputation += v.a; owner.EarningEvents.Add(ea); owner.TotalEarned += 0.6 * v.a; if (owner.Funds == null) { owner.Funds = new UserFunds() { Balance = 0.6 * v.a, TotalEarned = 0.6 * v.a }; } else { owner.Funds.Balance += 0.6 * v.a; } } var postGroup = post.Group; if (postGroup != null) { postGroup.TotalEarnedToDistribute += 0.2 * v.a; } else { // not in group - send to community comratio += 0.2; } var website = db.ZapreadGlobals.FirstOrDefault(i => i.Id == 1); if (website != null) { // Will be distributed to all users website.CommunityEarnedToDistribute += comratio * v.a; // And to the website website.ZapReadTotalEarned += webratio * v.a; website.ZapReadEarnedBalance += webratio * v.a; } try { await db.SaveChangesAsync(); } catch (Exception) { return(Json(new { result = "error", message = "Error" })); } return(Json(new { result = "success", delta = 1, score = post.Score, balance = userBalance, scoreStr = post.Score.ToAbbrString() })); } else { // Voted down if (user != null && post.VotesDown.Contains(user)) { //post.VotesDown.Remove(user); //user.PostVotesDown.Remove(post); //post.Score = post.VotesUp.Count() - post.VotesDown.Count(); //return Json(new { result = "success", message = "Already Voted", delta = 0, score = post.Score, balance = user.Funds.Balance }); } else if (user != null) { post.VotesDown.Add(user); user.PostVotesDown.Add(post); } //post.VotesUp.Remove(user); //user.PostVotesUp.Remove(post); post.Score = post.Score - v.a;// post.VotesUp.Count() - post.VotesDown.Count(); // Record and assign earnings // Related to post owner var webratio = 0.1; var comratio = 0.1; var owner = post.UserId; if (owner != null) { owner.Reputation -= v.a; } var postGroup = post.Group; if (postGroup != null) { postGroup.TotalEarnedToDistribute += 0.8 * v.a; } else { comratio += 0.8; } var website = db.ZapreadGlobals.FirstOrDefault(i => i.Id == 1); if (website != null) { // Will be distributed to all users website.CommunityEarnedToDistribute += comratio * v.a; // And to the website website.ZapReadTotalEarned += webratio * v.a; website.ZapReadEarnedBalance += webratio * v.a; } await db.SaveChangesAsync(); return(Json(new { result = "success", delta = -1, score = post.Score, balance = userBalance, scoreStr = post.Score.ToAbbrString() })); } } // All paths have returned }