/// <summary> /// Adds the transaction item to search index. Can also be used for updating existing items by specifying the Transaction.ID value. /// Throws exception when item is not valid, resolving customer external ID failed or if search index operation fails. /// </summary> /// <param name="t"></param> public void AddToIndex(Transaction t) { t.EnsureEntityValidForStorage(); Guid internalID; if (t.InternalRef.HasValue) { internalID = t.InternalRef.Value; } else { Customer c = new CustomerRepository().GetCustomerByExternalID(t.MvaNumber.Value, t.ExternalRef); if (c == null) { throw new Exception(string.Format("Failed to resolve customer external ID ({0}) to internal", t.ExternalRef)); } internalID = c.InternalID.Value; } var tableEnt = new TransactionTableEntity(t.ID.Value, t.Date.Value, internalID) { Amount = t.Amount, CustomerNumber = t.CustomerNumber, AccountID = t.AccountID, Description = t.Description, MvaNumber = t.MvaNumber, ProductID = t.ProductID }; AddToIndex(tableEnt); }
/// <summary> /// Inserts or updates (using merge operation) a batch of transaction table entities. /// Also generates IDs for items that do not have them and sets Date to DateTime.Now if it is null. /// </summary> /// <param name="batch">Batch of Transaction items to add/update</param> /// <exception cref="System.Exception">Thrown when any of the items is not valid or if adding to either table storage or search index failed.</exception> public void AddOrUpdateTransactionBatch(IEnumerable<Transaction> batch) { var tableEnts = new List<TransactionTableEntity>(); EnsureTransactionHasCustomerInternalID(batch.ToArray()); foreach (Transaction t in batch) { //also ensure that all entities are valid before any of them are committed to table storage or search index t.EnsureEntityValidForStorage(true); var ent = new TransactionTableEntity(t.ID.Value, t.Date.Value, t.InternalRef.Value) { MvaNumber = t.MvaNumber, Amount = t.Amount, Description = t.Description, CustomerNumber = t.CustomerNumber, AccountID = t.AccountID, ProductID = t.ProductID, NotInvoiceable = t.NotInvoiceable }; tableEnts.Add(ent); } //Need to group entities by partition key because table storage only allows batch operations in the scope of the same partition key var entsGroupedByPartition = tableEnts.GroupBy(t => t.PartitionKey); foreach (var entGroup in entsGroupedByPartition) { for (int i = 0; i < entGroup.Count(); i += 100) { var tableBatch = new TableBatchOperation(); foreach (var ent in entGroup.Skip(i).Take(100)) { tableBatch.Add(TableOperation.InsertOrMerge(ent)); } TransactionTable.ExecuteBatch(tableBatch); } } var dtReIndexReq = DateTime.UtcNow.Date.AddDays(-Constants.DaysToKeepTransactions); var entsToAddToIndex = tableEnts.Where(t => t.DateTime >= dtReIndexReq); var sRepo = new SearchRepository(); sRepo.AddToIndex(entsToAddToIndex.ToArray()); AddReIndexRequestIfNeeded(tableEnts.ToArray()); }
/// <summary> /// Inserts or updates (using merge operation) the transaction table entity. /// </summary> /// <param name="ent"></param> public void AddOrUpdateTransaction(TransactionTableEntity ent) { TableOperation op = TableOperation.InsertOrMerge(ent); var r = TransactionTable.Execute(op); //TODO: if productID was changed, a re-index request is not added for the previous productID value AddReIndexRequestIfNeeded(ent); }
/// <summary> /// Adds new transaction to table storage or updates an existing item. /// Throws exception when item is not valid, resolving customer external ID failed or if table storage operation fails. /// </summary> /// <param name="t">Transaction item to add/update</param> public void AddOrUpdateTransaction(Transaction t) { EnsureTransactionHasCustomerInternalID(t); t.EnsureEntityValidForStorage(); var ent = new TransactionTableEntity(t.ID.Value, t.Date.Value, t.InternalRef.Value) { MvaNumber = t.MvaNumber, Amount = t.Amount, Description = t.Description, CustomerNumber = t.CustomerNumber, AccountID = t.AccountID, ProductID = t.ProductID, NotInvoiceable = t.NotInvoiceable, ExternalRecordID = t.ExternalRecordID, }; AddOrUpdateTransaction(ent); }