Ejemplo n.º 1
0
 /// <summary>
 /// Releases the lock on the associated <see cref="SharpBooks.Transaction" />.
 /// </summary>
 /// <param name="disposing">Indicates whether or not to dispose of managed resources.  Pass true to dispose managed and unmanaged resources, or false to just dispose unmanaged ones.</param>
 private void Dispose(bool disposing)
 {
     if (disposing)
     {
         if (this.Transaction != null)
         {
             this.Transaction.Unlock(this);
             this.Transaction = null;
         }
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SharpBooks.TransactionData"/> class.
        /// </summary>
        /// <param name="transaction">The <see cref="SharpBooks.Transaction"/> from which to copy.</param>
        public TransactionData(Transaction transaction)
        {
            if (transaction == null)
            {
                throw new ArgumentNullException("transaction");
            }

            this.TransactionId = transaction.TransactionId;
            this.Date = transaction.Date;
            this.BaseSecurityId = transaction.BaseSecurity.SecurityId;
            this.Splits = (from s in transaction.Splits
                           select new SplitData(s)).ToList().AsReadOnly();
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Removes a transaction from all of the respective balances.
        /// </summary>
        /// <param name="transaction">The transaction being removed.</param>
        private void RemoveTransactionFromBalances(Transaction transaction)
        {
            foreach (var split in transaction.Splits)
            {
                var acct = split.Account;
                var balance = this.balances[acct];
                var newBal = balance.CombineWith(split.Security, -split.Amount, isExact: true);

                if (newBal != balance)
                {
                    this.balances[acct] = newBal;

                    while (acct != null)
                    {
                        this.totalBalances.Remove(acct);
                        acct = acct.ParentAccount;
                    }
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Replaces a transaction in a <see cref="Book"/> with an updated copy of the same transaction.
        /// </summary>
        /// <param name="oldTransaction">The transaction that should be replaced.</param>
        /// <param name="newTransaction">The transaction that will replace the old transaction.</param>
        public void ReplaceTransaction(Transaction oldTransaction, Transaction newTransaction)
        {
            lock (this.lockMutex)
            {
                if (oldTransaction == null)
                {
                    throw new ArgumentNullException("oldTransaction");
                }

                if (newTransaction == null)
                {
                    throw new ArgumentNullException("newTransaction");
                }

                if (oldTransaction.TransactionId != newTransaction.TransactionId)
                {
                    throw new InvalidOperationException("The new transaction given may not replace the old transaction, because they do not share the same TransactionId.");
                }

                TransactionLock oldTransactionLock;
                if (!this.transactions.TryGetValue(oldTransaction, out oldTransactionLock))
                {
                    throw new InvalidOperationException("Could not remove the transaction from the book, because the transaction is not a member of the book.");
                }

                TransactionLock newTransactionLock = null;

                try
                {
                    newTransactionLock = newTransaction.Lock();

                    if (!newTransaction.IsValid)
                    {
                        throw new InvalidOperationException("Could not replace the transaction in the book, because the new transaction is not valid.");
                    }

                    var splitsWithoutAccountsInBook = from s in newTransaction.Splits
                                                      where !this.accounts.Contains(s.Account)
                                                      select s;

                    if (splitsWithoutAccountsInBook.Any())
                    {
                        throw new InvalidOperationException(
                            "Could not replace the transaction in the book, because the new transaction contains at least one split whose account has not been added.");
                    }

                    var splitsWithoutSecurityInBook = from s in newTransaction.Splits
                                                      where s.Account.Security == null
                                                      where !this.securities.Contains(s.Security)
                                                      select s;

                    if (splitsWithoutSecurityInBook.Any())
                    {
                        throw new InvalidOperationException(
                            "Could not add the transaction to the book, because the transaction contains at least one split whose security has not been added.");
                    }

                    oldTransactionLock.Dispose();

                    this.transactions.Remove(oldTransaction);
                    this.transactions.Add(newTransaction, newTransactionLock);

                    this.UpdateSaveTracks(st => st.RemoveTransaction(oldTransaction.TransactionId));
                    this.UpdateSaveTracks(st => st.AddTransaction(new TransactionData(newTransaction)));

                    newTransactionLock = null;
                }
                finally
                {
                    if (newTransactionLock != null)
                    {
                        newTransactionLock.Dispose();
                    }
                }

                this.RemoveTransactionFromBalances(oldTransaction);
                this.AddTransactionToBalances(newTransaction);
            }

            this.TransactionRemoved.SafeInvoke(this, new TransactionRemovedEventArgs(oldTransaction));
            this.TransactionAdded.SafeInvoke(this, new TransactionAddedEventArgs(newTransaction));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Removes a transaction from the <see cref="Book"/>.
        /// </summary>
        /// <param name="transaction">The transaction to remove.</param>
        public void RemoveTransaction(Transaction transaction)
        {
            lock (this.lockMutex)
            {
                if (transaction == null)
                {
                    throw new ArgumentNullException("transaction");
                }

                TransactionLock transactionLock;
                if (!this.transactions.TryGetValue(transaction, out transactionLock))
                {
                    throw new InvalidOperationException("Could not remove the transaction from the book, because the transaction is not a member of the book.");
                }

                transactionLock.Dispose();
                this.transactions.Remove(transaction);
                this.transactionIds.Remove(transaction.TransactionId);
                this.UpdateSaveTracks(st => st.RemoveTransaction(transaction.TransactionId));

                this.RemoveTransactionFromBalances(transaction);
            }

            this.TransactionRemoved.SafeInvoke(this, new TransactionRemovedEventArgs(transaction));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Adds a transaction to the <see cref="Book"/>.
        /// </summary>
        /// <param name="transaction">The transaction to add.</param>
        public void AddTransaction(Transaction transaction)
        {
            lock (this.lockMutex)
            {
                if (transaction == null)
                {
                    throw new ArgumentNullException("transaction");
                }

                if (this.transactions.ContainsKey(transaction))
                {
                    throw new InvalidOperationException("Could not add the transaction to the book, because the transaction already belongs to the book.");
                }

                if (this.transactionIds.Contains(transaction.TransactionId))
                {
                    throw new InvalidOperationException(
                        "Could not add the transaction to the book, because another transaction has already been added with the same Transaction Id.");
                }

                TransactionLock transactionLock = null;

                try
                {
                    transactionLock = transaction.Lock();

                    if (!transaction.IsValid)
                    {
                        throw new InvalidOperationException("Could not add the transaction to the book, because the transaction is not valid.");
                    }

                    var splitsWithoutAccountsInBook = from s in transaction.Splits
                                                      where !this.accounts.Contains(s.Account)
                                                      select s;

                    if (splitsWithoutAccountsInBook.Any())
                    {
                        throw new InvalidOperationException(
                            "Could not add the transaction to the book, because the transaction contains at least one split whose account has not been added.");
                    }

                    var splitsWithoutSecurityInBook = from s in transaction.Splits
                                                      where s.Account.Security == null
                                                      where !this.securities.Contains(s.Security)
                                                      select s;

                    if (splitsWithoutSecurityInBook.Any())
                    {
                        throw new InvalidOperationException(
                            "Could not add the transaction to the book, because the transaction contains at least one split whose security has not been added.");
                    }

                    this.transactions.Add(transaction, transactionLock);
                    this.transactionIds.Add(transaction.TransactionId);
                    this.UpdateSaveTracks(st => st.AddTransaction(new TransactionData(transaction)));
                    transactionLock = null;
                }
                finally
                {
                    if (transactionLock != null)
                    {
                        transactionLock.Dispose();
                    }
                }

                this.AddTransactionToBalances(transaction);
            }

            this.TransactionAdded.SafeInvoke(this, new TransactionAddedEventArgs(transaction));
        }
Ejemplo n.º 7
0
        public Transaction Copy()
        {
            lock (this.lockMutex)
            {
                var tNew = new Transaction(this.TransactionId, this.BaseSecurity);
                using (var tLock = tNew.Lock())
                {
                    tNew.SetDate(this.Date, tLock);

                    foreach (var split in this.splits)
                    {
                        var sNew = tNew.AddSplit(tLock);
                        sNew.SetAccount(split.Account, tLock);
                        sNew.SetAmount(split.Amount, tLock);
                        sNew.SetDateCleared(split.DateCleared, tLock);
                        sNew.SetIsReconciled(split.IsReconciled, tLock);
                        sNew.SetSecurity(split.Security, tLock);
                        sNew.SetTransactionAmount(split.TransactionAmount, tLock);
                    }
                }

                return tNew;
            }
        }
Ejemplo n.º 8
0
 internal Split(Transaction transaction)
 {
     this.Transaction = transaction;
     this.Amount = 0;
     this.TransactionAmount = 0;
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SharpBooks.TransactionLock"/> class.
 /// </summary>
 /// <param name="transaction">The <see cref="SharpBooks.Transaction" /> to which the lock belongs.</param>
 internal TransactionLock(Transaction transaction)
 {
     this.Transaction = transaction;
 }
Ejemplo n.º 10
0
        public void AddTransaction(TransactionData transaction)
        {
            lock (this)
            {
                var baseSecurity = this.destinationBook.Securities.Where(s => s.SecurityId == transaction.BaseSecurityId).Single();

                var newTransaction = new Transaction(
                    transaction.TransactionId,
                    baseSecurity);

                using (var tlock = newTransaction.Lock())
                {
                    newTransaction.SetDate(transaction.Date, tlock);

                    foreach (var split in transaction.Splits)
                    {
                        var newSplit = newTransaction.AddSplit(tlock);

                        var account = this.destinationBook.Accounts.Where(a => a.AccountId == split.AccountId).Single();
                        var security = this.destinationBook.Securities.Where(s => s.SecurityId == split.SecurityId).Single();

                        newSplit.SetAccount(account, tlock);
                        newSplit.SetSecurity(security, tlock);
                        newSplit.SetAmount(split.Amount, tlock);
                        newSplit.SetTransactionAmount(split.TransactionAmount, tlock);
                        newSplit.SetDateCleared(split.DateCleared, tlock);
                        newSplit.SetIsReconciled(split.IsReconciled, tlock);
                    }
                }

                this.destinationBook.AddTransaction(
                    newTransaction);
            }
        }