diff --git a/src/Admin/Views/Shared/_OrganizationForm.cshtml b/src/Admin/Views/Shared/_OrganizationForm.cshtml index 76502ff75..72076cbd3 100644 --- a/src/Admin/Views/Shared/_OrganizationForm.cshtml +++ b/src/Admin/Views/Shared/_OrganizationForm.cshtml @@ -82,7 +82,11 @@ @{ var planTypes = Enum.GetValues() - .Where(p => Model.Provider == null || p is >= PlanType.TeamsMonthly and <= PlanType.TeamsStarter) + .Where(p => + Model.Provider == null || + (Model.Provider != null + && p is >= PlanType.TeamsMonthly2019 and <= PlanType.EnterpriseAnnually2019 or >= PlanType.TeamsMonthly2020 and <= PlanType.EnterpriseAnnually) + ) .Select(e => new SelectListItem { Value = ((int)e).ToString(), diff --git a/src/Infrastructure.EntityFramework/Repositories/OrganizationRepository.cs b/src/Infrastructure.EntityFramework/Repositories/OrganizationRepository.cs index b20026a6b..b7ee85543 100644 --- a/src/Infrastructure.EntityFramework/Repositories/OrganizationRepository.cs +++ b/src/Infrastructure.EntityFramework/Repositories/OrganizationRepository.cs @@ -96,12 +96,17 @@ public class OrganizationRepository : Repository> SearchUnassignedToProviderAsync(string name, string ownerEmail, int skip, int take) { using var scope = ServiceScopeFactory.CreateScope(); + var dbContext = GetDatabaseContext(scope); - var query = from o in dbContext.Organizations - where o.PlanType >= PlanType.TeamsMonthly2020 && o.PlanType <= PlanType.EnterpriseAnnually && - !dbContext.ProviderOrganizations.Any(po => po.OrganizationId == o.Id) && - (string.IsNullOrWhiteSpace(name) || EF.Functions.Like(o.Name, $"%{name}%")) - select o; + + var query = + from o in dbContext.Organizations + where + ((o.PlanType >= PlanType.TeamsMonthly2019 && o.PlanType <= PlanType.EnterpriseAnnually2019) || + (o.PlanType >= PlanType.TeamsMonthly2020 && o.PlanType <= PlanType.EnterpriseAnnually)) && + !dbContext.ProviderOrganizations.Any(po => po.OrganizationId == o.Id) && + (string.IsNullOrWhiteSpace(name) || EF.Functions.Like(o.Name, $"%{name}%")) + select o; if (string.IsNullOrWhiteSpace(ownerEmail)) { diff --git a/src/Sql/dbo/Stored Procedures/Organization_UnassignedToProviderSearch.sql b/src/Sql/dbo/Stored Procedures/Organization_UnassignedToProviderSearch.sql index 45fcbaeb9..dc71c809e 100644 --- a/src/Sql/dbo/Stored Procedures/Organization_UnassignedToProviderSearch.sql +++ b/src/Sql/dbo/Stored Procedures/Organization_UnassignedToProviderSearch.sql @@ -21,7 +21,7 @@ BEGIN INNER JOIN [dbo].[User] U ON U.[Id] = OU.[UserId] WHERE - O.[PlanType] >= 8 AND O.[PlanType] <= 11 -- Get 'Team' and 'Enterprise' Organizations + ((O.[PlanType] >= 2 AND O.[PlanType] <= 5) OR (O.[PlanType] >= 8 AND O.[PlanType] <= 15)) -- All 'Teams' and 'Enterprise' organizations AND NOT EXISTS (SELECT * FROM [dbo].[ProviderOrganizationView] PO WHERE PO.[OrganizationId] = O.[Id]) AND (@Name IS NULL OR O.[Name] LIKE @NameLikeSearch) AND (U.[Email] LIKE @OwnerLikeSearch) @@ -36,7 +36,7 @@ BEGIN FROM [dbo].[OrganizationView] O WHERE - O.[PlanType] >= 8 AND O.[PlanType] <= 11 -- Get 'Team' and 'Enterprise' Organizations + ((O.[PlanType] >= 2 AND O.[PlanType] <= 5) OR (O.[PlanType] >= 8 AND O.[PlanType] <= 15)) -- All 'Teams' and 'Enterprise' organizations AND NOT EXISTS (SELECT * FROM [dbo].[ProviderOrganizationView] PO WHERE PO.[OrganizationId] = O.[Id]) AND (@Name IS NULL OR O.[Name] LIKE @NameLikeSearch) ORDER BY O.[CreationDate] DESC diff --git a/util/Migrator/DbScripts/2023-11-14_00_UpdateOrganizationUnassignedToProviderSearch.sql b/util/Migrator/DbScripts/2023-11-14_00_UpdateOrganizationUnassignedToProviderSearch.sql new file mode 100644 index 000000000..5d85eb486 --- /dev/null +++ b/util/Migrator/DbScripts/2023-11-14_00_UpdateOrganizationUnassignedToProviderSearch.sql @@ -0,0 +1,64 @@ +/* + This procedure is used by the Bitwarden Admin Panel to retrieve the + Organizations a Reseller Provider is capable of adding as a client. + + Currently, the procedure is only surfacing Organizations with the most + current Enterprise or Teams plans, but we actually need to surface any + Enterprise or Teams plan regardless of the version as all of them are + applicable to Resellers. +*/ + +-- Drop existing SPROC +IF OBJECT_ID('[dbo].[Organization_UnassignedToProviderSearch]') IS NOT NULL +BEGIN + DROP PROCEDURE [dbo].[Organization_UnassignedToProviderSearch] +END +GO + +CREATE PROCEDURE [dbo].[Organization_UnassignedToProviderSearch] + @Name NVARCHAR(50), + @OwnerEmail NVARCHAR(256), + @Skip INT = 0, + @Take INT = 25 +WITH RECOMPILE +AS +BEGIN + SET NOCOUNT ON + DECLARE @NameLikeSearch NVARCHAR(55) = '%' + @Name + '%' + DECLARE @OwnerLikeSearch NVARCHAR(55) = @OwnerEmail + '%' + + IF @OwnerEmail IS NOT NULL + BEGIN + SELECT + O.* + FROM + [dbo].[OrganizationView] O + INNER JOIN + [dbo].[OrganizationUser] OU ON O.[Id] = OU.[OrganizationId] + INNER JOIN + [dbo].[User] U ON U.[Id] = OU.[UserId] + WHERE + ((O.[PlanType] >= 2 AND O.[PlanType] <= 5) OR (O.[PlanType] >= 8 AND O.[PlanType] <= 15)) -- All 'Teams' and 'Enterprise' organizations + AND NOT EXISTS (SELECT * FROM [dbo].[ProviderOrganizationView] PO WHERE PO.[OrganizationId] = O.[Id]) + AND (@Name IS NULL OR O.[Name] LIKE @NameLikeSearch) + AND (U.[Email] LIKE @OwnerLikeSearch) + ORDER BY O.[CreationDate] DESC + OFFSET @Skip ROWS + FETCH NEXT @Take ROWS ONLY + END + ELSE + BEGIN + SELECT + O.* + FROM + [dbo].[OrganizationView] O + WHERE + ((O.[PlanType] >= 2 AND O.[PlanType] <= 5) OR (O.[PlanType] >= 8 AND O.[PlanType] <= 15)) -- All 'Teams' and 'Enterprise' organizations + AND NOT EXISTS (SELECT * FROM [dbo].[ProviderOrganizationView] PO WHERE PO.[OrganizationId] = O.[Id]) + AND (@Name IS NULL OR O.[Name] LIKE @NameLikeSearch) + ORDER BY O.[CreationDate] DESC + OFFSET @Skip ROWS + FETCH NEXT @Take ROWS ONLY + END +END +GO