public async Task CreatePendingPayment(IUser user, decimal amount, string unit, [Remainder] string?note = null) { if (amount < 0) { await TypingReplyAsync("You cannot pay a negative amount!"); } else { var id = await _pending.CreatePending(Context.User.Id, user.Id, amount, unit, note, DateTime.UtcNow); var fid = new BalderHash32(id).ToString(); await TypingReplyAsync($"{user.Mention} type `!confirm {fid}` to confirm that you have been paid this"); await TypingReplyAsync($"{user.Mention} type `!deny {fid}` to deny that you received this payment. Please talk to the other user about why!"); } }
public async Task CreatePendingUoi(IUser user, decimal amount, string unit, [Remainder] string?note = null) { if (amount < 0) { await RespondAsync("You cannot owe a negative amount!"); } else { var id = await _pending.CreatePending(Context.User.Id, user.Id, amount, unit, note, DateTime.UtcNow); var fid = new BalderHash32(id).ToString(); await RespondAsync($"{user.Mention} type `/confirm {fid}` to confirm that you owe this"); await FollowupAsync($"{user.Mention} type `/deny {fid}` to deny that you owe this. Please talk to the other user about why!"); } }
private async Task PaginatedPending(IAsyncEnumerable <IPendingTransaction> pending, string none, string paginatedHeader, bool mentionReceiver) { async Task <string> FormatSinglePending(IPendingTransaction p, bool longForm) { var receiver = await _users.Name(p.ToId, mention : mentionReceiver); var payer = await _users.Name(p.FromId); var note = string.IsNullOrEmpty(p.Note) ? "" : $"'{p.Note}'"; var amount = TransactionFormatting.FormatCurrency(p.Amount, p.Unit); var fid = new BalderHash32(p.Id).ToString(); if (longForm) { return($"{receiver} Type `!confirm {fid}` or `!deny {fid}` to confirm/deny transaction of {amount} from {payer} {note}"); } else { return($"`{fid}`: {payer} paid {amount} to {receiver} {note}"); } } var pendingArr = await pending.ToListAsync(); var formatted = new List <string>(); var longForm = pendingArr.Count < 5; foreach (var item in pendingArr) { formatted.Add(await FormatSinglePending(item, longForm)); } if (pendingArr.Count == 0) { await TypingReplyAsync(none); } else if (longForm) { await ReplyAsync(string.Join("\n", formatted)); } else { await TypingReplyAsync(string.Format(paginatedHeader, pendingArr.Count)); await PagedReplyAsync(new PaginatedMessage { Pages = formatted.Batch(7).Select(d => string.Join("\n", d)) }); } }
private async Task <string> CreateReminder(ICommandContext context, string message) { DateTime triggerMoment; // Parse a moment from message var exactTimeResult = FuzzyParsing.Moment(message); if (exactTimeResult.IsValid) { if (exactTimeResult.Value < DateTime.UtcNow) { return(PastValueErrorMessage.Replace("$moment$", exactTimeResult.Value.ToString(CultureInfo.InvariantCulture))); } triggerMoment = exactTimeResult.Value; } else { // Attempt to parse a time range instead of an exact time (e.g. `next week`) var rangeTimeResult = FuzzyParsing.MomentRange(message); if (!rangeTimeResult.IsValid) { return("That doesn't seem to be a valid moment."); } // Send the reminder just after the start of the range triggerMoment = rangeTimeResult.Value.Item1 + (rangeTimeResult.Value.Item2 - rangeTimeResult.Value.Item1) * 0.05f; } var duration = triggerMoment - DateTime.UtcNow; // Add some context to the message var prelude = $"{context.Message.Author.Mention} Reminder from {DateTime.UtcNow.Humanize(dateToCompareAgainst: triggerMoment, culture: CultureInfo.GetCultureInfo("en-gn"))}..."; var msg = $"remind me {message}"; // Save to database var n = await _reminders.Create(triggerMoment, prelude, msg, context.Message.Channel.Id, context.User.Id); var friendlyId = new BalderHash32(n.ID); return($"I will remind you in {duration.Humanize(2, maxUnit: TimeUnit.Year, minUnit: TimeUnit.Second, toWords: true)} (id: `{friendlyId}`)"); }
public async Task CancelReminder(string id) { var parsed = BalderHash32.Parse(id); if (!parsed.HasValue) { await TypingReplyAsync("Invalid ID"); return; } if (await _reminders.Delete(Context.User.Id, parsed.Value.Value)) { await TypingReplyAsync($"Deleted reminder `{id}`"); } else { await TypingReplyAsync($"I can't find a reminder with id `{id}`"); } }
public async Task Confirm(string input) { var fid = BalderHash32.Parse(input); if (!fid.HasValue) { await TypingReplyAsync("Invalid ID `{id}`"); return; } var transactions = await _pending.Get(debtId : fid.Value.Value).ToArrayAsync(); if (transactions.Length == 0) { await TypingReplyAsync($"Cannot find a transaction with ID `{fid}`"); return; } if (transactions.Length > 1) { await TypingReplyAsync($"Found multiple transactions with ID `{fid}`! This is probably an error, please report it."); return; } var transaction = transactions[0]; if (transaction.ToId != Context.User.Id) { await TypingReplyAsync("You cannot confirm this transaction"); return; } var result = await _pending.ConfirmPending(fid.Value.Value); switch (result) { case ConfirmResult.Confirmed: await TypingReplyAsync($"Confirmed {await transaction.Format(_users)}"); break; case ConfirmResult.AlreadyDenied: await TypingReplyAsync("This transaction has already been denied and cannot be confirmed"); break; case ConfirmResult.AlreadyConfirmed: await TypingReplyAsync("This transaction has already been confirmed"); break; case ConfirmResult.IdNotFound: await TypingReplyAsync($"Cannot find a transaction with ID `{fid}`! This is probably an error, please report it."); break; default: await TypingReplyAsync($"Unknown transaction state `{result}`! This is probably an error, please report it."); throw new ArgumentOutOfRangeException(); } }
public async Task Deny(string input) { var fid = BalderHash32.Parse(input); if (!fid.HasValue) { await RespondAsync($"Invalid ID `{fid}`"); return; } var transactions = await _pending.Get(debtId : fid.Value.Value).ToListAsync(); if (transactions.Count == 0) { await RespondAsync($"Cannot find a transaction with ID `{fid}`"); return; } if (transactions.Count > 1) { await RespondAsync($"Found multiple transactions with ID `{fid}`! This is probably an error, please report it."); return; } var transaction = transactions[0]; if (transaction.ToId != Context.User.Id) { await RespondAsync("You cannot deny a transaction which does not belong to you"); return; } var result = await _pending.DenyPending(fid.Value.Value); switch (result) { case DenyResult.Denied: await RespondAsync($"Denied {await transaction.Format(_users, true)}"); break; case DenyResult.AlreadyDenied: await RespondAsync("This transaction has already been denied"); break; case DenyResult.AlreadyConfirmed: await RespondAsync("This transaction has already been confirmed and can no longer be denied"); break; case DenyResult.IdNotFound: await RespondAsync($"Cannot find a transaction with ID `{fid}`! This is probably an error, please report it."); break; default: await RespondAsync($"Unknown transaction state `{result}`! This is probably an error, please report it."); throw new ArgumentOutOfRangeException(); } }