/// <summary>
        /// Creates a Splitwise transaction with specified, or random values.
        /// </summary>
        /// <param name="context">The database context.</param>
        /// <param name="id">The identifier.</param>
        /// <param name="description">The description.</param>
        /// <param name="date">The date.</param>
        /// <param name="isDeleted">A value indicating if the expense is deleted.</param>
        /// <param name="updatedAt">The updated at timestamp.</param>
        /// <param name="paidAmount">The paid amount.</param>
        /// <param name="personalAmount">The personal amount.</param>
        /// <param name="imported">The imported value.</param>
        /// <param name="splits">The splits.</param>
        /// <returns>The created expense.</returns>
        public static SplitwiseTransactionEntity GenerateSplitwiseTransaction(
            this Context context,
            int id                          = 0,
            string description              = null,
            LocalDate?date                  = null,
            bool isDeleted                  = false,
            DateTime?updatedAt              = null,
            decimal paidAmount              = 10,
            decimal personalAmount          = 5,
            bool imported                   = false,
            List <SplitDetailEntity> splits = null)
        {
            var expense = new SplitwiseTransactionEntity
            {
                Id             = id,
                Description    = description ?? GetRandomString(),
                Date           = date ?? DateTime.Today.ToLocalDate(),
                IsDeleted      = isDeleted,
                UpdatedAt      = updatedAt ?? DateTime.Now,
                PaidAmount     = paidAmount,
                PersonalAmount = personalAmount,
                Imported       = imported,
                SplitDetails   = splits ?? new List <SplitDetailEntity>(),
            };

            context.SplitwiseTransactions.Add(expense);

            return(expense);
        }
예제 #2
0
        /// <summary>
        /// Converts a Splitwise transaction to a transfer transaction. Creates a transaction with the correct type.
        /// Also marks the Splitwise transaction as imported.
        /// </summary>
        /// <param name="entity">The Splitwise transaction.</param>
        /// <param name="splitwiseAccount">The Spltiwise account.</param>
        /// <param name="internalAccount">The receiving/sending account.</param>
        /// <returns>The created transaction.</returns>
        public static TransactionEntity ToTransaction(
            this SplitwiseTransactionEntity entity, AccountEntity splitwiseAccount, AccountEntity internalAccount)
        {
            entity.Imported = true;

            var transaction = new TransactionEntity
            {
                Description            = entity.Description,
                Date                   = entity.Date,
                SplitwiseTransactionId = entity.Id,
                SplitwiseTransaction   = entity,
                PaymentRequests        = new List <PaymentRequestEntity>(),
                SplitDetails           = entity.SplitDetails,
                Type                   = TransactionType.Transfer,
            };

            if (entity.PaidAmount > 0)
            {
                transaction.Account            = internalAccount;
                transaction.AccountId          = internalAccount.Id;
                transaction.ReceivingAccount   = splitwiseAccount;
                transaction.ReceivingAccountId = splitwiseAccount.Id;
                transaction.Amount             = entity.PaidAmount;
            }
            else
            {
                transaction.Account            = splitwiseAccount;
                transaction.AccountId          = splitwiseAccount.Id;
                transaction.ReceivingAccount   = internalAccount;
                transaction.ReceivingAccountId = internalAccount.Id;
                transaction.Amount             = entity.PersonalAmount;
            }

            return(transaction);
        }
예제 #3
0
        /// <summary>
        /// Converts a Splitwise transaction to a normal transaction. Creates a transaction with the correct type.
        /// Also marks the Splitwise transaction as imported.
        /// </summary>
        /// <param name="entity">The Splitwise transaction.</param>
        /// <param name="account">The account to be linked to the transaction.</param>
        /// <param name="category">The category to be linked to the transaction.</param>
        /// <returns>The created transaction.</returns>
        public static TransactionEntity ToTransaction(
            this SplitwiseTransactionEntity entity, AccountEntity account, CategoryEntity category)
        {
            entity.Imported = true;

            var transaction = new TransactionEntity
            {
                Description            = entity.Description,
                Date                   = entity.Date,
                AccountId              = account.Id,
                Account                = account,
                CategoryId             = category.Id,
                Category               = category,
                SplitwiseTransactionId = entity.Id,
                SplitwiseTransaction   = entity,
                PaymentRequests        = new List <PaymentRequestEntity>(),
                SplitDetails           = entity.SplitDetails,
            };

            if (entity.PaidAmount > 0 && account.Type == AccountType.Splitwise)
            {
                transaction.Type   = TransactionType.Income;
                transaction.Amount = entity.PaidAmount - entity.PersonalAmount;
            }
            else
            {
                transaction.Type   = TransactionType.Expense;
                transaction.Amount = -entity.PaidAmount;
            }

            return(transaction);
        }
예제 #4
0
 /// <summary>
 /// Updates the values of a Splitwise transaction with the values from an expense.
 /// </summary>
 /// <param name="entity">The Splitwise transaction entity to be updated.</param>
 /// <param name="expense">The expense.</param>
 public static void UpdateValues(this SplitwiseTransactionEntity entity, SW.Expense expense)
 {
     entity.Id             = expense.Id;
     entity.Date           = expense.Date;
     entity.Description    = expense.Description;
     entity.IsDeleted      = expense.IsDeleted;
     entity.UpdatedAt      = expense.UpdatedAt;
     entity.PaidAmount     = expense.PaidAmount;
     entity.PersonalAmount = expense.PersonalAmount;
     entity.Imported       = false;
 }
예제 #5
0
 /// <summary>
 /// Converts the entity to a data transfer object.
 /// </summary>
 /// <param name="entity">The entity.</param>
 /// <returns>The data transfer object.</returns>
 public static SplitwiseTransaction AsSplitwiseTransaction(this SplitwiseTransactionEntity entity)
 {
     return(new SplitwiseTransaction
     {
         Id = entity.Id,
         Description = entity.Description,
         Date = entity.Date,
         IsDeleted = entity.IsDeleted,
         Imported = entity.Imported,
         PaidAmount = entity.PaidAmount,
         PersonalAmount = entity.PersonalAmount,
     });
 }
        /// <summary>
        /// Verifies that a Splitwise transaction is processable. This is the case when the transaction has been
        /// imported and is not deleted.
        /// </summary>
        /// <param name="transaction">The entity to verify.</param>
        public static void VerifyProcessable(this SplitwiseTransactionEntity transaction)
        {
            if (!transaction.Imported)
            {
                throw new InvalidOperationException(
                          "This Splitwise transaction is not imported and should therefore not be processed.");
            }

            if (transaction.IsDeleted)
            {
                throw new InvalidOperationException(
                          "This Splitwise transaction is marked deleted and should therefore not be processed.");
            }
        }
예제 #7
0
        /// <summary>
        /// Reverses the processing of a Splitwise transaction. Meaning that the Splitwise account balances are updated
        /// if needed.
        /// </summary>
        /// <param name="transaction">The Splitwise transaction.</param>
        private void Revert(SplitwiseTransactionEntity transaction)
        {
            transaction.VerifyProcessable();

            var splitwiseAccount = this.Context.Accounts.GetSplitwiseEntity();

            var(historicalEntriesToEdit, _) =
                this.GetBalanceEntriesToEdit(splitwiseAccount.Id, transaction.Date);

            var mutationAmount = transaction.GetSplitwiseAccountDifference();

            foreach (var entry in historicalEntriesToEdit)
            {
                entry.Balance -= mutationAmount;
            }
        }
        /// <summary>
        /// Creates a transaction with specified, or random values.
        /// </summary>
        /// <param name="context">The database context.</param>
        /// <param name="account">The account.</param>
        /// <param name="type">The type of the transaction.</param>
        /// <param name="description">The description of the transaction.</param>
        /// <param name="date">The date of the transaction.</param>
        /// <param name="amount">The amount.</param>
        /// <param name="category">The category.</param>
        /// <param name="receivingAccount">The receiving account.</param>
        /// <param name="recurringTransaction">The recurring transaction from which this is an instance.</param>
        /// <param name="splitwiseTransaction">The Splitwise transaction which is linked to this transaction.</param>
        /// <param name="paymentRequests">The payment requests that are linked to this transaction.</param>
        /// <param name="splitDetails">The split details which are linked to this transaction.</param>
        /// <param name="needsConfirmation">A value indicating if the transaction has to be confirmed.</param>
        /// <returns>The created transaction.</returns>
        public static TransactionEntity GenerateTransaction(
            this Context context,
            AccountEntity account,
            TransactionType type           = TransactionType.Expense,
            string description             = null,
            LocalDate?date                 = null,
            decimal?amount                 = null,
            CategoryEntity category        = null,
            AccountEntity receivingAccount = null,
            RecurringTransactionEntity recurringTransaction = null,
            SplitwiseTransactionEntity splitwiseTransaction = null,
            List <PaymentRequestEntity> paymentRequests     = null,
            List <SplitDetailEntity> splitDetails           = null,
            bool needsConfirmation = false)
        {
            if ((type == TransactionType.Expense || type == TransactionType.Income) && category == null)
            {
                throw new Exception("Specify a category for an income or expense transaction.");
            }
            if (type == TransactionType.Transfer && receivingAccount == null)
            {
                throw new Exception("Specify a receiving account for a transfer transaction.");
            }

            return(context.Transactions.Add(new TransactionEntity
            {
                Account = account,
                Amount = amount ?? (type == TransactionType.Expense ? -50 : 50),
                Description = description ?? GetRandomString(),
                Date = date ?? DateTime.Now.ToLocalDate(),
                Category = category,
                ReceivingAccount = receivingAccount,
                NeedsConfirmation = needsConfirmation,
                PaymentRequests = paymentRequests ?? new List <PaymentRequestEntity>(),
                SplitDetails = splitDetails ?? new List <SplitDetailEntity>(),
                Processed = false,
                IsConfirmed = !needsConfirmation,
                Type = type,
                RecurringTransaction = recurringTransaction,
                SplitwiseTransaction = splitwiseTransaction,
            }).Entity);
        }
예제 #9
0
        /// <summary>
        /// Processes a Splitwise transaction. Meaning that the Splitwise account balances are updated if needed.
        /// </summary>
        /// <param name="transaction">The Splitwise transaction.</param>
        /// <param name="addedDailyBalances">The daily balances that were already added. This is needed since the
        /// context does not contain already added entities, resulting in possible double daily balances which results
        /// in an error.</param>
        private void Process(
            SplitwiseTransactionEntity transaction, List <DailyBalanceEntity> addedDailyBalances, TransactionType type)
        {
            transaction.VerifyProcessable();

            var splitwiseAccount = this.Context.Accounts.GetSplitwiseEntity();

            var(historicalEntriesToEdit, newHistoricalEntry) =
                this.GetBalanceEntriesToEdit(splitwiseAccount.Id, transaction.Date, addedDailyBalances);
            if (newHistoricalEntry.IsSome)
            {
                addedDailyBalances.Add(newHistoricalEntry.Value);
            }
            var mutationAmount = transaction.GetSplitwiseAccountDifference();

            foreach (var entry in historicalEntriesToEdit)
            {
                entry.Balance += mutationAmount;
            }
        }
 /// <summary>
 /// Gets the amount with which the Splitwise account should be updated. This can either be negative
 /// (in the case that something is owed to others) positive (when someone else owes something to me).
 /// </summary>
 /// <param name="entity">The transaction entity.</param>
 /// <returns>The mutation for the Splitwise account.</returns>
 public static decimal GetSplitwiseAccountDifference(this SplitwiseTransactionEntity entity)
 {
     return(-entity.OwedToOthers + entity.OwedByOthers);
 }