diff --git a/COA.EnterpriseServices.Creditors/CreditorController.cs b/COA.EnterpriseServices.Creditors/CreditorController.cs index 2e0bc56..91290c7 100644 --- a/COA.EnterpriseServices.Creditors/CreditorController.cs +++ b/COA.EnterpriseServices.Creditors/CreditorController.cs @@ -9,6 +9,11 @@ this.creditorLibrary = creditorLibrary; } + public Creditor GetCreditor(int creditorId) + { + return creditorLibrary.GetCreditor(creditorId); + } + public string GetCreditorStatus(int creditorId) { return creditorLibrary.GetCreditorStatus(creditorId); diff --git a/COA.EnterpriseServices.Creditors/CreditorLibrary.cs b/COA.EnterpriseServices.Creditors/CreditorLibrary.cs index 92bd03e..5f1768c 100644 --- a/COA.EnterpriseServices.Creditors/CreditorLibrary.cs +++ b/COA.EnterpriseServices.Creditors/CreditorLibrary.cs @@ -11,6 +11,11 @@ namespace COA.EnterpriseServices.Creditors this.creditorHelper = creditorHelper; } + public Creditor GetCreditor(int creditorId) + { + return creditorHelper.GetCreditor(creditorId); + } + public string GetCreditorStatus(int creditorId) { var creditor = creditorHelper.GetCreditor(creditorId); diff --git a/COA.EnterpriseServices.DataAccess.EntityFramework/Migrations/20201016134528_add-creditor-ref.Designer.cs b/COA.EnterpriseServices.DataAccess.EntityFramework/Migrations/20201016134528_add-creditor-ref.Designer.cs new file mode 100644 index 0000000..554d0b8 --- /dev/null +++ b/COA.EnterpriseServices.DataAccess.EntityFramework/Migrations/20201016134528_add-creditor-ref.Designer.cs @@ -0,0 +1,125 @@ +// +using System; +using COA.EnterpriseServices.DataAccess.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace COA.EnterpriseServices.DataAccess.EntityFramework.Migrations +{ + [DbContext(typeof(QuickBaseContext))] + [Migration("20201016134528_add-creditor-ref")] + partial class addcreditorref + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.9") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("COA.EnterpriseServices.DataAccess.Entities.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Address") + .HasColumnType("nvarchar(max)"); + + b.Property("City") + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasColumnType("nvarchar(max)"); + + b.Property("FirstName") + .HasColumnType("nvarchar(max)"); + + b.Property("LastName") + .HasColumnType("nvarchar(max)"); + + b.Property("Modified") + .HasColumnType("datetime2"); + + b.Property("Phone") + .HasColumnType("bigint"); + + b.Property("State") + .HasColumnType("nvarchar(max)"); + + b.Property("Zip") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("COA.EnterpriseServices.DataAccess.Entities.Creditor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("AccountNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("ClientFirstName") + .HasColumnType("nvarchar(max)"); + + b.Property("ClientLastName") + .HasColumnType("nvarchar(max)"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CurrentCreditorProfileId") + .HasColumnType("int"); + + b.Property("Modified") + .HasColumnType("datetime2"); + + b.Property("OriginalCreditorProfileId") + .HasColumnType("int"); + + b.Property("ReferenceNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("Status") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Creditors"); + }); + + modelBuilder.Entity("COA.EnterpriseServices.DataAccess.Entities.SettlementAttempt", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Modified") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("SettlementAttempts"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/COA.EnterpriseServices.DataAccess.EntityFramework/Migrations/20201016134528_add-creditor-ref.cs b/COA.EnterpriseServices.DataAccess.EntityFramework/Migrations/20201016134528_add-creditor-ref.cs new file mode 100644 index 0000000..3016984 --- /dev/null +++ b/COA.EnterpriseServices.DataAccess.EntityFramework/Migrations/20201016134528_add-creditor-ref.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace COA.EnterpriseServices.DataAccess.EntityFramework.Migrations +{ + public partial class addcreditorref : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ReferenceNumber", + table: "Creditors", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ReferenceNumber", + table: "Creditors"); + } + } +} diff --git a/COA.EnterpriseServices.DataAccess.EntityFramework/Migrations/QuickBaseContextModelSnapshot.cs b/COA.EnterpriseServices.DataAccess.EntityFramework/Migrations/QuickBaseContextModelSnapshot.cs index 9c0bc54..1257263 100644 --- a/COA.EnterpriseServices.DataAccess.EntityFramework/Migrations/QuickBaseContextModelSnapshot.cs +++ b/COA.EnterpriseServices.DataAccess.EntityFramework/Migrations/QuickBaseContextModelSnapshot.cs @@ -89,6 +89,9 @@ namespace COA.EnterpriseServices.DataAccess.EntityFramework.Migrations b.Property("OriginalCreditorProfileId") .HasColumnType("int"); + b.Property("ReferenceNumber") + .HasColumnType("nvarchar(max)"); + b.Property("Status") .HasColumnType("nvarchar(max)"); diff --git a/COA.EnterpriseServices.DataAccess/DataAccessManager.cs b/COA.EnterpriseServices.DataAccess/DataAccessManager.cs index e92261d..c651f61 100644 --- a/COA.EnterpriseServices.DataAccess/DataAccessManager.cs +++ b/COA.EnterpriseServices.DataAccess/DataAccessManager.cs @@ -5,7 +5,10 @@ using System.Linq.Expressions; namespace COA.EnterpriseServices.DataAccess { - public class DataAccessManager2 + /// + /// Provides a wrapper around as well as additional convenience CRUD methods + /// + public class DataAccessManager { private static readonly IDictionary enabledDataAccess = new Dictionary { @@ -105,108 +108,4 @@ namespace COA.EnterpriseServices.DataAccess .ToList(); } } - - /// - /// Provides a wrapper around as well as additional convenience CRUD methods - /// - /// - public class DataAccessManager where T : class, IRecord - { - private static readonly IDictionary enabledDataAccess = new Dictionary - { - #region Creditor - - ["COA.EnterpriseServices.DataAccess.Entities.Creditor"] = new[] - { - "COA.EnterpriseServices.DataAccess.QuickBase.QuickBaseDataAccess", - "COA.EnterpriseServices.DataAccess.EntityFramework.EntityDataAccess" - }, - - #endregion - - #region Client - - ["COA.EnterpriseServices.DataAccess.Entities.Client"] = new[] - { - "COA.EnterpriseServices.DataAccess.QuickBase.QuickBaseDataAccess", - "COA.EnterpriseServices.DataAccess.EntityFramework.EntityDataAccess" - } - - #endregion - }; - - public bool Add(T item) - { - return Invoke(d => d.Add(item)); - } - - public bool Update(T item) - { - item.Modified = DateTime.Now; - - return Invoke(d => d.Update(item)); - } - - public bool Update(int id, Action update) - { - var item = Get(id); - - update(item); - - return Update(item); - } - - public T Get(int id) - { - var item = Invoke(d => d.Get(i => i.Id == id)); - - if (item != null && item.Any()) - { - return item.FirstOrDefault(); - } - - return default; - } - - public ICollection Get(Expression> query) - { - return Invoke(d => d.Get(query)); - } - - #region Private Methods - - private TResult Invoke(Func, TResult> func) - { - var results = new List(); - var dataAccessInstances = GetEnabledDataAccess(); - - foreach (var dataAccessInstance in dataAccessInstances) - { - results.Add(func(dataAccessInstance)); - } - - // if the "EF" version invokes first, return that value - return results.FirstOrDefault(r => r != null && !r.Equals(default(TResult))); - } - - private ICollection> GetEnabledDataAccess() - { - var type = typeof(T); - - // load data access based on active configuration - return Dependencies.Container - .GetAllInstances>() - .Select(i => new - { - Instance = i, - Type = i.GetType() - }) - .Where(i => enabledDataAccess.ContainsKey(type.FullName) && enabledDataAccess[type.FullName].Any(a => i.Type.FullName.StartsWith(a))) - .OrderBy(i => i.Type.Name.StartsWith("QuickBase", StringComparison.OrdinalIgnoreCase)) - .Select(i => i.Instance) - .ToList(); - } - - #endregion - } } diff --git a/COA.EnterpriseServices.DataAccess/Dependencies.cs b/COA.EnterpriseServices.DataAccess/Dependencies.cs index cf61d3f..bef9ec7 100644 --- a/COA.EnterpriseServices.DataAccess/Dependencies.cs +++ b/COA.EnterpriseServices.DataAccess/Dependencies.cs @@ -15,17 +15,15 @@ namespace COA.EnterpriseServices.DataAccess c.Scan(s => { s.AddAllTypesOf(typeof(IDataAccess<>)); - s.AddAllTypesOf(typeof(DataAccessManager<>)); s.WithDefaultConventions(); s.AssembliesFromApplicationBaseDirectory(); }); c.For(typeof(IDataAccess<>)).Singleton(); - c.For(typeof(DataAccessManager<>)).Singleton(); + c.For().Singleton(); c.For().Singleton().Use(() => Mapping.GetMapper()); - c.For().Singleton(); c.For().Singleton(); }); diff --git a/COA.EnterpriseServices.DataAccess/Extensions/AutoMapperExtensions.cs b/COA.EnterpriseServices.DataAccess/Extensions/AutoMapperExtensions.cs new file mode 100644 index 0000000..5272fc7 --- /dev/null +++ b/COA.EnterpriseServices.DataAccess/Extensions/AutoMapperExtensions.cs @@ -0,0 +1,25 @@ +using AutoMapper; +using System.Collections.Generic; + +namespace COA.EnterpriseServices.DataAccess +{ + public static class AutoMapperExtensions + { + private static readonly IMapper mapper; + + static AutoMapperExtensions() + { + mapper = Dependencies.Container.GetInstance(); + } + + public static T MapTo(this object item) + { + return mapper.Map(item); + } + + public static IEnumerable MapTo(this IEnumerable item) + { + return mapper.Map>(item); + } + } +} diff --git a/COA.EnterpriseServices.DataAccess/Helpers/BaseHelper.cs b/COA.EnterpriseServices.DataAccess/Helpers/BaseHelper.cs new file mode 100644 index 0000000..78fb277 --- /dev/null +++ b/COA.EnterpriseServices.DataAccess/Helpers/BaseHelper.cs @@ -0,0 +1,16 @@ +using AutoMapper; + +namespace COA.EnterpriseServices.DataAccess.Helpers +{ + public class BaseHelper + { + protected DataAccessManager DataAccess { get; } + protected IMapper Mapper { get; } + + public BaseHelper(DataAccessManager dataAccess, IMapper mapper) + { + DataAccess = dataAccess; + Mapper = mapper; + } + } +} diff --git a/COA.EnterpriseServices.DataAccess/Helpers/ClientHelper.cs b/COA.EnterpriseServices.DataAccess/Helpers/ClientHelper.cs index 9050ca2..08e467d 100644 --- a/COA.EnterpriseServices.DataAccess/Helpers/ClientHelper.cs +++ b/COA.EnterpriseServices.DataAccess/Helpers/ClientHelper.cs @@ -3,18 +3,13 @@ using System.Collections.Generic; namespace COA.EnterpriseServices.DataAccess.Helpers { - public class ClientHelper + public class ClientHelper : BaseHelper { - private readonly DataAccessManager clientDataAccess; - - public ClientHelper(DataAccessManager clientDataAccess, IMapper mapper) - { - this.clientDataAccess = clientDataAccess; - } + public ClientHelper(DataAccessManager dataAccess, IMapper mapper) : base(dataAccess, mapper) { } public ICollection FindByEmail(string email) { - var client = clientDataAccess.Get(c => c.Email.Equals(email)); + var client = DataAccess.Get(c => c.Email.Equals(email)); return client; } diff --git a/COA.EnterpriseServices.DataAccess/Helpers/CreditorHelper.cs b/COA.EnterpriseServices.DataAccess/Helpers/CreditorHelper.cs index 54cbbae..4b4babe 100644 --- a/COA.EnterpriseServices.DataAccess/Helpers/CreditorHelper.cs +++ b/COA.EnterpriseServices.DataAccess/Helpers/CreditorHelper.cs @@ -1,50 +1,36 @@ using AutoMapper; using COA.EnterpriseServices.Creditors; -using COA.EnterpriseServices.DataAccess.Entities; using System.Collections.Generic; using System.Linq; namespace COA.EnterpriseServices.DataAccess.Helpers { - public class CreditorHelper + public class CreditorHelper : BaseHelper { - private readonly DataAccessManager creditorDataAccess; - private readonly DataAccessManager settlementAttemptDataAccess; private readonly IMapper mapper; - public CreditorHelper(DataAccessManager creditorDataAccess, DataAccessManager settlementAttemptDataAccess, IMapper mapper) + public CreditorHelper(DataAccessManager dataAccess, IMapper mapper) : base(dataAccess, mapper) { } + + public Creditor GetCreditor(int id) { - this.creditorDataAccess = creditorDataAccess; - this.settlementAttemptDataAccess = settlementAttemptDataAccess; - this.mapper = mapper; + return DataAccess + .Get(id) + .MapTo(); } - public Creditors.Creditor GetCreditor(int id) + public SettlementAttempt GetSettlementAttempt(int id) { - var creditor = creditorDataAccess.Get(id); - - // map EF => domain type - return mapper.Map(creditor); + return DataAccess + .Get(id) + .MapTo(); } - public Creditors.SettlementAttempt GetSettlementAttempt(int id) + public ICollection GetSettlements(SettlementAttemptFilter filter) { - var attempt = settlementAttemptDataAccess.Get(id); - - return mapper.Map(attempt); - } - - public ICollection GetSettlements(SettlementAttemptFilter filter) - { - // we may use this non-generic throughout instead - var dataAccess = new DataAccessManager2(); - // More info on "FromSqlRaw" => https://docs.microsoft.com/en-us/ef/core/querying/raw-sql - var attempts = dataAccess.Raw("uspCreditorPortal_SettlementAttemptGet @SettlementAttemptID = {0}, @CreditorProfileID = {1}", filter.SettlementAttemptId, filter.CreditorProfileId); - - // TODO: write extension to map list of T to destination type - return attempts - .Select(a => mapper.Map(a)) + return DataAccess + .Raw("uspCreditorPortal_SettlementAttemptGet @SettlementAttemptID = {0}, @CreditorProfileID = {1}", filter.SettlementAttemptId, filter.CreditorProfileId) + .MapTo() .ToList(); //return DBWrapper.ExecuteProcedure(QuickbaseConnectionString, "uspCreditorPortal_SettlementAttemptGet", cmd => @@ -78,41 +64,41 @@ namespace COA.EnterpriseServices.DataAccess.Helpers //}); } - public bool AddCreditor(Creditors.Creditor creditor) + public bool AddCreditor(Creditor creditor) { var creditorEntity = mapper.Map(creditor); - return creditorDataAccess.Add(creditorEntity); + return DataAccess.Add(creditorEntity); } - public bool UpdateCreditor(Creditors.Creditor creditor) + public bool UpdateCreditor(Creditor creditor) { var creditorEntity = mapper.Map(creditor); - return creditorDataAccess.Update(creditorEntity); + return DataAccess.Update(creditorEntity); } public bool SetCreditorStatus(int creditorId, string status) { - return creditorDataAccess.Update(creditorId, c => c.Status = status); + return DataAccess.Update(creditorId, c => c.Status = status); } public void SetOriginalCreditorAsPrimary(int creditorId) { - var creditor = creditorDataAccess.Get(creditorId); + var creditor = DataAccess.Get(creditorId); creditor.ReferenceNumber = string.Empty; - creditorDataAccess.Update(creditor); + DataAccess.Update(creditor); } public void ClearCreditorReferenceNumber(int creditorId) { - var creditor = creditorDataAccess.Get(creditorId); + var creditor = DataAccess.Get(creditorId); creditor.CurrentCreditorProfileId = creditor.OriginalCreditorProfileId; - creditorDataAccess.Update(creditor); + DataAccess.Update(creditor); } } } diff --git a/COA.EnterpriseServices.DataAccess/MappingProfile.cs b/COA.EnterpriseServices.DataAccess/MappingProfile.cs index da12d9d..fdd58e4 100644 --- a/COA.EnterpriseServices.DataAccess/MappingProfile.cs +++ b/COA.EnterpriseServices.DataAccess/MappingProfile.cs @@ -10,6 +10,7 @@ namespace COA.EnterpriseServices.DataAccess #region EF => Domain CreateMap() + .ForMember(d => d.creditorId, o => o.MapFrom(s => s.Id)) .ForMember(d => d.creditorStatus, o => o.MapFrom(s => s.Status)); CreateMap(); @@ -21,6 +22,7 @@ namespace COA.EnterpriseServices.DataAccess #region Domain => EF CreateMap() + .ForMember(d => d.Id, o => o.MapFrom(s => s.creditorId)) .ForMember(d => d.Status, o => o.MapFrom(s => s.creditorStatus)); CreateMap(); diff --git a/COA.EnterpriseServices.Sandbox/Program.cs b/COA.EnterpriseServices.Sandbox/Program.cs index 6ecf421..f4aeb25 100644 --- a/COA.EnterpriseServices.Sandbox/Program.cs +++ b/COA.EnterpriseServices.Sandbox/Program.cs @@ -13,6 +13,8 @@ namespace COA.EnterpriseServices.Sandbox //Console.WriteLine(creditorController.GetCreditorStatus(1)); Console.WriteLine(creditorController.SetCreditorStatus(1, "Active")); + var creditor = creditorController.GetCreditor(1); + //creditorController.AddOfferResponse(new OfferResponse //{ // CreditorId = 1