diff --git a/COA.EnterpriseServices.DataAccess.QuickBase/FieldMap.cs b/COA.EnterpriseServices.DataAccess.QuickBase/FieldMap.cs index 4e4fd70..c9e25c6 100644 --- a/COA.EnterpriseServices.DataAccess.QuickBase/FieldMap.cs +++ b/COA.EnterpriseServices.DataAccess.QuickBase/FieldMap.cs @@ -1,16 +1,8 @@ -using System; - -namespace COA.EnterpriseServices.DataAccess.QuickBase +namespace COA.EnterpriseServices.DataAccess.QuickBase { internal class FieldMap { - internal Type ItemType { get; set; } internal string PropertyName { get; set; } internal int FieldId { get; set; } } - - internal class TableMap - { - - } } diff --git a/COA.EnterpriseServices.DataAccess.QuickBase/FieldMapRegistry.cs b/COA.EnterpriseServices.DataAccess.QuickBase/FieldMapRegistry.cs deleted file mode 100644 index b34e897..0000000 --- a/COA.EnterpriseServices.DataAccess.QuickBase/FieldMapRegistry.cs +++ /dev/null @@ -1,149 +0,0 @@ -using COA.Common; -using COA.EnterpriseServices.DataAccess.Entities; -using COA.PartnerApis.QuickBase; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; - -namespace COA.EnterpriseServices.DataAccess.QuickBase -{ - internal static class FieldMapRegistry - { - private static readonly ICollection fieldRegistry = new List(); - private static readonly IDictionary tableRegistry = new Dictionary(); - - static FieldMapRegistry() - { - AddTable() - .WithDefaults() - .WithProperty(c => c.Status, CreditorsFieldMap.CreditorStatus) - .WithProperty(c => c.ClientFirstName, CreditorsFieldMap.ClientFirstName) - .WithProperty(c => c.ClientLastName, CreditorsFieldMap.ClientLastName) - .WithProperty(c => c.CurrentCreditorProfileId, CreditorsFieldMap.RelatedCurrentCreditorPrimary) - .WithProperty(c => c.OriginalCreditorProfileId, CreditorsFieldMap.RelatedOriginalCreditor) - .WithProperty(c => c.AccountNumber, CreditorsFieldMap.AccountNum); - - AddTable() - .WithDefaults() - .WithProperty(c => c.FirstName, ClientFieldMap.FirstName) - .WithProperty(c => c.LastName, ClientFieldMap.LastName) - .WithProperty(c => c.Email, ClientFieldMap.ClientPrimaryEmail) - .WithProperty(c => c.Phone, ClientFieldMap.ClientPrimaryPhone); - } - - /// - /// Adds a table mapping for a QuickBase field map - /// - /// - /// - /// - private static TableMap AddTable() where TEntity : IRecord - { - var tableNameAttribute = typeof(TEnumFieldMap).GetCustomAttribute(); - - if (tableNameAttribute != null) - { - tableRegistry.Add(typeof(TEntity), tableNameAttribute.Name); - } - - return default; - } - - /// - /// Adds default property mappings for common fields - /// - /// - /// - /// - /// - internal static TableMap WithDefaults(this TableMap table) where TEntity : IRecord where TEnumFieldMap : Enum - { - fieldRegistry.Add(new FieldMap - { - ItemType = typeof(TEntity), - PropertyName = nameof(IRecord.Id), - FieldId = PartnerApis.QuickBase.Constants.RecordIdFieldId - }); - - fieldRegistry.Add(new FieldMap - { - ItemType = typeof(TEntity), - PropertyName = nameof(IRecord.Created), - FieldId = PartnerApis.QuickBase.Constants.DateCreatedFieldId - }); - - fieldRegistry.Add(new FieldMap - { - ItemType = typeof(TEntity), - PropertyName = nameof(IRecord.Modified), - FieldId = PartnerApis.QuickBase.Constants.DateModifiedFieldId - }); - - return default; - } - - /// - /// Adds a propert mapping for an entity property - /// - /// - /// - /// - /// - /// - /// - internal static TableMap WithProperty(this TableMap table, Expression> property, TEnumFieldMap field) - { - if (property.Body is MemberExpression memberExpression) - { - fieldRegistry.Add(new FieldMap - { - ItemType = memberExpression.Member.DeclaringType, - PropertyName = memberExpression.Member.Name, - FieldId = field.To() - }); - } - else if (property.Body is UnaryExpression unaryExpression && unaryExpression.Operand is MemberExpression unaryMemberExpression) - { - fieldRegistry.Add(new FieldMap - { - ItemType = unaryMemberExpression.Member.DeclaringType, - PropertyName = unaryMemberExpression.Member.Name, - FieldId = field.To() - }); - } - - return default; - } - - internal static int? GetFieldId(PropertyInfo info) - { - var map = fieldRegistry.FirstOrDefault(m => m.ItemType == info.DeclaringType && m.PropertyName == info.Name); - - return map != null ? map.FieldId : default; - } - - internal static QuickBaseRecordContext GetTableContext(object item) - { - var context = new QuickBaseRecordContext(); - var itemType = item.GetType(); - var properties = itemType.GetProperties(); - - context.Table = tableRegistry.FirstOrDefault(r => r.Key == itemType).Value; - - foreach (var property in properties) - { - var fieldId = GetFieldId(property); - var value = property.GetValue(item); - - if (fieldId != null) - { - context.FieldIds.Add(new KeyValuePair(fieldId.Value, value)); - } - } - - return context; - } - } -} diff --git a/COA.EnterpriseServices.DataAccess.QuickBase/QuickBaseDataAccess.cs b/COA.EnterpriseServices.DataAccess.QuickBase/QuickBaseDataAccess.cs index 31c004f..9ac78f7 100644 --- a/COA.EnterpriseServices.DataAccess.QuickBase/QuickBaseDataAccess.cs +++ b/COA.EnterpriseServices.DataAccess.QuickBase/QuickBaseDataAccess.cs @@ -16,18 +16,18 @@ namespace COA.EnterpriseServices.DataAccess.QuickBase public bool Add(T item) { - var fieldData = FieldMapRegistry.GetTableContext(item); + var record = RecordMapRegistry.GetRecord(item); - var result = client.AddRecord(fieldData.Table, fieldData.FieldIds); + var result = client.AddRecord(record.Table, record.FieldIds); return result.Success; } public bool Update(T item) { - var fieldData = FieldMapRegistry.GetTableContext(item); + var record = RecordMapRegistry.GetRecord(item); - var result = client.EditRecord(item.Id, fieldData.Table, fieldData.FieldIds); + var result = client.EditRecord(item.Id, record.Table, record.FieldIds); return result.Success; } diff --git a/COA.EnterpriseServices.DataAccess.QuickBase/QuickBaseRecordContext.cs b/COA.EnterpriseServices.DataAccess.QuickBase/Record.cs similarity index 66% rename from COA.EnterpriseServices.DataAccess.QuickBase/QuickBaseRecordContext.cs rename to COA.EnterpriseServices.DataAccess.QuickBase/Record.cs index a124e8c..fc919e6 100644 --- a/COA.EnterpriseServices.DataAccess.QuickBase/QuickBaseRecordContext.cs +++ b/COA.EnterpriseServices.DataAccess.QuickBase/Record.cs @@ -2,7 +2,10 @@ namespace COA.EnterpriseServices.DataAccess.QuickBase { - internal class QuickBaseRecordContext + /// + /// Represents record data to be used in the QuickBase API + /// + internal class Record { internal string Table { get; set; } internal IDictionary FieldIds { get; set; } = new Dictionary(); diff --git a/COA.EnterpriseServices.DataAccess.QuickBase/RecordMap.cs b/COA.EnterpriseServices.DataAccess.QuickBase/RecordMap.cs new file mode 100644 index 0000000..61348f4 --- /dev/null +++ b/COA.EnterpriseServices.DataAccess.QuickBase/RecordMap.cs @@ -0,0 +1,92 @@ +using COA.Common; +using COA.PartnerApis.QuickBase; +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Reflection; + +namespace COA.EnterpriseServices.DataAccess.QuickBase +{ + /// + /// Represents a map between a CLR type, its QuickBase table, and fields + /// + internal abstract class RecordMap + { + internal Type ItemType { get; set; } + internal string Table { get; set; } + internal ICollection FieldMaps { get; } = new List(); + } + + internal class RecordMap : RecordMap where TEntity : IRecord where TEnumFieldMap : Enum + { + internal RecordMap() + { + ItemType = typeof(TEntity); + + var tableNameAttribute = typeof(TEnumFieldMap).GetCustomAttribute(); + + if (tableNameAttribute != null) + { + Table = tableNameAttribute.Name; + } + } + + /// + /// Adds a propery mapping for an entity property + /// + /// + /// + /// + internal RecordMap WithProperty(Expression> property, TEnumFieldMap field) + { + if (property.Body is MemberExpression memberExpression) + { + FieldMaps.Add(new FieldMap + { + PropertyName = memberExpression.Member.Name, + FieldId = field.To() + }); + } + else if (property.Body is UnaryExpression unaryExpression && unaryExpression.Operand is MemberExpression unaryMemberExpression) + { + FieldMaps.Add(new FieldMap + { + PropertyName = unaryMemberExpression.Member.Name, + FieldId = field.To() + }); + } + + return this; + } + + /// + /// Adds default property mappings for common entity fields + /// + /// + /// + /// + /// + internal RecordMap WithDefaults() + { + FieldMaps.Add(new FieldMap + { + PropertyName = nameof(IRecord.Id), + FieldId = PartnerApis.QuickBase.Constants.RecordIdFieldId + }); + + FieldMaps.Add(new FieldMap + { + PropertyName = nameof(IRecord.Created), + FieldId = PartnerApis.QuickBase.Constants.DateCreatedFieldId + }); + + FieldMaps.Add(new FieldMap + { + PropertyName = nameof(IRecord.Modified), + FieldId = PartnerApis.QuickBase.Constants.DateModifiedFieldId + }); + + return this; + } + } +} diff --git a/COA.EnterpriseServices.DataAccess.QuickBase/RecordMapRegistry.cs b/COA.EnterpriseServices.DataAccess.QuickBase/RecordMapRegistry.cs new file mode 100644 index 0000000..ecd9946 --- /dev/null +++ b/COA.EnterpriseServices.DataAccess.QuickBase/RecordMapRegistry.cs @@ -0,0 +1,68 @@ +using COA.EnterpriseServices.DataAccess.Entities; +using COA.PartnerApis.QuickBase; +using System.Collections.Generic; +using System.Linq; + +namespace COA.EnterpriseServices.DataAccess.QuickBase +{ + /// + /// Maintains a list of entity types and property mappings to QuickBase fields + /// + internal static class RecordMapRegistry + { + private static readonly ICollection recordMaps = new List(); + + static RecordMapRegistry() + { + #region Creditor + + recordMaps.Add(new RecordMap() + .WithDefaults() + .WithProperty(c => c.ClientFirstName, CreditorsFieldMap.ClientFirstName) + .WithProperty(c => c.ClientFirstName, CreditorsFieldMap.ClientFirstName) + .WithProperty(c => c.ClientLastName, CreditorsFieldMap.ClientLastName) + .WithProperty(c => c.CurrentCreditorProfileId, CreditorsFieldMap.RelatedCurrentCreditorPrimary) + .WithProperty(c => c.OriginalCreditorProfileId, CreditorsFieldMap.RelatedOriginalCreditor) + .WithProperty(c => c.Status, CreditorsFieldMap.CreditorStatus) + .WithProperty(c => c.AccountNumber, CreditorsFieldMap.AccountNum)); + + #endregion + + #region Client + + recordMaps.Add(new RecordMap() + .WithDefaults() + .WithProperty(c => c.FirstName, ClientFieldMap.FirstName) + .WithProperty(c => c.LastName, ClientFieldMap.LastName) + .WithProperty(c => c.Email, ClientFieldMap.ClientPrimaryEmail) + .WithProperty(c => c.Phone, ClientFieldMap.ClientPrimaryPhone) + .WithProperty(c => c.Address, ClientFieldMap.Address1)); + + #endregion + } + + internal static Record GetRecord(object item) + { + var data = new Record(); + var itemType = item.GetType(); + var properties = itemType.GetProperties(); + var map = recordMaps.FirstOrDefault(r => r.ItemType == itemType); + + data.Table = map.Table; + + foreach (var property in properties) + { + var fieldMap = map.FieldMaps.FirstOrDefault(f => f.PropertyName == property.Name); + + if (fieldMap != null) + { + var value = property.GetValue(item); + + data.FieldIds.Add(new KeyValuePair(fieldMap.FieldId, value)); + } + } + + return data; + } + } +}