public ErrorCode DeleteRow(DataModel dataModel, DataModelTransaction transaction, DebtRuleRow debtRuleRow) { debtRuleRow.AcquireReaderLock(transaction); DebtRuleMapRow[] debtRuleMaps = debtRuleRow.GetDebtRuleMapRows(); if (debtRuleRow.GetDebtClassRows().Length != 0) { return(ErrorCode.AccessDenied); } debtRuleRow.ReleaseReaderLock(transaction.TransactionId); foreach (DebtRuleMapRow debtRuleMapRow in debtRuleMaps) { debtRuleMapRow.AcquireReaderLock(transaction); if (!DataModelFilters.HasAccess(transaction, TradingSupport.UserId, debtRuleMapRow.DebtClassId, AccessRight.Write)) { return(ErrorCode.AccessDenied); } debtRuleMapRow.ReleaseReaderLock(transaction.TransactionId); } debtRuleRow.AcquireWriterLock(transaction); dataModel.DestroyDebtRule(new object[] { debtRuleRow.DebtRuleId }, debtRuleRow.RowVersion); debtRuleRow.ReleaseLock(transaction.TransactionId); return(ErrorCode.Success); }
/// <summary> /// Construct a service that provides a shared, in-memory data model. /// </summary> public Service() { // Initialize the object. this.ServiceName = serviceName; try { // This Windows Service can host one or many WCF Endpoints. They are started and stopped as a unit. this.serviceHosts = new List <ServiceHost>(); this.serviceHosts.Add(new ServiceHost(typeof(ServerAdmin), new Uri[] { })); this.serviceHosts.Add(new ServiceHost(typeof(ServerAdminCallbackManager), new Uri[] { })); this.serviceHosts.Add(new ServiceHost(typeof(ServerAdminStreamManager), new Uri[] { })); this.serviceHosts.Add(new ServiceHost(typeof(AdminSupport), new Uri[] { })); this.serviceHosts.Add(new ServiceHost(typeof(DataModel), new Uri[] { })); this.serviceHosts.Add(new ServiceHost(typeof(TradingSupport), new Uri[] { })); this.dataModelFilters = new DataModelFilters(); this.settlementDocumentFactory = new SettlementDocumentFactory(); } catch (Exception exception) { // Any problems initializing should be sent to the Event Log. EventLog.WriteEntry( Service.source, string.Format("{0}: {1}", exception.Message, exception.StackTrace), EventLogEntryType.Error); } }
/// <summary> /// Create a new Credit card /// </summary> /// <returns></returns> public override Guid Create(CreditCard record) { DataModel dataModel = new DataModel(); DataModelTransaction transaction = DataModelTransaction.Current; Guid blotterId = this.FindContainingBlotter(transaction, record.ConsumerId.GetValueOrDefault()); Guid tenantId = PersistenceHelper.GetTenantForEntity( transaction, blotterId); if (!DataModelFilters.HasAccess(transaction, TradingSupport.UserId, blotterId, AccessRight.Write)) { throw new SecurityAccessDeniedException("The current user does not write permission to the selected blotter"); } Guid ccId = Guid.NewGuid(); ////Create a entry in credit card dataModel.CreateCreditCard( record.AccountBalance, record.AccountNumber, record.ConsumerId.GetValueOrDefault(), ccId, record.DebtHolder, record.DebtRuleId, Guid.NewGuid().ToString(), record.AccountNumber, record.OriginalAccountNumber, tenantId); return(ccId); }
/// <summary> /// Update Credit Card /// </summary> /// <returns></returns> public override void Update(CreditCard record) { DataModel dataModel = new DataModel(); DataModelTransaction transaction = DataModelTransaction.Current; Guid blotterId = this.FindContainingBlotter(transaction, record.RowId); if (record.RowId == null || DataModel.CreditCard.CreditCardKey.Find(record.RowId) == null) { throw new FaultException <RecordNotFoundFault>(new RecordNotFoundFault("Credit Card", new object[] { record.RowId })); } if (!DataModelFilters.HasAccess(transaction, TradingSupport.UserId, blotterId, AccessRight.Write)) { throw new SecurityAccessDeniedException("The current user does not write permission to the selected blotter"); } dataModel.UpdateCreditCard( record.AccountBalance, record.AccountNumber, record.ConsumerId, null, new object[] { record.RowId }, record.DebtHolder, record.DebtRuleId, null, record.AccountNumber, record.OriginalAccountNumber, record.RowVersion, null); }
/// <summary> /// Grant a particular rights holder specific rights to an entity. /// </summary> /// <param name="rightsHolderId">The rights holder's id.</param> /// <param name="entityId">The entity's id.</param> /// <param name="rightId">The specific right's id.</param> /// <returns>The id of the AccessControl row.</returns> internal static Guid GrantAccess(Guid rightsHolderId, Guid entityId, Guid rightId) { DataModelTransaction transaction = DataModelTransaction.Current; DataModel dataModel = new DataModel(); Guid currentUserId = TradingSupport.UserId; UserRow currentUserRow = DataModel.User.UserKey.Find(currentUserId); RightsHolderRow rightsHolderRow = DataModel.RightsHolder.RightsHolderKey.Find(rightsHolderId); Guid rightsHolderTenantId; AccessControlRow accessControlRow = DataModel.AccessControl.AccessControlKeyRightsHolderIdEntityId.Find(rightsHolderId, entityId); Guid accessControlId = Guid.Empty; // Determine whether current user has write access to the entity. if (!DataModelFilters.HasAccess(transaction, currentUserId, entityId, AccessRight.Write)) { throw new FaultException <SecurityFault>( new SecurityFault(String.Format("{0} does not write permission to {1}", rightsHolderId, entityId))); } rightsHolderRow.AcquireReaderLock(transaction); rightsHolderTenantId = rightsHolderRow.TenantId; rightsHolderRow.ReleaseReaderLock(transaction.TransactionId); // Determine whether current user's tenant is upstream from rights holder we're modifying. if (!DataModelFilters.HasTenantAccess(transaction, currentUserId, rightsHolderTenantId)) { throw new FaultException <SecurityFault>( new SecurityFault(String.Format("{0} does not control over tenant {1}", rightsHolderId, rightsHolderTenantId))); } if (accessControlRow != null) { accessControlRow.AcquireWriterLock(transaction); accessControlId = accessControlRow.AccessControlId; dataModel.UpdateAccessControl( accessControlRow.AccessControlId, new object[] { accessControlRow.AccessControlId }, rightId, entityId, rightsHolderId, accessControlRow.RowVersion, rightsHolderTenantId); } else { accessControlId = Guid.NewGuid(); dataModel.CreateAccessControl( accessControlId, rightId, entityId, rightsHolderId, rightsHolderTenantId); } return(accessControlId); }
/// <summary> /// Placeholder /// </summary> /// <param name="record"></param> public override void Update(EntityTree record) { DataModel dataModel = new DataModel(); DataModelTransaction transaction = DataModelTransaction.Current; EntityTreeRow entityTreeRow = DataModel.EntityTree.EntityTreeKey.Find(record.RowId); EntityRow child = DataModel.Entity.EntityKey.Find(record.ChildId); EntityRow parent = DataModel.Entity.EntityKey.Find(record.ParentId); String childName; entityTreeRow.AcquireWriterLock(transaction); if (!DataModelFilters.HasAccess(transaction, TradingSupport.UserId, entityTreeRow.ParentId, AccessRight.Write)) { throw new SecurityException("Current user does not have write access to the old parent entity"); } if (!DataModelFilters.HasAccess(transaction, TradingSupport.UserId, record.ParentId, AccessRight.Write)) { throw new SecurityException("Current user does not have write access to the new parent entity"); } parent.AcquireWriterLock(transaction); child.AcquireReaderLock(transaction); childName = child.Name; child.ReleaseLock(transaction.TransactionId); if (record.ChildId == record.ParentId) { throw new FaultException <ArgumentFault>(new ArgumentFault("Create EntityTree"), new FaultReason(String.Format("Cannot add {0} as a child of this element because it wil create a circular relationship", childName))); } if (IsParentEntity(transaction, parent, record.ChildId) == true) { throw new FaultException <ArgumentFault>(new ArgumentFault("Create EntityTree"), new FaultReason(String.Format("Cannot add {0} as a child of this element because it wil create a circular relationship", childName))); } if (!EntityPersistence.IsNameUnique(transaction, parent, childName)) { throw new FaultException <RecordExistsFault>( new RecordExistsFault("Entity", new object[] { childName }), "An entity with this name already exists"); } dataModel.UpdateEntityTree( record.ChildId, entityTreeRow.EntityTreeId, new object[] { entityTreeRow.EntityTreeId }, null, record.ParentId, entityTreeRow.RowVersion); }
/// <summary> /// Revoke any and all access a rights holder has to an entity. /// </summary> /// <param name="rightsHolderId">The rights holder's id.</param> /// <param name="entityId">The entity's id.</param> /// <returns>The error code.</returns> internal static ErrorCode RevokeAccess(Guid rightsHolderId, Guid entityId) { DataModelTransaction transaction = DataModelTransaction.Current; DataModel dataModel = new DataModel(); Guid currentUserId = TradingSupport.UserId; UserRow currentUserRow = DataModel.User.UserKey.Find(currentUserId); RightsHolderRow rightsHolderRow = DataModel.RightsHolder.RightsHolderKey.Find(rightsHolderId); Guid rightsHolderTenantId; AccessControlRow accessControlRow = DataModel.AccessControl.AccessControlKeyRightsHolderIdEntityId.Find(rightsHolderId, entityId); // Determine whether current user has write access to the entity. if (!DataModelFilters.HasAccess(transaction, currentUserId, entityId, AccessRight.Write)) { return(ErrorCode.AccessDenied); } rightsHolderRow.AcquireReaderLock(transaction); rightsHolderTenantId = rightsHolderRow.TenantId; rightsHolderRow.ReleaseReaderLock(transaction.TransactionId); // Determine whether current user's tenant is upstream from rights holder we're modifying. if (!DataModelFilters.HasTenantAccess(transaction, currentUserId, rightsHolderTenantId)) { return(ErrorCode.AccessDenied); } if (accessControlRow != null) { accessControlRow.AcquireWriterLock(transaction); dataModel.DestroyAccessControl(new object[] { accessControlRow.AccessControlId }, accessControlRow.RowVersion); } else { return(ErrorCode.RecordNotFound); } return(ErrorCode.Success); }
/// <summary> /// Remove an entity tree link between to entities. /// </summary> /// <param name="record"></param> /// <returns></returns> public override FluidTrade.Core.ErrorCode Delete(EntityTree record) { DataModel dataModel = new DataModel(); DataModelTransaction transaction = DataModelTransaction.Current; EntityTreeRow entityTreeRow = DataModel.EntityTree.EntityTreeKey.Find(record.RowId); Guid parentEntityId; if (entityTreeRow == null) { return(ErrorCode.RecordNotFound); } entityTreeRow.AcquireWriterLock(transaction); parentEntityId = entityTreeRow.ParentId; if (!DataModelFilters.HasAccess(transaction, TradingSupport.UserId, parentEntityId, AccessRight.Write)) { return(ErrorCode.AccessDenied); } dataModel.DestroyEntityTree(new object[] { record.RowId }, record.RowVersion); return(ErrorCode.Success); }
public override void Update(DebtRule record) { DataModel dataModelClient = new DataModel(); DataModelTransaction transaction = DataModelTransaction.Current; DebtRuleRow debtRuleRow = DataModel.DebtRule.DebtRuleKey.Find(record.RowId); DebtRuleMapRow[] debtRuleMapRows; List <Guid> paymentMethod = record.PaymentMethod.ToList(); if (record.RowId == null || debtRuleRow == null) { throw new FaultException <RecordNotFoundFault>(new RecordNotFoundFault("DebtRule", new object[] { record.RowId }), "DebtRule could not be found"); } debtRuleRow.AcquireReaderLock(transaction); debtRuleMapRows = debtRuleRow.GetDebtRuleMapRows(); // There really should be at most one of these, but there may be none. foreach (DebtRuleMapRow debtRuleMapRow in debtRuleMapRows) { debtRuleMapRow.AcquireReaderLock(transaction); if (!DataModelFilters.HasAccess(transaction, TradingSupport.UserId, debtRuleMapRow.DebtClassId, AccessRight.Write)) { throw new SecurityAccessDeniedException("Current user does not have right access to the debt class that owns this debt rule"); } debtRuleMapRow.ReleaseLock(transaction.TransactionId); } foreach (DebtRulePaymentMethodRow methodRow in debtRuleRow.GetDebtRulePaymentMethodRows()) { methodRow.AcquireReaderLock(transaction); if (paymentMethod.Contains(methodRow.PaymentMethodTypeId)) { paymentMethod.Remove(methodRow.PaymentMethodTypeId); } else { dataModelClient.DestroyDebtRulePaymentMethod(new object[] { methodRow.DebtRulePaymentMethodId }, methodRow.RowVersion); } methodRow.ReleaseLock(transaction.TransactionId); } foreach (Guid method in paymentMethod) { dataModelClient.CreateDebtRulePaymentMethod(record.RowId, Guid.NewGuid(), method); } debtRuleRow.ReleaseLock(transaction.TransactionId); dataModelClient.UpdateDebtRule( null, new object[] { record.RowId }, null, record.IsAutoSettled, record.Name, record.PaymentLength, record.PaymentStartDateLength, record.PaymentStartDateUnitId, record.RowVersion, record.SettlementUnitId, record.SettlementValue); debtRuleRow.ReleaseLock(transaction.TransactionId); }
/// <summary> /// Create a new DebtRule /// </summary> /// <returns></returns> public override Guid Create(DebtRule record) { DataModel dataModelClient = new DataModel(); Guid debtRuleId = Guid.NewGuid(); // These fields are required by this method, but not by the record itself, so bark if they're missing. if (record.IsAutoSettled == null) { throw new FaultException("IsAutoSettled cannot be null"); } if (record.Owner == null) { throw new FaultException("Owner cannot be null"); } if (record.PaymentLength == null) { throw new FaultException("PaymentLength cannot be null"); } if (record.PaymentMethod == null) { throw new FaultException("SettlementValue cannot be null"); } if (record.PaymentStartDateLength == null) { throw new FaultException("PaymentStartDateLength cannot be null"); } if (record.PaymentStartDateUnitId == null) { throw new FaultException("PaymentStartDateUnitId cannot be null"); } if (record.SettlementUnitId == null) { throw new FaultException("SettlementUnitId cannot be null"); } if (record.SettlementValue == null) { throw new FaultException("SettlementValue cannot be null"); } if (!DataModelFilters.HasAccess(DataModelTransaction.Current, TradingSupport.UserId, record.Owner.Value, AccessRight.Write)) { throw new SecurityAccessDeniedException("Current user does not have right access to the debt class that would own this debt rule"); } dataModelClient.CreateDebtRule( debtRuleId, null, record.IsAutoSettled, record.Name, record.PaymentLength.Value, record.PaymentStartDateLength.Value, record.PaymentStartDateUnitId.Value, record.SettlementUnitId.Value, record.SettlementValue.Value); dataModelClient.CreateDebtRuleMap(record.Owner.Value, debtRuleId, Guid.NewGuid(), null); foreach (Guid paymentMethod in record.PaymentMethod) { dataModelClient.CreateDebtRulePaymentMethod(debtRuleId, Guid.NewGuid(), paymentMethod); } return(debtRuleId); }
/// <summary> /// Create a new Debt Holder Record /// </summary> /// <returns></returns> internal Guid Create() { DataModel dataModel = new DataModel(); DataModelTransaction dataModelTransaction = DataModelTransaction.Current; Guid userId = TradingSupport.UserId; Guid tenantId = PersistenceHelper.GetTenantForEntity(dataModelTransaction, this.Record.Blotter); Guid entityId = Guid.Empty; Guid consumerId; Guid creditCardId; Guid workingOrderId; CountryRow country; Guid countryId; Guid? provinceId = null; TypeRow type; Guid typeId; ImageRow image; Guid imageId; // These variables are used for auditing the changes to this record. DateTime createdTime = DateTime.UtcNow; Guid createdUserId = TradingSupport.UserId; DateTime modifiedTime = createdTime; Guid modifiedUserId = createdUserId; EntityRow dollars; Guid dollarsId; // We need write access to the containing blotter in order to add a record to it. if (!DataModelFilters.HasAccess(dataModelTransaction, userId, this.Record.Blotter, AccessRight.Write)) { throw new SecurityException("Current user does not have write access to the selected blotter"); } 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); image = TradingSupport.FindImageByKey( this.Record.ConfigurationId, "FK_Image_Entity", new object[] { "OBJECT" }); imageId = image.ImageId; image.ReleaseReaderLock(dataModelTransaction.TransactionId); type = TradingSupport.FindTypeByKey( this.Record.ConfigurationId, "FK_Type_Entity", new object[] { "CONSUMER DEBT" }); typeId = type.TypeId; type.ReleaseReaderLock(dataModelTransaction.TransactionId); entityId = Guid.NewGuid(); consumerId = Guid.NewGuid(); creditCardId = Guid.NewGuid(); workingOrderId = Guid.NewGuid(); dataModel.CreateEntity( createdTime, null, entityId, null, null, null, null, null, null, null, this.Record.AccountCode, imageId, false, false, modifiedTime, this.Record.OriginalAccountNumber, tenantId, typeId); dataModel.CreateSecurity( null, countryId, null, null, null, 1, 1, entityId, this.Record.AccountCode, tenantId, VolumeCategoryMap.FromCode(VolumeCategory.Unknown)); dataModel.CreateConsumer( this.Record.Address1, this.Record.Address2, null, null, this.Record.City, consumerId, this.Record.DateOfBirth != null ? (object)this.Record.DateOfBirth.Value : null, null, null, this.Record.FirstName, null, this.Record.LastName, this.Record.MiddleName, StringUtilities.CleanUpAlphaNumericString(this.Record.PhoneNumber), this.Record.PostalCode, provinceId, null, StringUtilities.CleanUpAlphaNumericString(this.Record.SocialSecurityNumber), this.Record.Suffix); dataModel.CreateCreditCard( this.Record.AccountBalance, this.Record.AccountCode, consumerId, creditCardId, this.Record.DebtHolder, null, null, this.Record.AccountCode, StringUtilities.CleanUpAlphaNumericString(this.Record.OriginalAccountNumber), tenantId); dataModel.CreateConsumerDebt( this.Record.CollectionDate, entityId, consumerId, creditCardId, this.Record.DateOfDelinquency != null ? (object)this.Record.DateOfDelinquency.Value : null, null, null, this.Record.Representative, this.Record.Tag, tenantId, this.Record.VendorCode); dataModel.CreateWorkingOrder( null, this.Record.Blotter, createdTime, createdUserId, CrossingMap.FromCode(Crossing.AlwaysMatch), null, null, null, null, true, true, true, null, modifiedTime, modifiedUserId, OrderTypeMap.FromCode(OrderType.Market), entityId, createdTime, dollarsId, SideMap.FromCode(Side.Sell), createdTime, StatusMap.FromCode(Status.New), null, null, null, null, TimeInForceMap.FromCode(TimeInForce.GoodTillCancel), createdTime, createdTime, workingOrderId); // Create the access control record for this new entity. dataModel.CreateAccessControl( Guid.NewGuid(), AccessRightMap.FromCode(AccessRight.FullControl), entityId, userId, tenantId); return(entityId); }
/// <summary> /// If a matching consumer debt record already exists, update the account with this, rather than creating a new one. /// </summary> /// <param name="entity">The entity row of the consumer debt record.</param> /// <returns>The entityId.</returns> internal Guid Update(EntityRow entity) { DataModel dataModel = new DataModel(); DataModelTransaction dataModelTransaction = DataModelTransaction.Current; CountryRow country; Guid countryId; Guid? provinceId = null; EntityRow dollars; Guid dollarsId; ConsumerRow consumer; ConsumerDebtRow consumerDebt; CreditCardRow creditCard; SecurityRow security; WorkingOrderRow workingOrder; Guid consumerId; Guid consumerDebtId = entity.EntityId; Guid creditCardId; Guid entityId = entity.EntityId; Guid securityId = entity.EntityId; Guid workingOrderId; Int64 consumerVersion; Int64 consumerDebtVersion; Int64 creditCardVersion; Int64 entityVersion = entity.RowVersion; Int64 securityVersion; Int64 workingOrderVersion; Boolean updateConsumer = false; Boolean updateConsumerDebt = false; Boolean updateCreditCard = false; Boolean updateEntity = false; Boolean updateSecurity = false; DateTime currentUTCTime = DateTime.UtcNow; entity.ReleaseReaderLock(dataModelTransaction.TransactionId); // We need write access to the containing blotter in order to add a record to it. if (!DataModelFilters.HasAccess(dataModelTransaction, TradingSupport.UserId, this.Record.Blotter, AccessRight.Write)) { throw new SecurityException("Current user does not have write access to the selected blotter"); } #if false // We need write access to the consumer debt's entity in order to update it. if (!TradingSupport.HasAccess(dataModelTransaction, entityId, AccessRight.Write)) { throw new SecurityException("Current user does not have write access to the selected consumer debt"); } #endif // Via the country row... country = TradingSupport.FindCountryByKey( this.Record.ConfigurationId, "FK_Country_Security", new object[] { this.Record.CountryCode }); countryId = country.CountryId; country.ReleaseReaderLock(dataModelTransaction.TransactionId); // ... get the province Id. 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); } // Get the USD security Id. dollars = TradingSupport.FindEntityByKey( this.Record.ConfigurationId, "FK_Security_WorkingOrder_SettlementId", new object[] { this.Record.Currency }); dollarsId = dollars.EntityId; dollars.ReleaseReaderLock(dataModelTransaction.TransactionId); // See if the entity needs to be updated. entity.AcquireReaderLock(dataModelTransaction); entityVersion = entity.RowVersion; if (TradingSupport.IsColumnOld(entity, "Name", this.Record.OriginalAccountNumber)) { updateEntity = true; } entity.ReleaseLock(dataModelTransaction.TransactionId); // Get security's children see if we need to update securityRow. security = DataModel.Security.SecurityKey.Find(entityId); security.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); securityVersion = security.RowVersion; consumerDebt = DataModel.ConsumerDebt.ConsumerDebtKey.Find(security.SecurityId); workingOrder = security.GetWorkingOrderRowsByFK_Security_WorkingOrder_SecurityId()[0]; if (TradingSupport.IsColumnOld(security, "CountryId", countryId)) { updateSecurity = true; } security.ReleaseLock(dataModelTransaction.TransactionId); // Control the working order: workingOrder.AcquireWriterLock(dataModelTransaction); // Get the consumer debt's children and see if we need to update the consumer debt. consumerDebt.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); consumerDebtVersion = consumerDebt.RowVersion; creditCard = DataModel.CreditCard.CreditCardKey.Find(consumerDebt.CreditCardId); if (TradingSupport.IsColumnOld(consumerDebt, "DateOfDelinquency", this.Record.DateOfDelinquency) || TradingSupport.IsColumnOld(consumerDebt, "Representative", this.Record.Representative) || TradingSupport.IsColumnOld(consumerDebt, "Tag", this.Record.Tag)) { updateConsumerDebt = true; } consumerDebt.ReleaseLock(dataModelTransaction.TransactionId); creditCard.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); creditCardId = creditCard.CreditCardId; creditCardVersion = creditCard.RowVersion; consumer = DataModel.Consumer.ConsumerKey.Find(creditCard.ConsumerId); if (TradingSupport.IsColumnOld(creditCard, "AccountBalance", this.Record.AccountBalance) || TradingSupport.IsColumnOld(creditCard, "AccountNumber", this.Record.AccountCode) || TradingSupport.IsColumnOld(creditCard, "DebtHolder", this.Record.DebtHolder) || TradingSupport.IsColumnOld(creditCard, "OriginalAccountNumber", this.Record.OriginalAccountNumber)) { updateCreditCard = true; } creditCard.ReleaseLock(dataModelTransaction.TransactionId); 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, "City", this.Record.City) || TradingSupport.IsColumnOld(consumer, "DateOfBirth", this.Record.DateOfBirth) || TradingSupport.IsColumnOld(consumer, "FirstName", this.Record.FirstName) || 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; } consumer.ReleaseLock(dataModelTransaction.TransactionId); workingOrder.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); workingOrderId = workingOrder.WorkingOrderId; workingOrderVersion = workingOrder.RowVersion; //workingOrder.ReleaseLock(dataModelTransaction.TransactionId); // 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, null, null, 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, null, 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, null, StringUtilities.CleanUpAlphaNumericString(this.Record.SocialSecurityNumber), this.Record.Suffix != null ? (object)this.Record.Suffix : DBNull.Value); } if (updateConsumerDebt) { dataModel.UpdateConsumerDebt( null, consumerDebtId, new object[] { consumerDebtId }, null, null, this.Record.DateOfDelinquency != null ? (object)this.Record.DateOfDelinquency.Value : DBNull.Value, null, null, this.Record.Representative != null ? (object)this.Record.Representative : DBNull.Value, consumerDebtVersion, this.Record.Tag != null ? (object)this.Record.Tag : DBNull.Value, null, null); } if (updateCreditCard) { dataModel.UpdateCreditCard( this.Record.AccountBalance, this.Record.AccountCode, null, creditCardId, new object[] { creditCardId }, this.Record.DebtHolder, null, null, null, StringUtilities.CleanUpAlphaNumericString(this.Record.OriginalAccountNumber), creditCardVersion, null); } if (updateEntity) { dataModel.UpdateEntity( null, null, entityId, new object[] { entityId }, null, null, null, null, null, null, null, null, null, null, null, currentUTCTime, this.Record.OriginalAccountNumber, 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, currentUTCTime, TradingSupport.UserId, null, workingOrderVersion, null, null, dollarsId, null, null, null, null, null, null, null, null, null, currentUTCTime, workingOrderId, new object[] { workingOrderId }); return(entityId); }
/// <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); }
/// <summary> /// Delete a credit card /// </summary> /// <returns>True for sucess</returns> public override ErrorCode Delete(CreditCard record) { DataModel dataModel = new DataModel(); DataModelTransaction transaction = DataModelTransaction.Current; CreditCardRow creditCardRow = DataModel.CreditCard.CreditCardKey.Find(record.RowId); WorkingOrderRow workingOrderRow = null; MatchRow[] matchRows; Guid blotterId; if (record.RowId == null || creditCardRow == null) { return(ErrorCode.RecordNotFound); } workingOrderRow = this.FindWorkingOrder(transaction, record.RowId); workingOrderRow.AcquireReaderLock(transaction); matchRows = workingOrderRow.GetMatchRows(); blotterId = workingOrderRow.BlotterId; workingOrderRow.ReleaseLock(transaction.TransactionId); if (!DataModelFilters.HasAccess(transaction, TradingSupport.UserId, blotterId, AccessRight.Write)) { return(ErrorCode.AccessDenied); } MatchPersistence matchPersistence = new MatchPersistence(); foreach (MatchRow matchRow in matchRows) { matchRow.AcquireReaderLock(transaction); Records.Match matchRecord = new Records.Match() { RowId = matchRow.MatchId, RowVersion = matchRow.RowVersion }; ConsumerTrustNegotiationRow[] consumerTrustNegotiationRows = matchRow.GetConsumerTrustNegotiationRows(); ConsumerDebtNegotiationRow[] consumerDebtNegotiationRows = matchRow.GetConsumerDebtNegotiationRows(); matchRow.ReleaseLock(transaction.TransactionId); foreach (ConsumerTrustNegotiationRow negotiationRow in consumerTrustNegotiationRows) { negotiationRow.AcquireReaderLock(transaction); Guid negRowCreditCardId = negotiationRow.CreditCardId; negotiationRow.ReleaseLock(transaction.TransactionId); if (negRowCreditCardId == record.RowId) { if (MatchDataTable.IsSettled(transaction, matchRow, true) == true) { return(ErrorCode.RecordExists); } matchPersistence.Delete(matchRecord); break; } } } dataModel.DestroyCreditCard( new object[] { record.RowId }, record.RowVersion); return(ErrorCode.Success); }
/// <summary> /// Create most of a debt class. This should be kicked off by children of DebtClass. /// </summary> /// <param name="record">The record, complete with TypeId and ImageId.</param> /// <returns>The entityId of the new debt class.</returns> public override Guid Create(DebtClass record) { DataModel dataModel = new DataModel(); TypeRow typeRow = DataModel.Type.TypeKey.Find(record.TypeId.Value); EntityRow parentEntity; AssetViewerTemplateRow[] templates; Guid entityId = Guid.Empty; Guid organizationId = Guid.Empty; DateTime createdTime = DateTime.UtcNow; DataModelTransaction dataModelTransaction = DataModelTransaction.Current; Guid ruleId = Guid.NewGuid(); entityId = Guid.NewGuid(); if (record.ParentId == null) { throw new FaultException <ArgumentFault>(new ArgumentFault("Parent EntityId not specified"), "Parent EntityId not specified"); } if (!DataModelFilters.HasAccess(dataModelTransaction, TradingSupport.UserId, record.ParentId.Value, AccessRight.Write)) { throw new FaultException <SecurityFault>( new SecurityFault("The current user doesn't have write permission to the specified parent"), "The current user doesn't have write permission to the specified parent"); } parentEntity = DataModel.Entity.EntityKey.Find(record.ParentId.Value); typeRow.AcquireReaderLock(dataModelTransaction); templates = typeRow.GetAssetViewerTemplateRows(); if (record.ImageId == null && !typeRow.IsImageIdNull()) { record.ImageId = typeRow.ImageId; } typeRow.ReleaseReaderLock(dataModelTransaction.TransactionId); if (record.ImageId == null) { ImageRow imageRow = DataModel.Image[0]; imageRow.AcquireReaderLock(dataModelTransaction); record.ImageId = imageRow.ImageId; imageRow.ReleaseReaderLock(dataModelTransaction.TransactionId); } parentEntity.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); try { record.Name = this.GetUniqueName(dataModelTransaction, parentEntity, record.Name as String); } finally { parentEntity.ReleaseReaderLock(dataModelTransaction.TransactionId); } dataModel.CreateEntity( createdTime, record.Description, entityId, Guid.NewGuid().ToString(), null, null, null, null, null, null, Guid.NewGuid().ToString(), record.ImageId.Value, false, false, createdTime, record.Name, record.TenantId.GetValueOrDefault(), record.TypeId.Value); dataModel.CreateEntityTree(entityId, Guid.NewGuid(), null, record.ParentId.Value); dataModel.CreateBlotter(entityId, PartyTypeMap.FromCode(PartyType.UseParent)); foreach (AssetViewerTemplateRow template in templates) { template.AcquireReaderLock(dataModelTransaction); dataModel.CreateBlotterConfiguration(Guid.NewGuid(), entityId, null, template.ReportId, template.ReportTypeId); template.ReleaseReaderLock(dataModelTransaction.TransactionId); } dataModel.CreateDebtClass( record.Address1, record.Address2, record.BankAccountNumber, record.BankRoutingNumber, record.City, null, record.CompanyName, record.ContactName, entityId, record.DebtRuleId, record.Department, record.Email, record.Fax, record.ForBenefitOf, record.Phone, record.PostalCode, record.Province, null); organizationId = this.FindOrganization(dataModelTransaction); Guid tenantId = record.TenantId.HasValue ? record.TenantId.GetValueOrDefault() : organizationId; PersistenceHelper.AddGroupPermissions(dataModel, dataModelTransaction, organizationId, entityId, tenantId); dataModel.CreateAccessControl( Guid.NewGuid(), AccessRightMap.FromCode(AccessRight.FullControl), entityId, TradingSupport.UserId, tenantId); return(entityId); }
/// <summary> /// Delete a debt holder /// </summary> /// <returns>True for sucess</returns> public override ErrorCode Delete(DebtNegotiator record) { DataModel dataModel = new DataModel(); DataModelTransaction transaction = DataModelTransaction.Current; WorkingOrderPersistence workingOrderPersistence = new WorkingOrderPersistence(); DebtRulePersistence debtRulePersistence = new DebtRulePersistence(); DebtNegotiatorRow debtNegotiatorRow = DataModel.DebtNegotiator.DebtNegotiatorKey.Find(record.RowId); // If/when we get these translations, we'll need this stuff. //DebtNegotiatorImportTranslationRow debtNegotiatorImportTranslationRow; DebtClassRow debtClassRow; BlotterRow blotterRow; WorkingOrderRow[] workingOrderRows; DebtRuleMapRow[] debtRuleMapRows; EntityRow entityRow; EntityTreeRow[] children; Guid entityId; Int64 entityRowVersion; //Guid debtNegotiatorImportTranslationId = Guid.Empty; //Int64 debtNegotiatorImportTranslationRowVersion = 0; if (record.RowId == null || debtNegotiatorRow == null) { return(ErrorCode.RecordNotFound); } if (!DataModelFilters.HasAccess(transaction, TradingSupport.UserId, record.RowId, AccessRight.Write)) { return(ErrorCode.AccessDenied); } debtNegotiatorRow.AcquireReaderLock(transaction); debtClassRow = debtNegotiatorRow.DebtClassRow; //debtNegotiatorImportTranslationRow = debtNegotiatorRow.DebtNegotiatorImportTranslationRow; debtNegotiatorRow.ReleaseReaderLock(transaction.TransactionId); #if false // If/when we get these translations, we'll need this stuff. if (debtHolderImportTranslationRow != null) { debtNegotiatorImportTranslationRow.AcquireReaderLock(transaction); debtNegotiatorImportTranslationId = debtNegotiatorImportTranslationRow.DebtNegotiatorImportTranslationId; debtNegotiatorImportTranslationRowVersion = debtNegotiatorImportTranslationRow.RowVersion; debtNegotiatorImportTranslationRow.ReleaseReaderLock(transaction.TransactionId); } #endif debtClassRow.AcquireReaderLock(transaction); blotterRow = debtClassRow.BlotterRow; debtRuleMapRows = debtClassRow.GetDebtRuleMapRows(); debtClassRow.ReleaseReaderLock(transaction.TransactionId); blotterRow.AcquireReaderLock(transaction); entityRow = blotterRow.EntityRow; workingOrderRows = blotterRow.GetWorkingOrderRows(); blotterRow.ReleaseLock(transaction.TransactionId); entityRow.AcquireReaderLock(transaction); children = entityRow.GetEntityTreeRowsByFK_Entity_EntityTree_ParentId(); entityId = entityRow.EntityId; entityRowVersion = entityRow.RowVersion; entityRow.ReleaseReaderLock(transaction.TransactionId); // Fail if the debt class has any children. if (children.Length != 0) { return(ErrorCode.AccessDenied); } // Destroy the import translation. //if (debtHolderImportTranslationRow != null) // dataModel.DestroyDebtNegotiatorImportTranslation(new object[] { debtNegotiatorImportTranslationId }, debtNegotiatorImportTranslationRowVersion); // Delete any rules this debt class may own. foreach (DebtRuleMapRow debtRuleMapRow in debtRuleMapRows) { DebtRuleRow debtRuleRow; debtRuleMapRow.AcquireReaderLock(transaction); debtRuleRow = debtRuleMapRow.DebtRuleRow; debtRuleMapRow.ReleaseReaderLock(transaction.TransactionId); debtRulePersistence.DeleteRow(dataModel, transaction, debtRuleRow); } // Delete any working orders this debt class may contain. foreach (WorkingOrderRow workingOrderRow in workingOrderRows) { workingOrderPersistence.DeleteRow(dataModel, transaction, workingOrderRow); } // Delete the entity itself. dataModel.DestroyEntity(new object[] { entityId }, entityRowVersion); return(ErrorCode.Success); }
/// <summary> /// Update Consumer Debt Payment Record /// </summary> /// <param name="record"></param> public override void Update(ConsumerDebtPayment record) { DataModel dataModel = new DataModel(); //Use the current transaction DataModelTransaction transaction = DataModelTransaction.Current; Guid userId = TradingSupport.UserId; //Use the deamonUser so that Modified user can be resolved from the other side of the chinese firewall. Guid deamonUser = TradingSupport.DaemonUserId; Guid blotterId; Int64 contraPaymentRowVersion; //Sanity Check ConsumerDebtPaymentRow consumerDebtPaymentRow = DataModel.ConsumerDebtPayment.ConsumerDebtPaymentKey.Find(record.RowId); if (consumerDebtPaymentRow == null) { throw new FaultException <RecordNotFoundFault>(new RecordNotFoundFault("ConsumerDebtPayment", new object[] { record.RowId })); } consumerDebtPaymentRow.AcquireWriterLock(transaction.TransactionId, DataModel.LockTimeout); try { blotterId = consumerDebtPaymentRow.BlotterId; } finally { consumerDebtPaymentRow.ReleaseReaderLock(transaction.TransactionId); } if (!DataModelFilters.HasAccess(transaction, userId, blotterId, AccessRight.Write)) { throw new FaultException <SecurityFault>(new SecurityFault("Current user does not have write access to the payment summary")); } ConsumerTrustPaymentRow consumerTrustPaymentRow = DataModel.ConsumerTrustPayment.ConsumerTrustPaymentKey.Find(record.RowId); consumerTrustPaymentRow.AcquireReaderLock(transaction.TransactionId, DataModel.LockTimeout); try { contraPaymentRowVersion = consumerTrustPaymentRow.RowVersion; } finally { consumerTrustPaymentRow.ReleaseLock(transaction.TransactionId); } dataModel.UpdateConsumerDebtPayment( record.ActualPaymentDate == null? DBNull.Value : (object)record.ActualPaymentDate.Value, record.ActualPaymentValue == null ? DBNull.Value : (object)record.ActualPaymentValue.Value, null, record.CheckId, record.ClearedDate, record.RowId, new object[] { record.RowId }, null, null, null, null, null, null, record.Fee0 == null ? DBNull.Value : (object)record.Fee0, null, null, null, record.IsActive, record.IsCleared, record.Memo0, record.Memo1, record.Memo2, record.Memo3, DateTime.UtcNow, userId, record.RowVersion, record.StatusId, record.TrackingNumber); //Update Contra side dataModel.UpdateConsumerTrustPayment( record.ActualPaymentDate == null ? DBNull.Value : (object)record.ActualPaymentDate.Value, record.ActualPaymentValue == null ? DBNull.Value : (object)record.ActualPaymentValue.Value, null, record.CheckId, record.ClearedDate, null, new object[] { record.RowId }, null, null, null, null, null, record.Fee0 == null ? DBNull.Value : (object)record.Fee0, null, null, null, record.IsActive, record.IsCleared, record.Memo0, record.Memo1, record.Memo2, record.Memo3, DateTime.UtcNow, deamonUser, contraPaymentRowVersion, record.StatusId, record.TrackingNumber); }