Пример #1
0
        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!");
            }
        }
Пример #2
0
        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!");
            }
        }
Пример #3
0
        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)) });
            }
        }
Пример #4
0
        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}`)");
        }
Пример #5
0
        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}`");
            }
        }
Пример #6
0
        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();
            }
        }
Пример #7
0
        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();
            }
        }