/// <summary> /// Verifies that the entities linked to a recurring transaction are not obsolete. /// </summary> /// <param name="transaction">The transaction.</param> /// <param name="splitwiseContext">The Splitwise context.</param> public static void VerifyEntitiesNotObsolete( this RecurringTransactionEntity transaction, ISplitwiseContext splitwiseContext) { if (transaction.Account == null) { throw new ArgumentNullException(nameof(transaction.Account)); } if (transaction.ReceivingAccountId.HasValue && transaction.ReceivingAccount == null) { throw new ArgumentNullException(nameof(transaction.ReceivingAccount)); } if (transaction.CategoryId.HasValue && transaction.Category == null) { throw new ArgumentNullException(nameof(transaction.Category)); } if (transaction.Account.IsObsolete) { throw new IsObsoleteException($"Account is obsolete."); } if (transaction.ReceivingAccountId.HasValue && transaction.ReceivingAccount.IsObsolete) { throw new IsObsoleteException($"Receiver is obsolete."); } if (transaction.CategoryId.HasValue && transaction.Category.IsObsolete) { throw new IsObsoleteException($"Category is obsolete."); } var currentSplitwiseUserIds = splitwiseContext.GetUsers().Select(u => u.Id).ToList(); foreach (var splitDetail in transaction.SplitDetails) { if (!currentSplitwiseUserIds.Contains(splitDetail.SplitwiseUserId)) { throw new IsObsoleteException("Splitwise user is obsolete."); } } }
/// <summary> /// Validates a list of payment requests and Splitwise splits. /// </summary> /// <param name="splitwiseContext">The Splitwise context.</param> /// <param name="paymentRequests">The list of payment requests.</param> /// <param name="splitwiseSplits">The list of Splitwise splits.</param> /// <param name="type">The type of the transaction.</param> /// <param name="totalAmount">The amount of the transaction.</param> public void Splits( ISplitwiseContext splitwiseContext, List <InputPaymentRequest> paymentRequests, List <InputSplitwiseSplit> splitwiseSplits, TransactionType type, decimal totalAmount) { if (!paymentRequests.Any() && !splitwiseSplits.Any()) { return; } totalAmount = Math.Abs(totalAmount); var sumPaymentRequests = paymentRequests.Sum(pr => pr.Count * pr.Amount); var sumSplitwiseSplits = splitwiseSplits.Sum(s => s.Amount); var personalAmount = totalAmount - sumSplitwiseSplits; if (type != TransactionType.Expense) { throw new ValidationException( "Payment requests and Splitwise splits can only be specified on expenses."); } if (sumSplitwiseSplits > totalAmount) { throw new ValidationException( "The amount split can not exceed the total amount of the transaction."); } if (sumPaymentRequests > personalAmount) { throw new ValidationException( $"The amount of the payment requests ({sumPaymentRequests}) can not exceed the personal " + $"amount ({personalAmount})"); } if (splitwiseSplits.Any(s => s.Amount <= 0)) { throw new ValidationException("Splits must have an amount greater than 0."); } var inputtedUserIds = splitwiseSplits.Select(s => s.UserId).ToSet(); if (inputtedUserIds.Count != splitwiseSplits.Count) { throw new ValidationException("A user can only be linked to a single split."); } var splitwiseUserIds = splitwiseContext.GetUsers().Select(u => u.Id).ToSet(); if (!inputtedUserIds.IsSubsetOf(splitwiseUserIds)) { throw new ValidationException("Unknown Splitwise user(s) specified."); } foreach (var paymentRequest in paymentRequests) { if (paymentRequest.Count <= 0) { throw new ValidationException("A payment request must at least have 1 requested payment."); } if (string.IsNullOrWhiteSpace(paymentRequest.Name)) { throw new ValidationException("A payment request must specify a name."); } if (paymentRequest.Amount <= 0) { throw new ValidationException("A payment request must have an amount greater than 0."); } } }