Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat : Add DynamicsCrmDbContext #665

Merged
merged 6 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions Masa.Framework.sln
Original file line number Diff line number Diff line change
Expand Up @@ -699,14 +699,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.StackSdks.Isol
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.StackSdks.Isolation", "src\BuildingBlocks\StackSdks\Masa.BuildingBlocks.StackSdks.Isolation\Masa.BuildingBlocks.StackSdks.Isolation.csproj", "{4B175C6B-F5BE-4B65-BFCC-A949CA5BC6A3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.StackSdks.Tsc.OpenTelemetry", "src\Contrib\StackSdks\Masa.Contrib.StackSdks.Tsc.OpenTelemetry\Masa.Contrib.StackSdks.Tsc.OpenTelemetry.csproj", "{2B861EF5-124F-4D13-8291-F223B6588C35}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.StackSdks.Tsc.OpenTelemetry", "src\Contrib\StackSdks\Masa.Contrib.StackSdks.Tsc.OpenTelemetry\Masa.Contrib.StackSdks.Tsc.OpenTelemetry.csproj", "{2B861EF5-124F-4D13-8291-F223B6588C35}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Contrib.StackSdks.Tsc.OpenTelemetry.Tests", "src\Contrib\StackSdks\Tests\Masa.Contrib.StackSdks.Tsc.OpenTelemetry.Tests\Masa.Contrib.StackSdks.Tsc.OpenTelemetry.Tests.csproj", "{62D22ED4-76A6-41EE-9121-992608E3590D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.StackSdks.Tsc.OpenTelemetry.Tests", "src\Contrib\StackSdks\Tests\Masa.Contrib.StackSdks.Tsc.OpenTelemetry.Tests\Masa.Contrib.StackSdks.Tsc.OpenTelemetry.Tests.csproj", "{62D22ED4-76A6-41EE-9121-992608E3590D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tsc", "tsc", "{E4AD67C8-9255-4013-A3C4-962694399770}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tsc", "tsc", "{6042AE23-A07E-4F6F-B1C3-F17617AEB722}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DynamicsCRM", "DynamicsCRM", "{64B54122-44F1-4379-9422-953EF706A3A6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Utils.DynamicsCrm.Core", "src\Utils\DynamicsCrm\Masa.Utils.DynamicsCrm.Core\Masa.Utils.DynamicsCrm.Core.csproj", "{83310F46-E1C7-4438-B32A-9F6F7EA13FCF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.Utils.DynamicsCrm.EntityFrameworkCore", "src\Utils\DynamicsCrm\Masa.Utils.DynamicsCrm.EntityFrameworkCore\Masa.Utils.DynamicsCrm.EntityFrameworkCore.csproj", "{8A51A2A9-FBF4-40DC-AD89-AD3B9D3A50DC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -2547,6 +2553,22 @@ Global
{62D22ED4-76A6-41EE-9121-992608E3590D}.Release|Any CPU.Build.0 = Release|Any CPU
{62D22ED4-76A6-41EE-9121-992608E3590D}.Release|x64.ActiveCfg = Release|Any CPU
{62D22ED4-76A6-41EE-9121-992608E3590D}.Release|x64.Build.0 = Release|Any CPU
{83310F46-E1C7-4438-B32A-9F6F7EA13FCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{83310F46-E1C7-4438-B32A-9F6F7EA13FCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{83310F46-E1C7-4438-B32A-9F6F7EA13FCF}.Debug|x64.ActiveCfg = Debug|Any CPU
{83310F46-E1C7-4438-B32A-9F6F7EA13FCF}.Debug|x64.Build.0 = Debug|Any CPU
{83310F46-E1C7-4438-B32A-9F6F7EA13FCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{83310F46-E1C7-4438-B32A-9F6F7EA13FCF}.Release|Any CPU.Build.0 = Release|Any CPU
{83310F46-E1C7-4438-B32A-9F6F7EA13FCF}.Release|x64.ActiveCfg = Release|Any CPU
{83310F46-E1C7-4438-B32A-9F6F7EA13FCF}.Release|x64.Build.0 = Release|Any CPU
{8A51A2A9-FBF4-40DC-AD89-AD3B9D3A50DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A51A2A9-FBF4-40DC-AD89-AD3B9D3A50DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A51A2A9-FBF4-40DC-AD89-AD3B9D3A50DC}.Debug|x64.ActiveCfg = Debug|Any CPU
{8A51A2A9-FBF4-40DC-AD89-AD3B9D3A50DC}.Debug|x64.Build.0 = Debug|Any CPU
{8A51A2A9-FBF4-40DC-AD89-AD3B9D3A50DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A51A2A9-FBF4-40DC-AD89-AD3B9D3A50DC}.Release|Any CPU.Build.0 = Release|Any CPU
{8A51A2A9-FBF4-40DC-AD89-AD3B9D3A50DC}.Release|x64.ActiveCfg = Release|Any CPU
{8A51A2A9-FBF4-40DC-AD89-AD3B9D3A50DC}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -2896,6 +2918,9 @@ Global
{62D22ED4-76A6-41EE-9121-992608E3590D} = {E4AD67C8-9255-4013-A3C4-962694399770}
{E4AD67C8-9255-4013-A3C4-962694399770} = {EC7A08E9-3355-486B-BA30-41A1F8CAC5F5}
{6042AE23-A07E-4F6F-B1C3-F17617AEB722} = {383995FF-B661-4E15-A830-640FC5BA8A1F}
{64B54122-44F1-4379-9422-953EF706A3A6} = {5944A182-13B8-4DA6-AEE2-0A01E64A9648}
{83310F46-E1C7-4438-B32A-9F6F7EA13FCF} = {64B54122-44F1-4379-9422-953EF706A3A6}
{8A51A2A9-FBF4-40DC-AD89-AD3B9D3A50DC} = {64B54122-44F1-4379-9422-953EF706A3A6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Utils.DynamicsCrm.Core.Configurations;

public class CrmConfiguration : ICrmConfiguration
{
public Guid SystemUserId { get; set; }

public Guid BusinessUnitId { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Utils.DynamicsCrm.Core.Configurations;

public interface ICrmConfiguration
{
Guid SystemUserId { get; set; }

Guid BusinessUnitId { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Masa.Utils.DynamicsCrm.Core.Domain.Entities.Auditing;

public class CrmAuditEntity : CrmEntity, ICrmOwnerAudited
{
public virtual Guid OwnerId { set; get; }

public virtual int OwnerIdType { set; get; }

public virtual Guid? OwningBusinessUnit { set; get; }
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Masa.Utils.DynamicsCrm.Core.Domain.Entities.Auditing;

public class CrmEntity : Entity<Guid>, ICrmEntity
{
public virtual Guid? CreatedBy { set; get; }

public virtual DateTime? CreatedOn { set; get; }

public virtual Guid? ModifiedBy { set; get; }

public virtual DateTime? ModifiedOn { set; get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
namespace Masa.Utils.DynamicsCrm.Core.Domain.Entities.Auditing;

public static class CrmEntityAuditingHelper
{
public static void SetCreationAuditProperties(
object entityAsObj,
Guid systemUserId,
Guid ownerId,
Guid businessUnitId)
{
var entityWithCrmCreatedAudit = entityAsObj as ICrmCreationAudited;
if (entityWithCrmCreatedAudit == null)
{
return;
}

if (entityWithCrmCreatedAudit.CreatedOn == default(DateTime) || !entityWithCrmCreatedAudit.CreatedOn.HasValue)
{
entityWithCrmCreatedAudit.CreatedOn = DateTime.UtcNow;
}
entityWithCrmCreatedAudit.CreatedBy = systemUserId;
if (entityAsObj is ICrmOwnerAudited ownerAudited)
{
if (ownerAudited.OwnerId == Guid.Empty)
{
ownerAudited.OwnerId = ownerId;
}
ownerAudited.OwnerIdType = 8;
if (ownerAudited.OwningBusinessUnit == null)
{
ownerAudited.OwningBusinessUnit = businessUnitId;
}
}
if (entityAsObj is ICrmDeletionAudited deletionAudited)
{
deletionAudited.StateCode = 0;
deletionAudited.StatusCode = 1;
}

SetModificationAuditProperties(entityAsObj, systemUserId);
}

public static void SetModificationAuditProperties(
object entityAsObj,
Guid systemUserId)
{
var entityWithCrmModifiedAudit = entityAsObj as ICrmModificationAudited;
if (entityWithCrmModifiedAudit == null)
{
return;
}

entityWithCrmModifiedAudit.ModifiedOn = DateTime.UtcNow;
entityWithCrmModifiedAudit.ModifiedBy = systemUserId;
}

public static void SetDeletionAuditProperties(
object entityAsObj,
Guid systemUserId)
{
var entityWithCrmDeletionAudited = entityAsObj as ICrmDeletionAudited;
if (entityWithCrmDeletionAudited == null)
{
return;
}

entityWithCrmDeletionAudited.StateCode = 1;
entityWithCrmDeletionAudited.StatusCode = 2;
entityWithCrmDeletionAudited.ModifiedOn = DateTime.UtcNow;
entityWithCrmDeletionAudited.ModifiedBy = systemUserId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Masa.Utils.DynamicsCrm.Core.Domain.Entities.Auditing;

public class CrmFullAuditCustomEntity : CrmFullAuditEntity, ICrmCustomEntity
{
[Column("new_name")]
public virtual string? Name { set; get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Masa.Utils.DynamicsCrm.Core.Domain.Entities.Auditing;

public class CrmFullAuditEntity : CrmAuditEntity, ICrmDeletionAudited
{
public virtual int StateCode { set; get; }
public virtual int? StatusCode { set; get; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public virtual byte[]? VersionNumber { set; get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Masa.Utils.DynamicsCrm.Core.Domain.Entities.Auditing;

public interface ICrmCreationAudited : ICrmHasCreationTime
{
Guid? CreatedBy { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Masa.Utils.DynamicsCrm.Core.Domain.Entities.Auditing;

public interface ICrmCustomEntity
{
string? Name { set; get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Masa.Utils.DynamicsCrm.Core.Domain.Entities.Auditing;

public interface ICrmDeletionAudited : ICrmState, ICrmModificationAudited
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Masa.Utils.DynamicsCrm.Core.Domain.Entities.Auditing;

public interface ICrmEntity : ICrmCreationAudited, ICrmModificationAudited
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Masa.Utils.DynamicsCrm.Core.Domain.Entities.Auditing;

public interface ICrmHasCreationTime
{
DateTime? CreatedOn { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Masa.Utils.DynamicsCrm.Core.Domain.Entities.Auditing;

public interface ICrmHasModificationTime
{
DateTime? ModifiedOn { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Masa.Utils.DynamicsCrm.Core.Domain.Entities.Auditing;

public interface ICrmModificationAudited : ICrmHasModificationTime
{
Guid? ModifiedBy { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Masa.Utils.DynamicsCrm.Core.Domain.Entities.Auditing;

public interface ICrmOwnerAudited
{
Guid OwnerId { get; set; }
int OwnerIdType { get; set; }
Guid? OwningBusinessUnit { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Masa.Utils.DynamicsCrm.Core.Domain.Entities.Auditing;

public interface ICrmState
{
int StateCode { get; set; }
int? StatusCode { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Masa.Utils.DynamicsCrm.Core.Identity;

public class DynamicsCrmUser : IIdentityUser
{
public string Id { get; set; } = string.Empty;
public string? UserName { get; set; }
public string[] Roles { get; set; } = Array.Empty<string>();

public Guid BusinessUnitId { get; set; }

public string GetUserName()
{
return UserName ?? string.Empty;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\BuildingBlocks\Authentication\Masa.BuildingBlocks.Authentication.Identity\Masa.BuildingBlocks.Authentication.Identity.csproj" />
<ProjectReference Include="..\..\..\BuildingBlocks\Ddd\Domain\Masa.BuildingBlocks.Ddd.Domain\Masa.BuildingBlocks.Ddd.Domain.csproj" />
</ItemGroup>

</Project>
3 changes: 3 additions & 0 deletions src/Utils/DynamicsCrm/Masa.Utils.DynamicsCrm.Core/_Imports.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
global using System.ComponentModel.DataAnnotations.Schema;
global using Masa.BuildingBlocks.Ddd.Domain.Entities;
global using Masa.BuildingBlocks.Authentication.Identity;
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Utils.DynamicsCrm.EntityFrameworkCore.Filters;

public class DynamicsCrmSaveChangeFilter<TDbContext, TUserId> : ISaveChangesFilter<TDbContext>
where TDbContext : DbContext, IMasaDbContext
{
private readonly IUserContext? _userContext;
private readonly ICrmConfiguration? _crmConfiguration;

public DynamicsCrmSaveChangeFilter(
IUserContext? userContext = null,
ICrmConfiguration? crmConfiguration = null)
{
_userContext = userContext;
_crmConfiguration = crmConfiguration;
}

public void OnExecuting(ChangeTracker changeTracker)
{
changeTracker.DetectChanges();

var user = _userContext?.GetUser<DynamicsCrmUser>();
var userId = GetUserId();
var businessUnitId = user?.BusinessUnitId ?? _crmConfiguration?.BusinessUnitId ?? Guid.Empty;

foreach (var entity in changeTracker.Entries()
.Where(entry => entry.State == EntityState.Added || entry.State == EntityState.Modified))
{
AuditEntityHandler(entity, userId, businessUnitId);
}
}

private static void AuditEntityHandler(EntityEntry entity, Guid systemUserId, Guid businessUnitId)
{
if (entity.State == EntityState.Added)
{
CrmEntityAuditingHelper.SetCreationAuditProperties(entity.Entity, systemUserId, systemUserId, businessUnitId);
}
else
{
CrmEntityAuditingHelper.SetModificationAuditProperties(entity.Entity, systemUserId);
}
}

private Guid GetUserId()
{
if (_userContext == null)
return Guid.Empty;

var userId = _userContext.GetUserId<TUserId>();

if (!(userId is Guid))
return Guid.Empty;

return userId as Guid? ?? _crmConfiguration?.SystemUserId ?? Guid.Empty;
}
}
Loading
Loading