Example #1
0
        /// <summary>
        /// update the order modify time, but dont save it. this will be used as a message to
        /// re-process the order
        /// </summary>
        /// <param name="utcModTime"></param>
        /// <param name="workingOrderId"></param>
        private static void UpdateOrderModifyTime(DateTime utcModTime, Guid workingOrderId)
        {
            using (TransactionScope transactionScope = new TransactionScope())
            {
                // This provides a context for any transactions.
                DataModelTransaction dataModelTransaction = DataModelTransaction.Current;
                WorkingOrderRow      workingOrderRow      = DataModel.WorkingOrder.WorkingOrderKey.Find(workingOrderId);
                if (workingOrderRow == null)
                {
                    return;
                }

                DataModel dataModel = new DataModel();
                workingOrderRow.AcquireWriterLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                try
                {
                    if (workingOrderRow.RowState == System.Data.DataRowState.Deleted ||
                        workingOrderRow.RowState == System.Data.DataRowState.Detached)
                    {
                        return;
                    }

                    DataModel.DataLock.EnterWriteLock();
                    try
                    {
                        workingOrderRow.BeginEdit();
                        workingOrderRow[DataModel.WorkingOrder.ModifiedTimeColumn] = utcModTime;
                    }
                    finally
                    {
                        workingOrderRow.EndEdit();
                        workingOrderRow.RejectChanges();
                        DataModel.DataLock.ExitWriteLock();
                    }
                }
                finally
                {
                    workingOrderRow.ReleaseWriterLock(dataModelTransaction.TransactionId);
                }
            }
        }
        /// <summary>
        /// Update a consumer.
        /// </summary>
        /// <param name="entity">The ConsumerTrust's Entity row.</param>
        /// <returns>The ConsumerId of the Consumer row.</returns>
        private Guid UpdateConsumer(EntityRow entity)
        {
            DataModel            dataModel            = new DataModel();
            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;
            DateTime             modified             = DateTime.UtcNow;
            CountryRow           country;
            Guid             countryId;
            Guid?            provinceId = null;
            EntityRow        dollars;
            Guid             dollarsId;
            ConsumerRow      consumer      = null;
            ConsumerTrustRow consumerTrust = null;
            SecurityRow      security      = null;
            WorkingOrderRow  workingOrder  = null;

            MatchRow[] matches;
            Guid       consumerId;
            Guid       consumerTrustId;
            Guid       entityId;
            Guid       securityId;
            Guid       workingOrderId;
            Int64      consumerVersion;
            Int64      consumerTrustVersion;
            Int64      entityVersion;
            Int64      securityVersion;
            Int64      workingOrderVersion;
            Boolean    updateConsumer      = false;
            Boolean    updateConsumerTrust = false;
            Boolean    updateEntity        = false;
            Boolean    updateSecurity      = false;

            country = TradingSupport.FindCountryByKey(
                this.Record.ConfigurationId,
                "FK_Country_Security",
                new object[] { this.Record.CountryCode });
            countryId = country.CountryId;
            country.ReleaseReaderLock(dataModelTransaction.TransactionId);

            if (this.Record.ProvinceCode != null)
            {
                ProvinceRow province = TradingSupport.FindProvinceByKey(
                    this.Record.ConfigurationId,
                    "FK_Province_Consumer",
                    new object[] { this.Record.ProvinceCode });
                provinceId = province.ProvinceId;
                province.ReleaseReaderLock(dataModelTransaction.TransactionId);
            }

            dollars = TradingSupport.FindEntityByKey(
                this.Record.ConfigurationId,
                "FK_Security_WorkingOrder_SettlementId",
                new object[] { this.Record.Currency });
            dollarsId = dollars.EntityId;
            dollars.ReleaseReaderLock(dataModelTransaction.TransactionId);

            try
            {
                entity.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                entityId      = entity.EntityId;
                entityVersion = entity.RowVersion;
                if (TradingSupport.IsColumnOld(entity, "Name", this.Record.OriginalAccountNumber))
                {
                    updateEntity = true;
                }
            }
            finally
            {
                entity.ReleaseLock(dataModelTransaction.TransactionId);
            }

            try
            {
                security = DataModel.Security.SecurityKey.Find(entityId);
                security.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                securityId      = entityId;
                securityVersion = security.RowVersion;
                workingOrder    = security.GetWorkingOrderRowsByFK_Security_WorkingOrder_SecurityId()[0];
                if (TradingSupport.IsColumnOld(security, "CountryId", countryId))
                {
                    updateSecurity = true;
                }
            }
            finally
            {
                security.ReleaseLock(dataModelTransaction.TransactionId);
            }


            // Control the working order:
            workingOrder.AcquireWriterLock(dataModelTransaction);

            try
            {
                consumerTrust = DataModel.ConsumerTrust.ConsumerTrustKey.Find(entityId);
                consumerTrust.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                consumerTrustId      = consumerTrust.ConsumerTrustId;
                consumerTrustVersion = consumerTrust.RowVersion;
                consumer             = DataModel.Consumer.ConsumerKey.Find(consumerTrust.ConsumerId);
                if (TradingSupport.IsColumnOld(consumerTrust, "SavingsAccount", this.Record.SavingsAccount) ||
                    TradingSupport.IsColumnOld(consumerTrust, "SavingsBalance", this.Record.SavingsBalance) ||
                    TradingSupport.IsColumnOld(consumerTrust, "Tag", this.Record.Tag))
                {
                    updateConsumerTrust = true;
                }
            }
            finally
            {
                consumerTrust.ReleaseLock(dataModelTransaction.TransactionId);
            }

            try
            {
                consumer.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                consumerId      = consumer.ConsumerId;
                consumerVersion = consumer.RowVersion;
                if (TradingSupport.IsColumnOld(consumer, "Address1", this.Record.Address1) ||
                    TradingSupport.IsColumnOld(consumer, "Address2", this.Record.Address2) ||
                    TradingSupport.IsColumnOld(consumer, "BankAccountNumber", this.Record.BankAccountNumber) ||
                    TradingSupport.IsColumnOld(consumer, "BankRoutingNumber", this.Record.BankRoutingNumber) ||
                    TradingSupport.IsColumnOld(consumer, "City", this.Record.City) ||
                    TradingSupport.IsColumnOld(consumer, "DateOfBirth", this.Record.DateOfBirth) ||
                    TradingSupport.IsColumnOld(consumer, "FirstName", this.Record.FirstName) ||
                    TradingSupport.IsColumnOld(consumer, "IsEmployed", this.Record.IsEmployed) ||
                    TradingSupport.IsColumnOld(consumer, "LastName", this.Record.LastName) ||
                    TradingSupport.IsColumnOld(consumer, "PostalCode", this.Record.PostalCode) ||
                    TradingSupport.IsColumnOld(consumer, "MiddleName", this.Record.MiddleName) ||
                    TradingSupport.IsColumnOld(consumer, "PhoneNumber", this.Record.PhoneNumber) ||
                    TradingSupport.IsColumnOld(consumer, "ProvinceId", provinceId) ||
                    TradingSupport.IsColumnOld(consumer, "SocialSecurityNumber", this.Record.SocialSecurityNumber) ||
                    TradingSupport.IsColumnOld(consumer, "Suffix", this.Record.Suffix))
                {
                    updateConsumer = true;
                }
            }
            finally
            {
                consumer.ReleaseLock(dataModelTransaction.TransactionId);
            }

            try
            {
                //workingOrder.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                workingOrderId      = workingOrder.WorkingOrderId;
                workingOrderVersion = workingOrder.RowVersion;
                matches             = workingOrder.GetMatchRows();
            }
            finally
            {
                //workingOrder.ReleaseLock(dataModelTransaction.TransactionId);
            }

            foreach (MatchRow match in matches)
            {
                if (WorkingOrderPersistence.IsSettled(dataModelTransaction, match))
                {
                    throw new FaultException <SecurityFault>(
                              new SecurityFault("Cannot update account that is settled")
                    {
                        FaultCode = ErrorCode.RecordExists
                    },
                              "Cannot update account that is settled");
                }
            }

            // We need write access to the containing blotter in order to add a record to it.
            if (!TradingSupport.HasAccess(dataModelTransaction, PersistenceHelper.GetBlotterForConsumer(dataModelTransaction, consumerId), AccessRight.Write))
            {
                throw new SecurityException("Current user does not have write access to the original blotter");
            }

            if (updateConsumer)
            {
                dataModel.UpdateConsumer(
                    this.Record.Address1 != null ? (object)this.Record.Address1 : DBNull.Value,
                    this.Record.Address2 != null ? (object)this.Record.Address2 : DBNull.Value,
                    this.Record.BankAccountNumber != null ? (object)this.Record.BankAccountNumber : DBNull.Value,
                    this.Record.BankRoutingNumber != null ? (object)this.Record.BankRoutingNumber : DBNull.Value,
                    this.Record.City != null ? (object)this.Record.City : DBNull.Value,
                    consumerId,
                    new object[] { consumerId },
                    this.Record.DateOfBirth != null ? (object)this.Record.DateOfBirth.Value : DBNull.Value,
                    null,
                    null,
                    this.Record.FirstName != null ? (object)this.Record.FirstName : DBNull.Value,
                    this.Record.IsEmployed != null ? (object)this.Record.IsEmployed.Value : DBNull.Value,
                    this.Record.LastName != null ? (object)this.Record.LastName : DBNull.Value,
                    this.Record.MiddleName != null ? (object)this.Record.MiddleName : DBNull.Value,
                    this.Record.PhoneNumber != null ? (object)StringUtilities.CleanUpAlphaNumericString(this.Record.PhoneNumber) : DBNull.Value,
                    this.Record.PostalCode != null ? (object)this.Record.PostalCode : DBNull.Value,
                    provinceId,
                    consumerVersion,
                    this.Record.Salutation,
                    StringUtilities.CleanUpAlphaNumericString(this.Record.SocialSecurityNumber),
                    this.Record.Suffix != null ? (object)this.Record.Suffix : DBNull.Value);
            }

            if (updateConsumerTrust)
            {
                dataModel.UpdateConsumerTrust(
                    null,
                    consumerTrustId,
                    new object[] { consumerTrustId },
                    null,
                    null,
                    consumerTrustVersion,
                    this.Record.SavingsAccount,
                    this.Record.SavingsBalance,
                    this.Record.Tag != null ? (object)this.Record.Tag : DBNull.Value,
                    null,
                    null);
            }

            if (updateEntity)
            {
                dataModel.UpdateEntity(
                    null,
                    null,
                    entityId,
                    new object[] { entityId },
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    modified,
                    this.Record.SavingsEntityCode,
                    entityVersion,
                    null,
                    null);
            }

            if (updateSecurity)
            {
                dataModel.UpdateSecurity(
                    null,
                    countryId,
                    null,
                    null,
                    null,
                    1,
                    1,
                    securityVersion,
                    securityId,
                    new object[] { securityId },
                    null,
                    null,
                    null);
            }

            dataModel.UpdateWorkingOrder(
                null,
                this.Record.Blotter,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                modified,
                TradingSupport.UserId,
                null,
                workingOrderVersion,
                null,
                null,
                dollarsId,
                null,
                null,
                StatusMap.FromCode(Status.New),
                null,
                null,
                null,
                null,
                null,
                null,
                modified,
                workingOrderId,
                new object[] { workingOrderId });

            return(consumerId);
        }
        /// <summary>
        /// Delete a WorkingOrderRow.
        /// </summary>
        /// <param name="dataModel">The data model.</param>
        /// <param name="transaction">The current transaction.</param>
        /// <param name="workingOrderRow">The working order row to delete.</param>
        /// <returns>Error code of any failure, or Success.</returns>
        public ErrorCode DeleteRow(DataModel dataModel, DataModelTransaction transaction, WorkingOrderRow workingOrderRow)
        {
            SecurityRow securityRow       = null;
            EntityRow   securityEntityRow = null;

            MatchRow[]         matchRows;
            ConsumerDebtRow[]  consumerDebtRows;
            ConsumerTrustRow[] consumerTrustRows;
            CreditCardRow      creditCardRow = null;
            ConsumerRow        consumerRow   = null;
            Guid    blotterId;
            Guid    securityEntityId         = Guid.Empty;
            Int64   securityEntityRowVersion = 0;
            Guid    consumerId           = Guid.Empty;
            Int64   consumerRowVersion   = 0;
            Guid    creditCardId         = Guid.Empty;
            Int64   creditCardRowVersion = 0;
            Boolean consumerStillInUse   = false;

            workingOrderRow.AcquireWriterLock(transaction.TransactionId, DataModel.LockTimeout);
            if (workingOrderRow.RowState == DataRowState.Deleted ||
                workingOrderRow.RowState == DataRowState.Detached)
            {
                workingOrderRow.ReleaseLock(transaction.TransactionId);
                return(ErrorCode.RecordNotFound);
            }
            else
            {
                transaction.AddLock(workingOrderRow);
            }
            blotterId   = workingOrderRow.BlotterId;
            securityRow = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId;
            matchRows   = workingOrderRow.GetMatchRows();

            if (matchRows != null)
            {
                foreach (MatchRow matchRow in matchRows)
                {
                    if (IsSettled(transaction, matchRow))
                    {
                        return(ErrorCode.RecordExists);
                    }
                }
            }

            if (!DataModelFilters.HasAccess(transaction, TradingSupport.UserId, blotterId, AccessRight.Write))
            {
                workingOrderRow.ReleaseLock(transaction.TransactionId);
                return(ErrorCode.AccessDenied);
            }
            securityRow.AcquireWriterLock(transaction.TransactionId, DataModel.LockTimeout);
            if (securityRow.RowState == DataRowState.Deleted ||
                securityRow.RowState == DataRowState.Detached)
            {
                workingOrderRow.ReleaseLock(transaction.TransactionId);
                securityRow.ReleaseWriterLock(transaction.TransactionId);
                return(ErrorCode.RecordNotFound);
            }
            securityEntityRow = securityRow.EntityRow;
            consumerDebtRows  = securityRow.GetConsumerDebtRows();
            consumerTrustRows = securityRow.GetConsumerTrustRows();
            securityRow.ReleaseWriterLock(transaction.TransactionId);

            securityEntityRow.AcquireWriterLock(transaction);
            if (securityEntityRow.RowState == DataRowState.Deleted ||
                securityEntityRow.RowState == DataRowState.Detached)
            {
                workingOrderRow.ReleaseLock(transaction.TransactionId);
                securityEntityRow.ReleaseLock(transaction.TransactionId);
                return(ErrorCode.RecordNotFound);
            }
            securityEntityId         = securityEntityRow.EntityId;
            securityEntityRowVersion = securityEntityRow.RowVersion;
            securityEntityRow.ReleaseLock(transaction.TransactionId);

            if (consumerTrustRows.Length > 0 && consumerDebtRows.Length > 0)
            {
                EventLog.Warning("Deleting a working order associated with both ConsumerDebt and ConsumerTrust rows");
            }
            else if (consumerDebtRows.Length > 1)
            {
                EventLog.Warning("Deleting a working order associated with more than one ConsumerDebt row");
            }
            else if (consumerTrustRows.Length > 1)
            {
                EventLog.Warning("Deleting a working order associated with more than one ConsumerTrust row");
            }

            if (consumerDebtRows.Length == 1)
            {
                ConsumerDebtRow consumerDebtRow = consumerDebtRows[0];

                consumerDebtRow.AcquireWriterLock(transaction);
                if (consumerDebtRow.RowState == DataRowState.Deleted ||
                    consumerDebtRow.RowState == DataRowState.Detached)
                {
                }
                else
                {
                    creditCardRow = consumerDebtRow.CreditCardRow;
                    consumerRow   = consumerDebtRow.ConsumerRow;
                }
                consumerDebtRow.ReleaseLock(transaction.TransactionId);
            }
            else if (consumerTrustRows.Length == 1)
            {
                ConsumerTrustRow consumerTrustRow = consumerTrustRows[0];

                consumerTrustRow.AcquireWriterLock(transaction);
                if (consumerTrustRow.RowState == DataRowState.Deleted ||
                    consumerTrustRow.RowState == DataRowState.Detached)
                {
                }
                else
                {
                    consumerRow = consumerTrustRow.ConsumerRow;
                }
                consumerTrustRow.ReleaseLock(transaction.TransactionId);
            }

            if (consumerRow != null)
            {
                consumerRow.AcquireWriterLock(transaction);
                if (consumerRow.RowState == DataRowState.Deleted ||
                    consumerRow.RowState == DataRowState.Detached)
                {
                    consumerRow = null;
                }
                else
                {
                    consumerStillInUse = consumerRow.GetConsumerDebtRows().Length > 1;
                    consumerId         = consumerRow.ConsumerId;
                    consumerRowVersion = consumerRow.RowVersion;
                }
                consumerRow.ReleaseLock(transaction.TransactionId);
            }

            if (creditCardRow != null)
            {
                creditCardRow.AcquireWriterLock(transaction);
                if (creditCardRow.RowState == DataRowState.Deleted ||
                    creditCardRow.RowState == DataRowState.Detached)
                {
                    creditCardRow = null;
                }
                else
                {
                    creditCardId         = creditCardRow.ConsumerId;
                    creditCardRowVersion = creditCardRow.RowVersion;
                }
                creditCardRow.ReleaseLock(transaction.TransactionId);
            }

            //gonna get the lock on the workingOrder and let the txn commit/rollback get rid of it
            //this will basically wrap the delete row
            //action in a critical section because the first
            //reader lock in the method is on the workingOrder row
            //workingOrderRow.AcquireWriterLock(transaction.TransactionId, DataModel.LockTimeout);
            if (workingOrderRow.RowState == DataRowState.Deleted ||
                workingOrderRow.RowState == DataRowState.Detached)
            {
                workingOrderRow.ReleaseLock(transaction.TransactionId);
                return(ErrorCode.RecordNotFound);
            }
            //securityRow.AcquireWriterLock(transaction.TransactionId, DataModel.LockTimeout);
            //if(securityRow.RowState == DataRowState.Deleted ||
            //        securityRow.RowState == DataRowState.Detached)
            //{
            //    workingOrderRow.ReleaseLock(transaction.TransactionId);
            //    return ErrorCode.RecordNotFound;
            //}
            if (creditCardRow != null && consumerStillInUse)
            {
                dataModel.DestroyCreditCard(new object[] { creditCardId }, creditCardRowVersion);
            }
            if (consumerRow != null && !consumerStillInUse)
            {
                dataModel.DestroyConsumer(new object[] { consumerId }, consumerRowVersion);
            }

            dataModel.DestroyEntity(new object[] { securityEntityId }, securityEntityRowVersion);

            return(ErrorCode.Success);
        }