Skip to content

Commit

Permalink
Merge pull request #456 from Strongminds/release/10.0.0
Browse files Browse the repository at this point in the history
Release/10.0.0
  • Loading branch information
mrjsawdk authored Sep 6, 2022
2 parents ac1d48e + 8255a6d commit 0e3e978
Show file tree
Hide file tree
Showing 667 changed files with 30,446 additions and 15,266 deletions.
1 change: 1 addition & 0 deletions Core.Abstractions/Core.Abstractions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
<Compile Include="Extensions\ObjectExtensions.cs" />
<Compile Include="Extensions\ResultExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Types\DetailedOperationError.cs" />
<Compile Include="Types\Factory.cs" />
<Compile Include="Types\Maybe.cs" />
<Compile Include="Types\OperationError.cs" />
Expand Down
5 changes: 5 additions & 0 deletions Core.Abstractions/Extensions/ObjectExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ public static Maybe<T> FromNullable<T>(this T src)
return src == null ? Maybe<T>.None : Maybe<T>.Some(src);
}

public static Maybe<T> FromNullableValueType<T>(this T? src) where T:struct
{
return src == null ? Maybe<T>.None : Maybe<T>.Some(src.Value);
}

public static Maybe<string> FromString(this string src)
{
return string.IsNullOrEmpty(src) ? Maybe<string>.None : src;
Expand Down
13 changes: 13 additions & 0 deletions Core.Abstractions/Types/DetailedOperationError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Core.Abstractions.Types
{
public class DetailedOperationError<TDetail> : OperationError
{
public DetailedOperationError(OperationFailure failureType, TDetail detail, string message = null)
: base(message, failureType)
{
Detail = detail;
}

public TDetail Detail { get; }
}
}
27 changes: 15 additions & 12 deletions Core.ApplicationServices/AdviceService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,21 +170,21 @@ private bool DispatchEmails(Advice advice)
case RecieverType.RECIEVER:
switch (r.RecpientType)
{
case RecieverType.USER:
case RecipientType.USER:
AddRecipientByName(r, message.To);
break;
case RecieverType.ROLE:
case RecipientType.ROLE:
AddRecipientByRole(advice, r, message.To);
break;
}
break;
case RecieverType.CC:
switch (r.RecpientType)
{
case RecieverType.USER:
case RecipientType.USER:
AddRecipientByName(r, message.CC);
break;
case RecieverType.ROLE:
case RecipientType.ROLE:
AddRecipientByRole(advice, r, message.CC);
break;
}
Expand Down Expand Up @@ -223,9 +223,9 @@ private bool DispatchEmails(Advice advice)

private static void AddRecipientByName(AdviceUserRelation r, MailAddressCollection mailAddressCollection)
{
if (!string.IsNullOrEmpty(r.Name))
if (!string.IsNullOrEmpty(r.Email))
{
mailAddressCollection.Add(r.Name);
mailAddressCollection.Add(r.Email);
}
}

Expand All @@ -234,30 +234,32 @@ private void AddRecipientByRole(Advice advice, AdviceUserRelation r, MailAddress
switch (advice.Type)
{
case RelatedEntityType.itContract:

var itContractRoles = _itContractRights.AsQueryable().Where(I => I.ObjectId == advice.RelationId
&& I.Role.Name == r.Name);
&& I.RoleId == r.ItContractRoleId);
foreach (var t in itContractRoles)
{
if(t.User.Deleted) continue;
mailAddressCollection.Add(t.User.Email);
}

break;
case RelatedEntityType.itProject:
var projectRoles = _itProjectRights.AsQueryable().Where(I => I.ObjectId == advice.RelationId
&& I.Role.Name == r.Name);
&& I.RoleId == r.ItProjectRoleId);
foreach (var t in projectRoles)
{
if(t.User.Deleted) continue;
mailAddressCollection.Add(t.User.Email);
}

break;
case RelatedEntityType.itSystemUsage:

var systemRoles = _itSystemRights.AsQueryable().Where(I => I.ObjectId == advice.RelationId
&& I.Role.Name == r.Name);
&& I.RoleId == r.ItSystemRoleId);
foreach (var t in systemRoles)
{
if(t.User.Deleted) continue;
mailAddressCollection.Add(t.User.Email);
}

Expand All @@ -266,9 +268,10 @@ private void AddRecipientByRole(Advice advice, AdviceUserRelation r, MailAddress

var dpaRoles = _dataProcessingRegistrationRights.AsQueryable().Where(I =>
I.ObjectId == advice.RelationId
&& I.Role.Name == r.Name);
&& I.RoleId == r.DataProcessingRegistrationRoleId);
foreach (var t in dpaRoles)
{
if(t.User.Deleted) continue;
mailAddressCollection.Add(t.User.Email);
}

Expand Down Expand Up @@ -403,7 +406,7 @@ public void UpdateSchedule(Advice advice)
public void CreateOrUpdateJob(int adviceId)
{
var advice = _adviceRepository.GetByKey(adviceId);
if (advice == null || advice.Scheduling == null || advice.AlarmDate == null)
if (advice?.Scheduling == null || advice.AlarmDate == null)
{
throw new ArgumentException(nameof(adviceId) + " does not point to a valid id or points to an advice without alarm date or scheduling");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ public interface IPermissionVisitor
bool Visit(ViewBrokenExternalReferencesReportPermission permission);
bool Visit(TriggerBrokenReferencesReportPermission permission);
bool Visit(AdministerGlobalPermission permission);
bool Visit(ImportHierarchyFromStsOrganizationPermission permission);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ public bool AllowDelete(IEntity entity)
{
result = entity switch
{
Organization _ => IsGlobalAdmin(),
User user => IsGlobalAdmin() && EntityEqualsActiveUser(user) == false,
ItInterface itInterface =>
//Even rightsholders are not allowed to delete interfaces
IsGlobalAdmin() || IsLocalAdmin(itInterface.OrganizationId),
Expand Down Expand Up @@ -369,10 +369,10 @@ bool IPermissionVisitor.Visit(VisibilityControlPermission permission)

return target switch
{
IContractModule _ => IsGlobalAdmin() ||
IContractModule _ => IsGlobalAdmin() ||
IsLocalAdmin(ownedByOrganization.OrganizationId) ||
IsContractModuleAdmin(ownedByOrganization.OrganizationId),
IOrganizationModule _ => IsGlobalAdmin() ||
IOrganizationModule _ => IsGlobalAdmin() ||
IsLocalAdmin(ownedByOrganization.OrganizationId),
_ => IsGlobalAdmin()
};
Expand Down Expand Up @@ -458,6 +458,14 @@ public bool Visit(AdministerGlobalPermission permission)
};
}

public bool Visit(ImportHierarchyFromStsOrganizationPermission permission)
{
var organizationId = permission.Organization.Id;
return IsGlobalAdmin() ||
IsLocalAdmin(organizationId) ||
IsOrganizationModuleAdmin(organizationId);
}

#endregion PERMISSIONS
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Core.DomainModel.Organization;

namespace Core.ApplicationServices.Authorization.Permissions
{
public class ImportHierarchyFromStsOrganizationPermission : Permission
{
public Organization Organization { get; }

public ImportHierarchyFromStsOrganizationPermission(Organization organization)
{
Organization = organization;
}

public override bool Accept(IPermissionVisitor permissionVisitor)
{
return permissionVisitor.Visit(this);
}
}
}
5 changes: 4 additions & 1 deletion Core.ApplicationServices/Contract/IItContractService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using Core.Abstractions.Types;
using Core.ApplicationServices.Model.Contracts;
using Core.DomainModel.GDPR;
using Core.DomainModel.ItContract;
using Core.DomainServices.Queries;
Expand All @@ -12,7 +13,7 @@ namespace Core.ApplicationServices.Contract
public interface IItContractService
{
Result<ItContract, OperationError> Create(int organizationId, string name);
IQueryable<ItContract> GetAllByOrganization(int orgId, string optionalNameSearch = null);
Result<IQueryable<ItContract>,OperationError> GetAllByOrganization(int orgId, string optionalNameSearch = null);
Result<ItContract, OperationFailure> Delete(int id);

Result<DataProcessingRegistration, OperationError> AssignDataProcessingRegistration(int id, int dataProcessingRegistrationId);
Expand All @@ -23,5 +24,7 @@ public interface IItContractService
Result<bool,OperationError> CanCreateNewContractWithName(string name, int organizationId);
Maybe<OperationError> ValidateNewName(int contractId, string name);
IQueryable<ItContract> Query(params IDomainQuery<ItContract>[] conditions);
Result<ContractOptions, OperationError> GetAssignableContractOptions(int organizationId);
Result<IEnumerable<(int year, int quarter)>,OperationError> GetAppliedProcurementPlans(int organizationId);
}
}
80 changes: 76 additions & 4 deletions Core.ApplicationServices/Contract/ItContractService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Core.Abstractions.Extensions;
using Core.Abstractions.Types;
using Core.ApplicationServices.Authorization;
using Core.ApplicationServices.Model.Contracts;
using Core.ApplicationServices.References;
using Core.DomainModel.Events;
using Core.DomainModel.GDPR;
Expand All @@ -12,6 +13,7 @@
using Core.DomainServices.Authorization;
using Core.DomainServices.Contract;
using Core.DomainServices.Extensions;
using Core.DomainServices.Options;
using Core.DomainServices.Queries;
using Core.DomainServices.Repositories.Contract;
using Infrastructure.Services.DataAccess;
Expand All @@ -31,6 +33,15 @@ public class ItContractService : IItContractService
private readonly ILogger _logger;
private readonly IContractDataProcessingRegistrationAssignmentService _contractDataProcessingRegistrationAssignmentService;
private readonly IOrganizationalUserContext _userContext;
private readonly IOptionsService<ItContract, CriticalityType> _criticalityOptionsService;
private readonly IOptionsService<ItContract, ItContractType> _contractTypeOptionsService;
private readonly IOptionsService<ItContract, ItContractTemplateType> _contractTemplateOptionsService;
private readonly IOptionsService<ItContract, PurchaseFormType> _purchaseFormOptionsService;
private readonly IOptionsService<ItContract, ProcurementStrategyType> _procurementStrategyOptionsService;
private readonly IOptionsService<ItContract, PaymentModelType> _paymentModelOptionsService;
private readonly IOptionsService<ItContract, PaymentFreqencyType> _paymentFrequencyOptionsService;
private readonly IOptionsService<ItContract, OptionExtendType> _optionExtendOptionsService;
private readonly IOptionsService<ItContract, TerminationDeadlineType> _terminationDeadlineOptionsService;

public ItContractService(
IItContractRepository repository,
Expand All @@ -40,8 +51,17 @@ public ItContractService(
IDomainEvents domainEvents,
IAuthorizationContext authorizationContext,
ILogger logger,
IContractDataProcessingRegistrationAssignmentService contractDataProcessingRegistrationAssignmentService,
IOrganizationalUserContext userContext)
IContractDataProcessingRegistrationAssignmentService contractDataProcessingRegistrationAssignmentService,
IOrganizationalUserContext userContext,
IOptionsService<ItContract, CriticalityType> criticalityOptionsService,
IOptionsService<ItContract, ItContractType> contractTypeOptionsService,
IOptionsService<ItContract, ItContractTemplateType> contractTemplateOptionsService,
IOptionsService<ItContract, PurchaseFormType> purchaseFormOptionsService,
IOptionsService<ItContract, ProcurementStrategyType> procurementStrategyOptionsService,
IOptionsService<ItContract, PaymentModelType> paymentModelOptionsService,
IOptionsService<ItContract, PaymentFreqencyType> paymentFrequencyOptionsService,
IOptionsService<ItContract, OptionExtendType> optionExtendOptionsService,
IOptionsService<ItContract, TerminationDeadlineType> terminationDeadlineOptionsService)
{
_repository = repository;
_economyStreamRepository = economyStreamRepository;
Expand All @@ -52,6 +72,15 @@ public ItContractService(
_logger = logger;
_contractDataProcessingRegistrationAssignmentService = contractDataProcessingRegistrationAssignmentService;
_userContext = userContext;
_criticalityOptionsService = criticalityOptionsService;
_contractTypeOptionsService = contractTypeOptionsService;
_contractTemplateOptionsService = contractTemplateOptionsService;
_purchaseFormOptionsService = purchaseFormOptionsService;
_procurementStrategyOptionsService = procurementStrategyOptionsService;
_paymentModelOptionsService = paymentModelOptionsService;
_paymentFrequencyOptionsService = paymentFrequencyOptionsService;
_optionExtendOptionsService = optionExtendOptionsService;
_terminationDeadlineOptionsService = terminationDeadlineOptionsService;
}

public Result<ItContract, OperationError> Create(int organizationId, string name)
Expand All @@ -76,16 +105,20 @@ public Result<ItContract, OperationError> Create(int organizationId, string name
return itContract;
}

public IQueryable<ItContract> GetAllByOrganization(int orgId, string optionalNameSearch = null)
public Result<IQueryable<ItContract>, OperationError> GetAllByOrganization(int orgId, string optionalNameSearch = null)
{
if (_authorizationContext.GetOrganizationReadAccessLevel(orgId) != OrganizationDataReadAccessLevel.All)
{
return new OperationError(OperationFailure.Forbidden);
}
var contracts = _repository.GetContractsInOrganization(orgId);

if (!string.IsNullOrWhiteSpace(optionalNameSearch))
{
contracts = contracts.ByPartOfName(optionalNameSearch);
}

return contracts;
return Result<IQueryable<ItContract>, OperationError>.Success(contracts);
}

public Result<ItContract, OperationFailure> Delete(int id)
Expand Down Expand Up @@ -219,6 +252,45 @@ public Maybe<OperationError> ValidateNewName(int contractId, string name)
);
}

public Result<ContractOptions, OperationError> GetAssignableContractOptions(int organizationId)
{
return WithOrganizationReadAccess(organizationId,
() => new ContractOptions(
_criticalityOptionsService.GetAllOptionsDetails(organizationId),
_contractTypeOptionsService.GetAllOptionsDetails(organizationId),
_contractTemplateOptionsService.GetAllOptionsDetails(organizationId),
_purchaseFormOptionsService.GetAllOptionsDetails(organizationId),
_procurementStrategyOptionsService.GetAllOptionsDetails(organizationId),
_paymentModelOptionsService.GetAllOptionsDetails(organizationId),
_paymentFrequencyOptionsService.GetAllOptionsDetails(organizationId),
_optionExtendOptionsService.GetAllOptionsDetails(organizationId),
_terminationDeadlineOptionsService.GetAllOptionsDetails(organizationId)));
}

public Result<IEnumerable<(int year, int quarter)>, OperationError> GetAppliedProcurementPlans(int organizationId)
{
return GetAllByOrganization(organizationId)
.Select<IEnumerable<(int year, int quarter)>>(contracts => contracts
.Where(contract => contract.ProcurementPlanYear != null && contract.ProcurementPlanQuarter != null)
.Select(c => new { c.ProcurementPlanYear, c.ProcurementPlanQuarter })
.Distinct()
.OrderBy(x => x.ProcurementPlanYear)
.ThenBy(x => x.ProcurementPlanQuarter)
.ToList()
.Select(x => (x.ProcurementPlanYear.GetValueOrDefault(), x.ProcurementPlanQuarter.GetValueOrDefault()))
.ToList()
);
}

private Result<ContractOptions, OperationError> WithOrganizationReadAccess(int organizationId, Func<Result<ContractOptions, OperationError>> authorizedAction)
{
var readAccessLevel = _authorizationContext.GetOrganizationReadAccessLevel(organizationId);

return readAccessLevel < OrganizationDataReadAccessLevel.All
? new OperationError(OperationFailure.Forbidden)
: authorizedAction();
}

private IQueryable<ItContract> SearchByName(int organizationId, string name)
{
return _repository.GetContractsInOrganization(organizationId).ByNameExact(name);
Expand Down
Loading

0 comments on commit 0e3e978

Please sign in to comment.