diff --git a/backend/pidp-backend.sln b/backend/pidp-backend.sln index 48d93f95f..05d6c8095 100644 --- a/backend/pidp-backend.sln +++ b/backend/pidp-backend.sln @@ -15,7 +15,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "endorsement-reminder", "ser EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "endorsement-reminder.tests", "services.endorsement-reminder.tests\endorsement-reminder.tests.csproj", "{1251BD7F-30CB-4333-87D3-A96912F86361}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "update-opid", "tools.update-opid\update-opid.csproj", "{631ECF6D-6E61-49EF-933B-B9423A068032}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "do-work", "tools.do-work\do-work.csproj", "{631ECF6D-6E61-49EF-933B-B9423A068032}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/backend/tools.update-opid/.vscode/settings.json b/backend/tools.do-work/.vscode/settings.json similarity index 100% rename from backend/tools.update-opid/.vscode/settings.json rename to backend/tools.do-work/.vscode/settings.json diff --git a/backend/tools.do-work/DoWorkService.cs b/backend/tools.do-work/DoWorkService.cs new file mode 100644 index 000000000..446a19c2d --- /dev/null +++ b/backend/tools.do-work/DoWorkService.cs @@ -0,0 +1,27 @@ +namespace DoWork; + +using Microsoft.EntityFrameworkCore; + +using Pidp.Data; +using Pidp.Infrastructure.HttpClients.Keycloak; + +public class DoWorkService : IDoWorkService +{ + private readonly IKeycloakAdministrationClient keycloakClient; + private readonly PidpDbContext context; + + public DoWorkService(IKeycloakAdministrationClient keycloakClient, PidpDbContext context) + { + this.keycloakClient = keycloakClient; + this.context = context; + } + + public async Task DoWorkAsync() + { + var userId = await this.context.Parties + .Where(party => party.Id == 1001) + .Select(party => party.Credentials.First().UserId) + .SingleOrDefaultAsync(); + await this.keycloakClient.GetUser(userId); + } +} diff --git a/backend/tools.update-opid/HostedServiceWrapper.cs b/backend/tools.do-work/HostedServiceWrapper.cs similarity index 75% rename from backend/tools.update-opid/HostedServiceWrapper.cs rename to backend/tools.do-work/HostedServiceWrapper.cs index ce4d758fe..c51a4abdb 100644 --- a/backend/tools.update-opid/HostedServiceWrapper.cs +++ b/backend/tools.do-work/HostedServiceWrapper.cs @@ -1,17 +1,18 @@ -namespace UpdateOpId; +namespace DoWork; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using System.Diagnostics; internal sealed class HostedServiceWrapper : IHostedService { - private readonly IUpdateOpIdService service; + private readonly IDoWorkService service; private readonly IHostApplicationLifetime appLifetime; private readonly ILogger logger; private int? exitCode; public HostedServiceWrapper( - IUpdateOpIdService service, + IDoWorkService service, IHostApplicationLifetime appLifetime, ILogger logger) { @@ -24,9 +25,11 @@ public Task StartAsync(CancellationToken cancellationToken) { this.appLifetime.ApplicationStarted.Register(async () => { + var sw = Stopwatch.StartNew(); try { - await this.service.UpdateOpIdAsync(); + Console.WriteLine(">>>> Starting Work."); + await this.service.DoWorkAsync(); this.exitCode = 0; } catch (Exception ex) @@ -36,6 +39,8 @@ public Task StartAsync(CancellationToken cancellationToken) } finally { + sw.Stop(); + Console.WriteLine($">>>> Work Stopped. Total Run Time: {(sw.ElapsedMilliseconds > 1000 ? sw.ElapsedMilliseconds / 1000 : sw.ElapsedMilliseconds + "m")}s."); this.appLifetime.StopApplication(); } }); diff --git a/backend/tools.do-work/IDoWorkService.cs b/backend/tools.do-work/IDoWorkService.cs new file mode 100644 index 000000000..ae24cf887 --- /dev/null +++ b/backend/tools.do-work/IDoWorkService.cs @@ -0,0 +1,9 @@ +namespace DoWork; + +public interface IDoWorkService +{ + /// + /// A service with DI that can be updated to perform manual tasks. + /// + public Task DoWorkAsync(); +} diff --git a/backend/tools.update-opid/Program.cs b/backend/tools.do-work/Program.cs similarity index 69% rename from backend/tools.update-opid/Program.cs rename to backend/tools.do-work/Program.cs index 9a1b34643..52a41ef62 100644 --- a/backend/tools.update-opid/Program.cs +++ b/backend/tools.do-work/Program.cs @@ -5,12 +5,10 @@ using NodaTime; using System.Reflection; -using UpdateOpId; +using DoWork; using Pidp; using Pidp.Data; using Pidp.Infrastructure.HttpClients; -using Pidp.Infrastructure.HttpClients.Keycloak; - await Host.CreateDefaultBuilder(args) .UseContentRoot(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)) @@ -18,19 +16,11 @@ await Host.CreateDefaultBuilder(args) { var config = InitializeConfiguration(services); - services.AddHttpClient(); - services.AddHttpClientWithBaseAddress(config.Keycloak.AdministrationUrl) - .WithBearerToken(new KeycloakAdministrationClientCredentials - { - Address = config.Keycloak.TokenUrl, - ClientId = config.Keycloak.AdministrationClientId, - ClientSecret = config.Keycloak.AdministrationClientSecret - }); - services + .AddHttpClients(config) .AddSingleton(SystemClock.Instance) .AddMediatR(opt => opt.RegisterServicesFromAssemblyContaining()) - .AddTransient() + .AddTransient() .AddHostedService() .AddDbContext(options => options .UseNpgsql(config.ConnectionStrings.PidpDatabase, npg => npg.UseNodaTime()) diff --git a/backend/tools.do-work/README.md b/backend/tools.do-work/README.md new file mode 100644 index 000000000..2aa75c3ef --- /dev/null +++ b/backend/tools.do-work/README.md @@ -0,0 +1,5 @@ +# Do-Work Tool + +This tool is intended as a standalone app to run ad-hoc scripts and migrations using the same Dependancy Injection as the main webapi project. +Add whatever additional services you may need to the DI in `Program.cs`, and update `appsettings.json` with the needed environment variables/screts. +Be sure not to commit any secrets when doing so. diff --git a/backend/tools.update-opid/appsettings.json b/backend/tools.do-work/appsettings.json similarity index 100% rename from backend/tools.update-opid/appsettings.json rename to backend/tools.do-work/appsettings.json diff --git a/backend/tools.update-opid/update-opid.csproj b/backend/tools.do-work/do-work.csproj similarity index 69% rename from backend/tools.update-opid/update-opid.csproj rename to backend/tools.do-work/do-work.csproj index 21ad846c2..afcebeb23 100644 --- a/backend/tools.update-opid/update-opid.csproj +++ b/backend/tools.do-work/do-work.csproj @@ -3,17 +3,13 @@ Exe net6.0 - UpdateOpId + DoWork enable enable - 5c2dc965-00b4-4531-9ff0-9b37193ead9b - - - PreserveNewest diff --git a/backend/tools.update-opid/IUpdateOpIdService.cs b/backend/tools.update-opid/IUpdateOpIdService.cs deleted file mode 100644 index ebe92a0de..000000000 --- a/backend/tools.update-opid/IUpdateOpIdService.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace UpdateOpId; - -public interface IUpdateOpIdService -{ - /// - /// Generates an identifier for each Party in the database - /// with a BCSC account that does not have an OpId - /// and updates the party in the database. - /// - /// - public Task UpdateOpIdAsync(); -} diff --git a/backend/tools.update-opid/UpdateOpIdService.cs b/backend/tools.update-opid/UpdateOpIdService.cs deleted file mode 100644 index 790ade020..000000000 --- a/backend/tools.update-opid/UpdateOpIdService.cs +++ /dev/null @@ -1,44 +0,0 @@ -namespace UpdateOpId; - -using Microsoft.EntityFrameworkCore; - -using Pidp.Data; -using Pidp.Infrastructure.Auth; -using Pidp.Infrastructure.HttpClients.Keycloak; - -public class UpdateOpIdService : IUpdateOpIdService -{ - private readonly PidpDbContext context; - private readonly IKeycloakAdministrationClient keycloakClient; - - public UpdateOpIdService(PidpDbContext context, IKeycloakAdministrationClient keycloakClient) - { - this.context = context; - this.keycloakClient = keycloakClient; - } - - public async Task UpdateOpIdAsync() - { - Console.WriteLine(">>>>Start!"); - var parties = await this.context.Parties - .Include(party => party.Credentials) - .Take(1000) - .Where(party => party.OpId == null - && party.Credentials.Any(credential => credential.IdentityProvider == IdentityProviders.BCServicesCard)) - .ToListAsync(); - - foreach (var party in parties) - { - await party.GenerateOpId(this.context); - - foreach (var userId in party.Credentials.Select(credential => credential.UserId)) - { - await this.keycloakClient.UpdateUser(userId, user => user.SetOpId(party.OpId!)); - } - } - - Console.WriteLine("<<< -{ -} diff --git a/backend/webapi/Data/Configuration/OrganizationConfiguration.cs b/backend/webapi/Data/Configuration/OrganizationConfiguration.cs deleted file mode 100644 index b635aada4..000000000 --- a/backend/webapi/Data/Configuration/OrganizationConfiguration.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Pidp.Data.Configuration; - -using Pidp.Models.Lookups; - -public class OrganizationConfiguration : LookupTableConfiguration -{ -} diff --git a/backend/webapi/Data/Migrations/20240405005433_RemoveOrganization.Designer.cs b/backend/webapi/Data/Migrations/20240405005433_RemoveOrganization.Designer.cs new file mode 100644 index 000000000..e12bab256 --- /dev/null +++ b/backend/webapi/Data/Migrations/20240405005433_RemoveOrganization.Designer.cs @@ -0,0 +1,1426 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using NodaTime; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Pidp.Data; + +#nullable disable + +namespace Pidp.Data.Migrations +{ + [DbContext(typeof(PidpDbContext))] + [Migration("20240405005433_RemoveOrganization")] + partial class RemoveOrganization + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.2") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Pidp.Models.AccessRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessTypeCode") + .HasColumnType("integer"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.Property("PartyId") + .HasColumnType("integer"); + + b.Property("RequestedOn") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("PartyId"); + + b.ToTable("AccessRequest"); + }); + + modelBuilder.Entity("Pidp.Models.Address", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("City") + .IsRequired() + .HasColumnType("text"); + + b.Property("CountryCode") + .IsRequired() + .HasColumnType("text"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.Property("Postal") + .IsRequired() + .HasColumnType("text"); + + b.Property("ProvinceCode") + .IsRequired() + .HasColumnType("text"); + + b.Property("Street") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CountryCode"); + + b.HasIndex("ProvinceCode"); + + b.ToTable("Address"); + + b.HasDiscriminator("Discriminator").HasValue("Address"); + }); + + modelBuilder.Entity("Pidp.Models.BusinessEvent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.Property("RecordedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Severity") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("BusinessEvent"); + + b.HasDiscriminator("Discriminator").HasValue("BusinessEvent"); + }); + + modelBuilder.Entity("Pidp.Models.ClientLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AdditionalInformation") + .HasColumnType("text"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("LogLevel") + .HasColumnType("integer"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("ClientLog"); + }); + + modelBuilder.Entity("Pidp.Models.Credential", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("IdentityProvider") + .HasColumnType("text"); + + b.Property("IdpId") + .HasColumnType("text"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.Property("PartyId") + .HasColumnType("integer"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("PartyId"); + + b.HasIndex("UserId") + .IsUnique() + .HasFilter("\"UserId\" != '00000000-0000-0000-0000-000000000000'"); + + b.ToTable("Credential"); + + b.HasCheckConstraint("CHK_Credential_AtLeastOneIdentifier", "((\"UserId\" != '00000000-0000-0000-0000-000000000000') or (\"IdpId\" is not null))"); + }); + + modelBuilder.Entity("Pidp.Models.CredentialLinkTicket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Claimed") + .HasColumnType("boolean"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.Property("LinkToIdentityProvider") + .IsRequired() + .HasColumnType("text"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.Property("PartyId") + .HasColumnType("integer"); + + b.Property("Token") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("PartyId"); + + b.ToTable("CredentialLinkTicket"); + }); + + modelBuilder.Entity("Pidp.Models.EmailLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Body") + .IsRequired() + .HasColumnType("text"); + + b.Property("Cc") + .IsRequired() + .HasColumnType("text"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("DateSent") + .HasColumnType("timestamp with time zone"); + + b.Property("LatestStatus") + .HasColumnType("text"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.Property("MsgId") + .HasColumnType("uuid"); + + b.Property("SendType") + .IsRequired() + .HasColumnType("text"); + + b.Property("SentTo") + .IsRequired() + .HasColumnType("text"); + + b.Property("StatusMessage") + .HasColumnType("text"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpdateCount") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("EmailLog"); + }); + + modelBuilder.Entity("Pidp.Models.Endorsement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedOn") + .HasColumnType("timestamp with time zone"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("Endorsement"); + }); + + modelBuilder.Entity("Pidp.Models.EndorsementRelationship", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("EndorsementId") + .HasColumnType("integer"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.Property("PartyId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("EndorsementId"); + + b.HasIndex("PartyId"); + + b.ToTable("EndorsementRelationship"); + }); + + modelBuilder.Entity("Pidp.Models.EndorsementRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AdditionalInformation") + .HasColumnType("text"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.Property("ReceivingPartyId") + .HasColumnType("integer"); + + b.Property("RecipientEmail") + .IsRequired() + .HasColumnType("text"); + + b.Property("RequestingPartyId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("StatusDate") + .HasColumnType("timestamp with time zone"); + + b.Property("Token") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ReceivingPartyId"); + + b.HasIndex("RequestingPartyId"); + + b.ToTable("EndorsementRequest"); + }); + + modelBuilder.Entity("Pidp.Models.Lookups.AccessType", b => + { + b.Property("Code") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Code"); + + b.ToTable("AccessTypeLookup"); + + b.HasData( + new + { + Code = 1, + Name = "Special Authority eForms" + }, + new + { + Code = 2, + Name = "HCIMWeb Account Transfer" + }, + new + { + Code = 3, + Name = "HCIMWeb Enrolment" + }, + new + { + Code = 4, + Name = "Driver Medical Fitness" + }, + new + { + Code = 5, + Name = "MS Teams for Clinical Use - Privacy Officer" + }, + new + { + Code = 6, + Name = "Prescription Refill eForm for Pharmacists" + }, + new + { + Code = 7, + Name = "Provider Reporting Portal" + }, + new + { + Code = 8, + Name = "MS Teams for Clinical Use - Clinic Member" + }, + new + { + Code = 9, + Name = "Access Harmonization User Access Agreement" + }, + new + { + Code = 10, + Name = "Immunization Entry eForm" + }, + new + { + Code = 11, + Name = "EDRD eForm" + }); + }); + + modelBuilder.Entity("Pidp.Models.Lookups.College", b => + { + b.Property("Code") + .HasColumnType("integer"); + + b.Property("Acronym") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Code"); + + b.ToTable("CollegeLookup"); + + b.HasData( + new + { + Code = 1, + Acronym = "CPSBC", + Name = "College of Physicians and Surgeons of BC" + }, + new + { + Code = 2, + Acronym = "CPBC", + Name = "College of Pharmacists of BC" + }, + new + { + Code = 3, + Acronym = "BCCNM", + Name = "BC College of Nurses and Midwives" + }, + new + { + Code = 4, + Acronym = "CNPBC", + Name = "College of Naturopathic Physicians of BC" + }, + new + { + Code = 5, + Acronym = "CDSBC", + Name = "College of Dental Surgeons of British Columbia" + }, + new + { + Code = 6, + Acronym = "COBC", + Name = "College of Optometrists of British Columbia" + }); + }); + + modelBuilder.Entity("Pidp.Models.Lookups.Country", b => + { + b.Property("Code") + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Code"); + + b.ToTable("CountryLookup"); + + b.HasData( + new + { + Code = "CA", + Name = "Canada" + }, + new + { + Code = "US", + Name = "United States" + }); + }); + + modelBuilder.Entity("Pidp.Models.Lookups.Province", b => + { + b.Property("Code") + .HasColumnType("text"); + + b.Property("CountryCode") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Code"); + + b.ToTable("ProvinceLookup"); + + b.HasData( + new + { + Code = "AB", + CountryCode = "CA", + Name = "Alberta" + }, + new + { + Code = "BC", + CountryCode = "CA", + Name = "British Columbia" + }, + new + { + Code = "MB", + CountryCode = "CA", + Name = "Manitoba" + }, + new + { + Code = "NB", + CountryCode = "CA", + Name = "New Brunswick" + }, + new + { + Code = "NL", + CountryCode = "CA", + Name = "Newfoundland and Labrador" + }, + new + { + Code = "NS", + CountryCode = "CA", + Name = "Nova Scotia" + }, + new + { + Code = "ON", + CountryCode = "CA", + Name = "Ontario" + }, + new + { + Code = "PE", + CountryCode = "CA", + Name = "Prince Edward Island" + }, + new + { + Code = "QC", + CountryCode = "CA", + Name = "Quebec" + }, + new + { + Code = "SK", + CountryCode = "CA", + Name = "Saskatchewan" + }, + new + { + Code = "NT", + CountryCode = "CA", + Name = "Northwest Territories" + }, + new + { + Code = "NU", + CountryCode = "CA", + Name = "Nunavut" + }, + new + { + Code = "YT", + CountryCode = "CA", + Name = "Yukon" + }, + new + { + Code = "AL", + CountryCode = "US", + Name = "Alabama" + }, + new + { + Code = "AK", + CountryCode = "US", + Name = "Alaska" + }, + new + { + Code = "AS", + CountryCode = "US", + Name = "American Samoa" + }, + new + { + Code = "AZ", + CountryCode = "US", + Name = "Arizona" + }, + new + { + Code = "AR", + CountryCode = "US", + Name = "Arkansas" + }, + new + { + Code = "CA", + CountryCode = "US", + Name = "California" + }, + new + { + Code = "CO", + CountryCode = "US", + Name = "Colorado" + }, + new + { + Code = "CT", + CountryCode = "US", + Name = "Connecticut" + }, + new + { + Code = "DE", + CountryCode = "US", + Name = "Delaware" + }, + new + { + Code = "DC", + CountryCode = "US", + Name = "District of Columbia" + }, + new + { + Code = "FL", + CountryCode = "US", + Name = "Florida" + }, + new + { + Code = "GA", + CountryCode = "US", + Name = "Georgia" + }, + new + { + Code = "GU", + CountryCode = "US", + Name = "Guam" + }, + new + { + Code = "HI", + CountryCode = "US", + Name = "Hawaii" + }, + new + { + Code = "ID", + CountryCode = "US", + Name = "Idaho" + }, + new + { + Code = "IL", + CountryCode = "US", + Name = "Illinois" + }, + new + { + Code = "IN", + CountryCode = "US", + Name = "Indiana" + }, + new + { + Code = "IA", + CountryCode = "US", + Name = "Iowa" + }, + new + { + Code = "KS", + CountryCode = "US", + Name = "Kansas" + }, + new + { + Code = "KY", + CountryCode = "US", + Name = "Kentucky" + }, + new + { + Code = "LA", + CountryCode = "US", + Name = "Louisiana" + }, + new + { + Code = "ME", + CountryCode = "US", + Name = "Maine" + }, + new + { + Code = "MD", + CountryCode = "US", + Name = "Maryland" + }, + new + { + Code = "MA", + CountryCode = "US", + Name = "Massachusetts" + }, + new + { + Code = "MI", + CountryCode = "US", + Name = "Michigan" + }, + new + { + Code = "MN", + CountryCode = "US", + Name = "Minnesota" + }, + new + { + Code = "MS", + CountryCode = "US", + Name = "Mississippi" + }, + new + { + Code = "MO", + CountryCode = "US", + Name = "Missouri" + }, + new + { + Code = "MT", + CountryCode = "US", + Name = "Montana" + }, + new + { + Code = "NE", + CountryCode = "US", + Name = "Nebraska" + }, + new + { + Code = "NV", + CountryCode = "US", + Name = "Nevada" + }, + new + { + Code = "NH", + CountryCode = "US", + Name = "New Hampshire" + }, + new + { + Code = "NJ", + CountryCode = "US", + Name = "New Jersey" + }, + new + { + Code = "NM", + CountryCode = "US", + Name = "New Mexico" + }, + new + { + Code = "NY", + CountryCode = "US", + Name = "New York" + }, + new + { + Code = "NC", + CountryCode = "US", + Name = "North Carolina" + }, + new + { + Code = "ND", + CountryCode = "US", + Name = "North Dakota" + }, + new + { + Code = "MP", + CountryCode = "US", + Name = "Northern Mariana Islands" + }, + new + { + Code = "OH", + CountryCode = "US", + Name = "Ohio" + }, + new + { + Code = "OK", + CountryCode = "US", + Name = "Oklahoma" + }, + new + { + Code = "OR", + CountryCode = "US", + Name = "Oregon" + }, + new + { + Code = "PA", + CountryCode = "US", + Name = "Pennsylvania" + }, + new + { + Code = "PR", + CountryCode = "US", + Name = "Puerto Rico" + }, + new + { + Code = "RI", + CountryCode = "US", + Name = "Rhode Island" + }, + new + { + Code = "SC", + CountryCode = "US", + Name = "South Carolina" + }, + new + { + Code = "SD", + CountryCode = "US", + Name = "South Dakota" + }, + new + { + Code = "TN", + CountryCode = "US", + Name = "Tennessee" + }, + new + { + Code = "TX", + CountryCode = "US", + Name = "Texas" + }, + new + { + Code = "UM", + CountryCode = "US", + Name = "United States Minor Outlying Islands" + }, + new + { + Code = "UT", + CountryCode = "US", + Name = "Utah" + }, + new + { + Code = "VT", + CountryCode = "US", + Name = "Vermont" + }, + new + { + Code = "VI", + CountryCode = "US", + Name = "Virgin Islands, U.S." + }, + new + { + Code = "VA", + CountryCode = "US", + Name = "Virginia" + }, + new + { + Code = "WA", + CountryCode = "US", + Name = "Washington" + }, + new + { + Code = "WV", + CountryCode = "US", + Name = "West Virginia" + }, + new + { + Code = "WI", + CountryCode = "US", + Name = "Wisconsin" + }, + new + { + Code = "WY", + CountryCode = "US", + Name = "Wyoming" + }); + }); + + modelBuilder.Entity("Pidp.Models.MSTeamsClinic", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("PrivacyOfficerId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PrivacyOfficerId"); + + b.ToTable("MSTeamsClinic"); + }); + + modelBuilder.Entity("Pidp.Models.Party", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Birthdate") + .HasColumnType("date"); + + b.Property("Cpn") + .HasColumnType("text"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Email") + .HasColumnType("text"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.Property("OpId") + .HasColumnType("text"); + + b.Property("Phone") + .HasColumnType("text"); + + b.Property("PreferredFirstName") + .HasColumnType("text"); + + b.Property("PreferredLastName") + .HasColumnType("text"); + + b.Property("PreferredMiddleName") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("OpId") + .IsUnique(); + + b.ToTable("Party"); + }); + + modelBuilder.Entity("Pidp.Models.PartyLicenceDeclaration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CollegeCode") + .HasColumnType("integer"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("LicenceNumber") + .HasColumnType("text"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.Property("PartyId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CollegeCode"); + + b.HasIndex("PartyId") + .IsUnique(); + + b.ToTable("PartyLicenceDeclaration"); + }); + + modelBuilder.Entity("Pidp.Models.PrpAuthorizedLicence", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Claimed") + .HasColumnType("boolean"); + + b.Property("LicenceNumber") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("LicenceNumber") + .IsUnique(); + + b.ToTable("PrpAuthorizedLicence"); + }); + + modelBuilder.Entity("Pidp.Models.HcimAccountTransfer", b => + { + b.HasBaseType("Pidp.Models.AccessRequest"); + + b.Property("LdapUsername") + .IsRequired() + .HasColumnType("text"); + + b.ToTable("HcimAccountTransfer"); + }); + + modelBuilder.Entity("Pidp.Models.LicenceStatusRoleAssigned", b => + { + b.HasBaseType("Pidp.Models.BusinessEvent"); + + b.Property("PartyId") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("PartyId"); + + b.HasIndex("PartyId"); + + b.ToTable("BusinessEvent"); + + b.HasDiscriminator().HasValue("LicenceStatusRoleAssigned"); + }); + + modelBuilder.Entity("Pidp.Models.LicenceStatusRoleUnassigned", b => + { + b.HasBaseType("Pidp.Models.BusinessEvent"); + + b.Property("PartyId") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("PartyId"); + + b.HasIndex("PartyId"); + + b.ToTable("BusinessEvent"); + + b.HasDiscriminator().HasValue("LicenceStatusRoleUnassigned"); + }); + + modelBuilder.Entity("Pidp.Models.MSTeamsClinicAddress", b => + { + b.HasBaseType("Pidp.Models.Address"); + + b.Property("ClinicId") + .HasColumnType("integer"); + + b.HasIndex("ClinicId") + .IsUnique(); + + b.ToTable("Address"); + + b.HasDiscriminator().HasValue("MSTeamsClinicAddress"); + }); + + modelBuilder.Entity("Pidp.Models.MSTeamsClinicMemberEnrolment", b => + { + b.HasBaseType("Pidp.Models.AccessRequest"); + + b.Property("ClinicId") + .HasColumnType("integer"); + + b.HasIndex("ClinicId"); + + b.ToTable("MSTeamsClinicMemberEnrolment"); + }); + + modelBuilder.Entity("Pidp.Models.PartyNotInPlr", b => + { + b.HasBaseType("Pidp.Models.BusinessEvent"); + + b.Property("PartyId") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("PartyId"); + + b.HasIndex("PartyId"); + + b.ToTable("BusinessEvent"); + + b.HasDiscriminator().HasValue("PartyNotInPlr"); + }); + + modelBuilder.Entity("Pidp.Models.AccessRequest", b => + { + b.HasOne("Pidp.Models.Party", "Party") + .WithMany("AccessRequests") + .HasForeignKey("PartyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Party"); + }); + + modelBuilder.Entity("Pidp.Models.Address", b => + { + b.HasOne("Pidp.Models.Lookups.Country", "Country") + .WithMany() + .HasForeignKey("CountryCode") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Pidp.Models.Lookups.Province", "Province") + .WithMany() + .HasForeignKey("ProvinceCode") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Country"); + + b.Navigation("Province"); + }); + + modelBuilder.Entity("Pidp.Models.Credential", b => + { + b.HasOne("Pidp.Models.Party", "Party") + .WithMany("Credentials") + .HasForeignKey("PartyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Party"); + }); + + modelBuilder.Entity("Pidp.Models.CredentialLinkTicket", b => + { + b.HasOne("Pidp.Models.Party", "Party") + .WithMany() + .HasForeignKey("PartyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Party"); + }); + + modelBuilder.Entity("Pidp.Models.EndorsementRelationship", b => + { + b.HasOne("Pidp.Models.Endorsement", "Endorsement") + .WithMany("EndorsementRelationships") + .HasForeignKey("EndorsementId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Pidp.Models.Party", "Party") + .WithMany() + .HasForeignKey("PartyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Endorsement"); + + b.Navigation("Party"); + }); + + modelBuilder.Entity("Pidp.Models.EndorsementRequest", b => + { + b.HasOne("Pidp.Models.Party", "ReceivingParty") + .WithMany() + .HasForeignKey("ReceivingPartyId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("Pidp.Models.Party", "RequestingParty") + .WithMany() + .HasForeignKey("RequestingPartyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ReceivingParty"); + + b.Navigation("RequestingParty"); + }); + + modelBuilder.Entity("Pidp.Models.MSTeamsClinic", b => + { + b.HasOne("Pidp.Models.Party", "PrivacyOfficer") + .WithMany() + .HasForeignKey("PrivacyOfficerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PrivacyOfficer"); + }); + + modelBuilder.Entity("Pidp.Models.PartyLicenceDeclaration", b => + { + b.HasOne("Pidp.Models.Lookups.College", "College") + .WithMany() + .HasForeignKey("CollegeCode"); + + b.HasOne("Pidp.Models.Party", "Party") + .WithOne("LicenceDeclaration") + .HasForeignKey("Pidp.Models.PartyLicenceDeclaration", "PartyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("College"); + + b.Navigation("Party"); + }); + + modelBuilder.Entity("Pidp.Models.HcimAccountTransfer", b => + { + b.HasOne("Pidp.Models.AccessRequest", null) + .WithOne() + .HasForeignKey("Pidp.Models.HcimAccountTransfer", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Pidp.Models.LicenceStatusRoleAssigned", b => + { + b.HasOne("Pidp.Models.Party", "Party") + .WithMany() + .HasForeignKey("PartyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Party"); + }); + + modelBuilder.Entity("Pidp.Models.LicenceStatusRoleUnassigned", b => + { + b.HasOne("Pidp.Models.Party", "Party") + .WithMany() + .HasForeignKey("PartyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Party"); + }); + + modelBuilder.Entity("Pidp.Models.MSTeamsClinicAddress", b => + { + b.HasOne("Pidp.Models.MSTeamsClinic", "Clinic") + .WithOne("Address") + .HasForeignKey("Pidp.Models.MSTeamsClinicAddress", "ClinicId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Clinic"); + }); + + modelBuilder.Entity("Pidp.Models.MSTeamsClinicMemberEnrolment", b => + { + b.HasOne("Pidp.Models.MSTeamsClinic", "Clinic") + .WithMany() + .HasForeignKey("ClinicId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Pidp.Models.AccessRequest", null) + .WithOne() + .HasForeignKey("Pidp.Models.MSTeamsClinicMemberEnrolment", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Clinic"); + }); + + modelBuilder.Entity("Pidp.Models.PartyNotInPlr", b => + { + b.HasOne("Pidp.Models.Party", "Party") + .WithMany() + .HasForeignKey("PartyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Party"); + }); + + modelBuilder.Entity("Pidp.Models.Endorsement", b => + { + b.Navigation("EndorsementRelationships"); + }); + + modelBuilder.Entity("Pidp.Models.MSTeamsClinic", b => + { + b.Navigation("Address") + .IsRequired(); + }); + + modelBuilder.Entity("Pidp.Models.Party", b => + { + b.Navigation("AccessRequests"); + + b.Navigation("Credentials"); + + b.Navigation("LicenceDeclaration"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/backend/webapi/Data/Migrations/20240405005433_RemoveOrganization.cs b/backend/webapi/Data/Migrations/20240405005433_RemoveOrganization.cs new file mode 100644 index 000000000..26e120180 --- /dev/null +++ b/backend/webapi/Data/Migrations/20240405005433_RemoveOrganization.cs @@ -0,0 +1,234 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using NodaTime; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Pidp.Data.Migrations +{ + public partial class RemoveOrganization : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Address_Facility_FacilityId", + table: "Address"); + + migrationBuilder.DropTable( + name: "Facility"); + + migrationBuilder.DropTable( + name: "HcimEnrolment"); + + migrationBuilder.DropTable( + name: "HealthAuthorityLookup"); + + migrationBuilder.DropTable( + name: "OrganizationLookup"); + + migrationBuilder.DropTable( + name: "PartyAccessAdministrator"); + + migrationBuilder.DropTable( + name: "PartyOrgainizationDetail"); + + migrationBuilder.DropIndex( + name: "IX_Address_FacilityId", + table: "Address"); + + migrationBuilder.DropColumn( + name: "JobTitle", + table: "Party"); + + migrationBuilder.DropColumn( + name: "FacilityId", + table: "Address"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "JobTitle", + table: "Party", + type: "text", + nullable: true); + + migrationBuilder.AddColumn( + name: "FacilityId", + table: "Address", + type: "integer", + nullable: true); + + migrationBuilder.CreateTable( + name: "Facility", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + PartyId = table.Column(type: "integer", nullable: false), + Created = table.Column(type: "timestamp with time zone", nullable: false), + Modified = table.Column(type: "timestamp with time zone", nullable: false), + Name = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Facility", x => x.Id); + table.ForeignKey( + name: "FK_Facility_Party_PartyId", + column: x => x.PartyId, + principalTable: "Party", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "HcimEnrolment", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false), + ManagesTasks = table.Column(type: "boolean", nullable: false), + ModifiesPhns = table.Column(type: "boolean", nullable: false), + RecordsNewborns = table.Column(type: "boolean", nullable: false), + SearchesIdentifiers = table.Column(type: "boolean", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_HcimEnrolment", x => x.Id); + table.ForeignKey( + name: "FK_HcimEnrolment_AccessRequest_Id", + column: x => x.Id, + principalTable: "AccessRequest", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "HealthAuthorityLookup", + columns: table => new + { + Code = table.Column(type: "integer", nullable: false), + Name = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_HealthAuthorityLookup", x => x.Code); + }); + + migrationBuilder.CreateTable( + name: "OrganizationLookup", + columns: table => new + { + Code = table.Column(type: "integer", nullable: false), + Name = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_OrganizationLookup", x => x.Code); + }); + + migrationBuilder.CreateTable( + name: "PartyAccessAdministrator", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + PartyId = table.Column(type: "integer", nullable: false), + Created = table.Column(type: "timestamp with time zone", nullable: false), + Email = table.Column(type: "text", nullable: false), + Modified = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PartyAccessAdministrator", x => x.Id); + table.ForeignKey( + name: "FK_PartyAccessAdministrator_Party_PartyId", + column: x => x.PartyId, + principalTable: "Party", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "PartyOrgainizationDetail", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + PartyId = table.Column(type: "integer", nullable: false), + Created = table.Column(type: "timestamp with time zone", nullable: false), + EmployeeIdentifier = table.Column(type: "text", nullable: false), + HealthAuthorityCode = table.Column(type: "integer", nullable: false), + Modified = table.Column(type: "timestamp with time zone", nullable: false), + OrganizationCode = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PartyOrgainizationDetail", x => x.Id); + table.ForeignKey( + name: "FK_PartyOrgainizationDetail_Party_PartyId", + column: x => x.PartyId, + principalTable: "Party", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.InsertData( + table: "HealthAuthorityLookup", + columns: new[] { "Code", "Name" }, + values: new object[,] + { + { 1, "Provincial Health Services Authority" }, + { 2, "Vancouver Island Health Authority" }, + { 3, "Vancouver Coastal Health Authority" }, + { 4, "Fraser Health Authority" }, + { 5, "Interior Health Authority" }, + { 6, "Northern Health Authority" }, + { 7, "First Nations Health Authority" } + }); + + migrationBuilder.InsertData( + table: "OrganizationLookup", + columns: new[] { "Code", "Name" }, + values: new object[,] + { + { 1, "Health Authority" }, + { 2, "BC Government Ministry" }, + { 3, "Maximus" }, + { 4, "ICBC" }, + { 5, "Other" } + }); + + migrationBuilder.CreateIndex( + name: "IX_Address_FacilityId", + table: "Address", + column: "FacilityId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Facility_PartyId", + table: "Facility", + column: "PartyId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_PartyAccessAdministrator_PartyId", + table: "PartyAccessAdministrator", + column: "PartyId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_PartyOrgainizationDetail_PartyId", + table: "PartyOrgainizationDetail", + column: "PartyId", + unique: true); + + migrationBuilder.AddForeignKey( + name: "FK_Address_Facility_FacilityId", + table: "Address", + column: "FacilityId", + principalTable: "Facility", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/backend/webapi/Data/Migrations/PidpDbContextModelSnapshot.cs b/backend/webapi/Data/Migrations/PidpDbContextModelSnapshot.cs index 5a29cd110..e08eb8b14 100644 --- a/backend/webapi/Data/Migrations/PidpDbContextModelSnapshot.cs +++ b/backend/webapi/Data/Migrations/PidpDbContextModelSnapshot.cs @@ -395,35 +395,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("EndorsementRequest"); }); - modelBuilder.Entity("Pidp.Models.Facility", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Created") - .HasColumnType("timestamp with time zone"); - - b.Property("Modified") - .HasColumnType("timestamp with time zone"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("PartyId") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.HasIndex("PartyId") - .IsUnique(); - - b.ToTable("Facility"); - }); - modelBuilder.Entity("Pidp.Models.Lookups.AccessType", b => { b.Property("Code") @@ -577,98 +548,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) }); }); - modelBuilder.Entity("Pidp.Models.Lookups.HealthAuthority", b => - { - b.Property("Code") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Code"); - - b.ToTable("HealthAuthorityLookup"); - - b.HasData( - new - { - Code = 1, - Name = "Provincial Health Services Authority" - }, - new - { - Code = 2, - Name = "Vancouver Island Health Authority" - }, - new - { - Code = 3, - Name = "Vancouver Coastal Health Authority" - }, - new - { - Code = 4, - Name = "Fraser Health Authority" - }, - new - { - Code = 5, - Name = "Interior Health Authority" - }, - new - { - Code = 6, - Name = "Northern Health Authority" - }, - new - { - Code = 7, - Name = "First Nations Health Authority" - }); - }); - - modelBuilder.Entity("Pidp.Models.Lookups.Organization", b => - { - b.Property("Code") - .HasColumnType("integer"); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Code"); - - b.ToTable("OrganizationLookup"); - - b.HasData( - new - { - Code = 1, - Name = "Health Authority" - }, - new - { - Code = 2, - Name = "BC Government Ministry" - }, - new - { - Code = 3, - Name = "Maximus" - }, - new - { - Code = 4, - Name = "ICBC" - }, - new - { - Code = 5, - Name = "Other" - }); - }); - modelBuilder.Entity("Pidp.Models.Lookups.Province", b => { b.Property("Code") @@ -1161,9 +1040,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired() .HasColumnType("text"); - b.Property("JobTitle") - .HasColumnType("text"); - b.Property("LastName") .IsRequired() .HasColumnType("text"); @@ -1194,35 +1070,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Party"); }); - modelBuilder.Entity("Pidp.Models.PartyAccessAdministrator", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Created") - .HasColumnType("timestamp with time zone"); - - b.Property("Email") - .IsRequired() - .HasColumnType("text"); - - b.Property("Modified") - .HasColumnType("timestamp with time zone"); - - b.Property("PartyId") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.HasIndex("PartyId") - .IsUnique(); - - b.ToTable("PartyAccessAdministrator"); - }); - modelBuilder.Entity("Pidp.Models.PartyLicenceDeclaration", b => { b.Property("Id") @@ -1256,41 +1103,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("PartyLicenceDeclaration"); }); - modelBuilder.Entity("Pidp.Models.PartyOrgainizationDetail", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Created") - .HasColumnType("timestamp with time zone"); - - b.Property("EmployeeIdentifier") - .IsRequired() - .HasColumnType("text"); - - b.Property("HealthAuthorityCode") - .HasColumnType("integer"); - - b.Property("Modified") - .HasColumnType("timestamp with time zone"); - - b.Property("OrganizationCode") - .HasColumnType("integer"); - - b.Property("PartyId") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.HasIndex("PartyId") - .IsUnique(); - - b.ToTable("PartyOrgainizationDetail"); - }); - modelBuilder.Entity("Pidp.Models.PrpAuthorizedLicence", b => { b.Property("Id") @@ -1314,21 +1126,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("PrpAuthorizedLicence"); }); - modelBuilder.Entity("Pidp.Models.FacilityAddress", b => - { - b.HasBaseType("Pidp.Models.Address"); - - b.Property("FacilityId") - .HasColumnType("integer"); - - b.HasIndex("FacilityId") - .IsUnique(); - - b.ToTable("Address"); - - b.HasDiscriminator().HasValue("FacilityAddress"); - }); - modelBuilder.Entity("Pidp.Models.HcimAccountTransfer", b => { b.HasBaseType("Pidp.Models.AccessRequest"); @@ -1340,25 +1137,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("HcimAccountTransfer"); }); - modelBuilder.Entity("Pidp.Models.HcimEnrolment", b => - { - b.HasBaseType("Pidp.Models.AccessRequest"); - - b.Property("ManagesTasks") - .HasColumnType("boolean"); - - b.Property("ModifiesPhns") - .HasColumnType("boolean"); - - b.Property("RecordsNewborns") - .HasColumnType("boolean"); - - b.Property("SearchesIdentifiers") - .HasColumnType("boolean"); - - b.ToTable("HcimEnrolment"); - }); - modelBuilder.Entity("Pidp.Models.LicenceStatusRoleAssigned", b => { b.HasBaseType("Pidp.Models.BusinessEvent"); @@ -1523,17 +1301,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("RequestingParty"); }); - modelBuilder.Entity("Pidp.Models.Facility", b => - { - b.HasOne("Pidp.Models.Party", "Party") - .WithOne("Facility") - .HasForeignKey("Pidp.Models.Facility", "PartyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Party"); - }); - modelBuilder.Entity("Pidp.Models.MSTeamsClinic", b => { b.HasOne("Pidp.Models.Party", "PrivacyOfficer") @@ -1545,17 +1312,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("PrivacyOfficer"); }); - modelBuilder.Entity("Pidp.Models.PartyAccessAdministrator", b => - { - b.HasOne("Pidp.Models.Party", "Party") - .WithOne("AccessAdministrator") - .HasForeignKey("Pidp.Models.PartyAccessAdministrator", "PartyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Party"); - }); - modelBuilder.Entity("Pidp.Models.PartyLicenceDeclaration", b => { b.HasOne("Pidp.Models.Lookups.College", "College") @@ -1573,28 +1329,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("Party"); }); - modelBuilder.Entity("Pidp.Models.PartyOrgainizationDetail", b => - { - b.HasOne("Pidp.Models.Party", "Party") - .WithOne("OrgainizationDetail") - .HasForeignKey("Pidp.Models.PartyOrgainizationDetail", "PartyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Party"); - }); - - modelBuilder.Entity("Pidp.Models.FacilityAddress", b => - { - b.HasOne("Pidp.Models.Facility", "Facility") - .WithOne("PhysicalAddress") - .HasForeignKey("Pidp.Models.FacilityAddress", "FacilityId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Facility"); - }); - modelBuilder.Entity("Pidp.Models.HcimAccountTransfer", b => { b.HasOne("Pidp.Models.AccessRequest", null) @@ -1604,15 +1338,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired(); }); - modelBuilder.Entity("Pidp.Models.HcimEnrolment", b => - { - b.HasOne("Pidp.Models.AccessRequest", null) - .WithOne() - .HasForeignKey("Pidp.Models.HcimEnrolment", "Id") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - modelBuilder.Entity("Pidp.Models.LicenceStatusRoleAssigned", b => { b.HasOne("Pidp.Models.Party", "Party") @@ -1679,11 +1404,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("EndorsementRelationships"); }); - modelBuilder.Entity("Pidp.Models.Facility", b => - { - b.Navigation("PhysicalAddress"); - }); - modelBuilder.Entity("Pidp.Models.MSTeamsClinic", b => { b.Navigation("Address") @@ -1692,17 +1412,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Pidp.Models.Party", b => { - b.Navigation("AccessAdministrator"); - b.Navigation("AccessRequests"); b.Navigation("Credentials"); - b.Navigation("Facility"); - b.Navigation("LicenceDeclaration"); - - b.Navigation("OrgainizationDetail"); }); #pragma warning restore 612, 618 } diff --git a/backend/webapi/Data/PidpDbContext.cs b/backend/webapi/Data/PidpDbContext.cs index 16b9f26ce..9b4180a04 100644 --- a/backend/webapi/Data/PidpDbContext.cs +++ b/backend/webapi/Data/PidpDbContext.cs @@ -30,15 +30,11 @@ public PidpDbContext( public DbSet EndorsementRelationships { get; set; } = default!; public DbSet EndorsementRequests { get; set; } = default!; public DbSet Endorsements { get; set; } = default!; - public DbSet Facilities { get; set; } = default!; public DbSet HcimAccountTransfers { get; set; } = default!; - public DbSet HcimEnrolments { get; set; } = default!; public DbSet MSTeamsClinics { get; set; } = default!; public DbSet MSTeamsClinicMemberEnrolments { get; set; } = default!; public DbSet PartyLicenceDeclarations { get; set; } = default!; public DbSet Parties { get; set; } = default!; - public DbSet PartyAccessAdministrators { get; set; } = default!; - public DbSet PartyOrgainizationDetails { get; set; } = default!; public DbSet PrpAuthorizedLicences { get; set; } = default!; /// diff --git a/backend/webapi/Features/AccessRequests/AccessRequestsController.cs b/backend/webapi/Features/AccessRequests/AccessRequestsController.cs index e6510a321..975b2f98b 100644 --- a/backend/webapi/Features/AccessRequests/AccessRequestsController.cs +++ b/backend/webapi/Features/AccessRequests/AccessRequestsController.cs @@ -83,15 +83,6 @@ public async Task CreateHcimAccountTransfer([FromServices] IComma } } - [HttpPost("hcim-enrolment")] - [Authorize(Policy = Policies.AnyPartyIdentityProvider)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task CreateHcimEnrolment([FromServices] ICommandHandler handler, - [FromHybrid] HcimEnrolment.Command command) - => await this.AuthorizePartyBeforeHandleAsync(command.PartyId, handler, command) - .ToActionResult(); - [HttpPost("immsbc-eforms")] [Authorize(Policy = Policies.HighAssuranceIdentityProvider)] [ProducesResponseType(StatusCodes.Status204NoContent)] diff --git a/backend/webapi/Features/AccessRequests/HcimAccountTransfer.cs b/backend/webapi/Features/AccessRequests/HcimAccountTransfer.cs index 1dfea24ba..4bd10c873 100644 --- a/backend/webapi/Features/AccessRequests/HcimAccountTransfer.cs +++ b/backend/webapi/Features/AccessRequests/HcimAccountTransfer.cs @@ -83,8 +83,7 @@ public async Task> HandleAsync(Command command) .Where(party => party.Id == command.PartyId) .Select(party => new { - AlreadyEnroled = party.AccessRequests.Any(request => request.AccessTypeCode == AccessTypeCode.HcimAccountTransfer - || request.AccessTypeCode == AccessTypeCode.HcimEnrolment), + AlreadyEnroled = party.AccessRequests.Any(request => request.AccessTypeCode == AccessTypeCode.HcimAccountTransfer), DemographicsComplete = party.Email != null && party.Phone != null, UserId = party.PrimaryUserId, party.Email diff --git a/backend/webapi/Features/AccessRequests/HcimEnrolment.cs b/backend/webapi/Features/AccessRequests/HcimEnrolment.cs deleted file mode 100644 index 2136da25d..000000000 --- a/backend/webapi/Features/AccessRequests/HcimEnrolment.cs +++ /dev/null @@ -1,121 +0,0 @@ -namespace Pidp.Features.AccessRequests; - -using DomainResults.Common; -using FluentValidation; -using HybridModelBinding; -using Microsoft.EntityFrameworkCore; -using NodaTime; -using System.Text.Json.Serialization; - -using Pidp.Data; -// using Pidp.Infrastructure.Auth; -// using Pidp.Infrastructure.HttpClients.Keycloak; -using Pidp.Infrastructure.HttpClients.Mail; -using Pidp.Infrastructure.Services; -using Pidp.Models.Lookups; - -public class HcimEnrolment -{ - public class Command : ICommand - { - [JsonIgnore] - [HybridBindProperty(Source.Route)] - public int PartyId { get; set; } - public bool ManagesTasks { get; set; } - public bool ModifiesPhns { get; set; } - public bool RecordsNewborns { get; set; } - public bool SearchesIdentifiers { get; set; } - } - - public class CommandValidator : AbstractValidator - { - public CommandValidator() => this.RuleFor(x => x.PartyId).GreaterThan(0); - } - - public class CommandHandler : ICommandHandler - { - private readonly IClock clock; - private readonly IEmailService emailService; - // private readonly IKeycloakAdministrationClient keycloakClient; - private readonly ILogger logger; - private readonly PidpDbContext context; - - public CommandHandler( - IClock clock, - IEmailService emailService, - // IKeycloakAdministrationClient keycloakClient, - ILogger logger, - PidpDbContext context) - { - this.clock = clock; - this.emailService = emailService; - // this.keycloakClient = keycloakClient; - this.logger = logger; - this.context = context; - } - - public async Task HandleAsync(Command command) - { - var dto = await this.context.Parties - .Where(party => party.Id == command.PartyId) - .Select(party => new - { - AlreadyEnroled = party.AccessRequests.Any(request => request.AccessTypeCode == AccessTypeCode.HcimAccountTransfer - || request.AccessTypeCode == AccessTypeCode.HcimEnrolment), - DemographicsComplete = party.Email != null && party.Phone != null, - AdminEmail = party.AccessAdministrator!.Email, - }) - .SingleAsync(); - - if (dto.AlreadyEnroled - || !dto.DemographicsComplete - || dto.AdminEmail == null) - { - this.logger.LogHcimEnrolmentAccessRequestDenied(); - return DomainResult.Failed(); - } - - // TODO assign role? - // if (!await this.keycloakClient.AssignClientRole(dto.UserId, ?, ?)) - // { - // return DomainResult.Failed(); - // } - - this.context.HcimEnrolments.Add(new Models.HcimEnrolment - { - PartyId = command.PartyId, - AccessTypeCode = AccessTypeCode.HcimEnrolment, - RequestedOn = this.clock.GetCurrentInstant(), - ManagesTasks = command.ManagesTasks, - ModifiesPhns = command.ModifiesPhns, - RecordsNewborns = command.RecordsNewborns, - SearchesIdentifiers = command.SearchesIdentifiers, - }); - - await this.context.SaveChangesAsync(); - - await this.SendConfirmationEmailAsync(dto.AdminEmail); - - return DomainResult.Success(); - } - - private async Task SendConfirmationEmailAsync(string adminEmail) - { - // TODO email text - // var link = $"link"; - var email = new Email( - from: EmailService.PidpEmail, - to: adminEmail, - subject: "HCIMWeb Enrolment Confirmation", - body: $"Placeholder Email." - ); - await this.emailService.SendAsync(email); - } - } -} - -public static partial class HcimEnrolmentLoggingExtensions -{ - [LoggerMessage(1, LogLevel.Warning, "HCIM Enrolment Access Request denied due to the Party Record not meeting all prerequisites.")] - public static partial void LogHcimEnrolmentAccessRequestDenied(this ILogger logger); -} diff --git a/backend/webapi/Features/Lookups/Index.cs b/backend/webapi/Features/Lookups/Index.cs index 66a5c44d4..63c523a7e 100644 --- a/backend/webapi/Features/Lookups/Index.cs +++ b/backend/webapi/Features/Lookups/Index.cs @@ -15,8 +15,6 @@ public class Model public List Colleges { get; set; } = new(); public List Countries { get; set; } = new(); public List Provinces { get; set; } = new(); - public List Organizations { get; set; } = new(); - public List HealthAuthorities { get; set; } = new(); } public class QueryHandler : IQueryHandler @@ -36,10 +34,6 @@ public async Task HandleAsync(Query query) Countries = await this.context.Set() .ToListAsync(), Provinces = await this.context.Set() - .ToListAsync(), - Organizations = await this.context.Set() - .ToListAsync(), - HealthAuthorities = await this.context.Set() .ToListAsync() }; } diff --git a/backend/webapi/Features/Parties/AccessAdministrator.cs b/backend/webapi/Features/Parties/AccessAdministrator.cs deleted file mode 100644 index 6dee4207b..000000000 --- a/backend/webapi/Features/Parties/AccessAdministrator.cs +++ /dev/null @@ -1,89 +0,0 @@ -namespace Pidp.Features.Parties; - -using AutoMapper; -using AutoMapper.QueryableExtensions; -using FluentValidation; -using HybridModelBinding; -using Microsoft.EntityFrameworkCore; -using System.Text.Json.Serialization; - -using Pidp.Data; - -public class AccessAdministrator -{ - public class Query : IQuery - { - public int PartyId { get; set; } - } - - public class Command : ICommand - { - [JsonIgnore] - [HybridBindProperty(Source.Route)] - public int PartyId { get; set; } - - public string Email { get; set; } = string.Empty; - } - - public class QueryValidator : AbstractValidator - { - public QueryValidator() => this.RuleFor(x => x.PartyId).GreaterThan(0); - } - - public class CommandValidator : AbstractValidator - { - public CommandValidator() - { - this.RuleFor(x => x.PartyId).GreaterThan(0); - this.RuleFor(x => x.Email).NotEmpty().EmailAddress(); // TODO Custom email validation? - } - } - - public class QueryHandler : IQueryHandler - { - private readonly IMapper mapper; - private readonly PidpDbContext context; - - public QueryHandler(IMapper mapper, PidpDbContext context) - { - this.mapper = mapper; - this.context = context; - } - - public async Task HandleAsync(Query query) - { - var admin = await this.context.PartyAccessAdministrators - .Where(admin => admin.PartyId == query.PartyId) - .ProjectTo(this.mapper.ConfigurationProvider) - .SingleOrDefaultAsync(); - - return admin ?? new Command { PartyId = query.PartyId }; - } - } - - public class CommandHandler : ICommandHandler - { - private readonly PidpDbContext context; - - public CommandHandler(PidpDbContext context) => this.context = context; - - public async Task HandleAsync(Command command) - { - var admin = await this.context.PartyAccessAdministrators - .SingleOrDefaultAsync(admin => admin.PartyId == command.PartyId); - - if (admin == null) - { - admin = new Models.PartyAccessAdministrator - { - PartyId = command.PartyId - }; - this.context.PartyAccessAdministrators.Add(admin); - } - - admin.Email = command.Email; - - await this.context.SaveChangesAsync(); - } - } -} diff --git a/backend/webapi/Features/Parties/MappingProfile.cs b/backend/webapi/Features/Parties/MappingProfile.cs index 9c05d9b15..ebba0a296 100644 --- a/backend/webapi/Features/Parties/MappingProfile.cs +++ b/backend/webapi/Features/Parties/MappingProfile.cs @@ -19,13 +19,8 @@ public MappingProfile() .ForMember(dest => dest.DemographicsComplete, opt => opt.MapFrom(src => src.Email != null && src.Phone != null)) .ForMember(dest => dest.HasBCProviderCredential, opt => opt.MapFrom(src => src.Credentials.Any(x => x.IdentityProvider == IdentityProviders.BCProvider))) .ForMember(dest => dest.LicenceDeclarationComplete, opt => opt.MapFrom(src => src.LicenceDeclaration != null)); - this.CreateProjection() - .ForMember(dest => dest.PhysicalAddress, opt => opt.MapFrom(src => src.Facility!.PhysicalAddress)); - this.CreateProjection(); - this.CreateProjection(); this.CreateProjection(); - this.CreateProjection(); this.CreateMap() .ForMember(dest => dest.IsGoodStanding, opt => opt.MapFrom(src => src.IsGoodStanding())) diff --git a/backend/webapi/Features/Parties/OrganizationDetails.cs b/backend/webapi/Features/Parties/OrganizationDetails.cs deleted file mode 100644 index 194464930..000000000 --- a/backend/webapi/Features/Parties/OrganizationDetails.cs +++ /dev/null @@ -1,96 +0,0 @@ -namespace Pidp.Features.Parties; - -using AutoMapper; -using AutoMapper.QueryableExtensions; -using FluentValidation; -using HybridModelBinding; -using Microsoft.EntityFrameworkCore; -using System.Text.Json.Serialization; - -using Pidp.Data; -using Pidp.Models.Lookups; - -public class OrganizationDetails -{ - public class Query : IQuery - { - public int PartyId { get; set; } - } - - public class Command : ICommand - { - [JsonIgnore] - [HybridBindProperty(Source.Route)] - public int PartyId { get; set; } - - public OrganizationCode OrganizationCode { get; set; } - public HealthAuthorityCode HealthAuthorityCode { get; set; } - public string EmployeeIdentifier { get; set; } = string.Empty; - } - - public class QueryValidator : AbstractValidator - { - public QueryValidator() => this.RuleFor(x => x.PartyId).GreaterThan(0); - } - - public class CommandValidator : AbstractValidator - { - public CommandValidator() - { - this.RuleFor(x => x.PartyId).GreaterThan(0); - this.RuleFor(x => x.OrganizationCode).IsInEnum(); - this.RuleFor(x => x.HealthAuthorityCode).IsInEnum(); - this.RuleFor(x => x.EmployeeIdentifier).NotEmpty(); - } - } - - public class QueryHandler : IQueryHandler - { - private readonly IMapper mapper; - private readonly PidpDbContext context; - - public QueryHandler(IMapper mapper, PidpDbContext context) - { - this.mapper = mapper; - this.context = context; - } - - public async Task HandleAsync(Query query) - { - var orgDetails = await this.context.PartyOrgainizationDetails - .Where(detail => detail.PartyId == query.PartyId) - .ProjectTo(this.mapper.ConfigurationProvider) - .SingleOrDefaultAsync(); - - return orgDetails ?? new Command { PartyId = query.PartyId }; - } - } - - public class CommandHandler : ICommandHandler - { - private readonly PidpDbContext context; - - public CommandHandler(PidpDbContext context) => this.context = context; - - public async Task HandleAsync(Command command) - { - var org = await this.context.PartyOrgainizationDetails - .SingleOrDefaultAsync(detail => detail.PartyId == command.PartyId); - - if (org == null) - { - org = new Models.PartyOrgainizationDetail - { - PartyId = command.PartyId - }; - this.context.PartyOrgainizationDetails.Add(org); - } - - org.OrganizationCode = command.OrganizationCode; - org.HealthAuthorityCode = command.HealthAuthorityCode; - org.EmployeeIdentifier = command.EmployeeIdentifier; - - await this.context.SaveChangesAsync(); - } - } -} diff --git a/backend/webapi/Features/Parties/PartiesController.cs b/backend/webapi/Features/Parties/PartiesController.cs index 6d750e81c..653d69afa 100644 --- a/backend/webapi/Features/Parties/PartiesController.cs +++ b/backend/webapi/Features/Parties/PartiesController.cs @@ -22,24 +22,6 @@ public async Task> CreateParty([FromServices] ICommandHandler< [FromBody] Create.Command command) => await handler.HandleAsync(command); - [HttpGet("{partyId}/access-administrator")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task> GetAccessAdministrator([FromServices] IQueryHandler handler, - [FromRoute] AccessAdministrator.Query query) - => await this.AuthorizePartyBeforeHandleAsync(query.PartyId, handler, query) - .ToActionResultOfT(); - - [HttpPut("{partyId}/access-administrator")] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task UpdateAccessAdministrator([FromServices] ICommandHandler handler, - [FromHybrid] AccessAdministrator.Command command) - => await this.AuthorizePartyBeforeHandleAsync(command.PartyId, handler, command) - .ToActionResult(); - [HttpGet("{partyId}/college-certifications")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] @@ -85,24 +67,6 @@ public async Task UpdatePartyDemographics([FromServices] ICommand => await this.AuthorizePartyBeforeHandleAsync(command.PartyId, handler, command) .ToActionResultOfT(); - [HttpGet("{partyId}/organization-details")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task> GetOrganizationDetails([FromServices] IQueryHandler handler, - [FromRoute] OrganizationDetails.Query query) - => await this.AuthorizePartyBeforeHandleAsync(query.PartyId, handler, query) - .ToActionResultOfT(); - - [HttpPut("{partyId}/organization-details")] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task UpdateOrganizationDetails([FromServices] ICommandHandler handler, - [FromHybrid] OrganizationDetails.Command command) - => await this.AuthorizePartyBeforeHandleAsync(command.PartyId, handler, command) - .ToActionResult(); - [HttpGet("{id}/profile-status")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] @@ -111,22 +75,4 @@ public async Task UpdateOrganizationDetails([FromServices] IComma [FromRoute] ProfileStatus.Query query) => await this.AuthorizePartyBeforeHandleAsync(query.Id, handler, query.WithUser(this.User)) .ToActionResultOfT(); - - [HttpGet("{id}/work-setting")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task> GetPartyWorkSetting([FromServices] IQueryHandler handler, - [FromRoute] WorkSetting.Query query) - => await this.AuthorizePartyBeforeHandleAsync(query.Id, handler, query) - .ToActionResultOfT(); - - [HttpPut("{id}/work-setting")] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task UpdatePartyWorkSetting([FromServices] ICommandHandler handler, - [FromHybrid] WorkSetting.Command command) - => await this.AuthorizePartyBeforeHandleAsync(command.Id, handler, command) - .ToActionResult(); } diff --git a/backend/webapi/Features/Parties/ProfileStatus.Model.cs b/backend/webapi/Features/Parties/ProfileStatus.Model.cs index edab0e77e..7932ac511 100644 --- a/backend/webapi/Features/Parties/ProfileStatus.Model.cs +++ b/backend/webapi/Features/Parties/ProfileStatus.Model.cs @@ -201,20 +201,9 @@ public class HcimAccountTransferSection : ProfileSection protected override StatusCode Compute(ProfileData profile) { - // TODO revert - // if (profile.CompletedEnrolments.Contains(AccessTypeCode.HcimAccountTransfer) - // || profile.CompletedEnrolments.Contains(AccessTypeCode.HcimEnrolment)) - // { - // this.StatusCode = StatusCode.Hidden; - // return; - // } - - return profile switch - { - _ when profile.HasEnrolment(AccessTypeCode.HcimAccountTransfer) => StatusCode.Complete, - _ when profile.HasEnrolment(AccessTypeCode.HcimEnrolment) => StatusCode.Hidden, - _ => StatusCode.Incomplete - }; + return profile.HasEnrolment(AccessTypeCode.HcimAccountTransfer) + ? StatusCode.Complete + : StatusCode.Incomplete; } } diff --git a/backend/webapi/Features/Parties/WorkSetting.cs b/backend/webapi/Features/Parties/WorkSetting.cs deleted file mode 100644 index e2fa70af0..000000000 --- a/backend/webapi/Features/Parties/WorkSetting.cs +++ /dev/null @@ -1,127 +0,0 @@ -namespace Pidp.Features.Parties; - -using AutoMapper; -using AutoMapper.QueryableExtensions; -using FluentValidation; -using HybridModelBinding; -using Microsoft.EntityFrameworkCore; -using System.Text.Json.Serialization; - -using Pidp.Data; -using Pidp.Features; -using Pidp.Models; - -public class WorkSetting -{ - public class Query : IQuery - { - public int Id { get; set; } - } - - public class Command : ICommand - { - [JsonIgnore] - [HybridBindProperty(Source.Route)] - public int Id { get; set; } - public string JobTitle { get; set; } = string.Empty; - public string FacilityName { get; set; } = string.Empty; - - public Address? PhysicalAddress { get; set; } - - public class Address - { - public string CountryCode { get; set; } = string.Empty; - public string ProvinceCode { get; set; } = string.Empty; - public string Street { get; set; } = string.Empty; - public string City { get; set; } = string.Empty; - public string Postal { get; set; } = string.Empty; - } - } - - public class QueryValidator : AbstractValidator - { - public QueryValidator() => this.RuleFor(x => x.Id).GreaterThan(0); - } - - public class CommandValidator : AbstractValidator - { - public CommandValidator() - { - this.RuleFor(x => x.Id).GreaterThan(0); - this.RuleFor(x => x.PhysicalAddress).SetValidator(new AddressValidator()!); - } - } - - public class AddressValidator : AbstractValidator - { - public AddressValidator() - { - this.RuleFor(x => x.CountryCode).NotEmpty(); - this.RuleFor(x => x.ProvinceCode).NotEmpty(); - this.RuleFor(x => x.Street).NotEmpty(); - this.RuleFor(x => x.City).NotEmpty(); - this.RuleFor(x => x.Postal).NotEmpty(); - } - } - - public class QueryHandler : IQueryHandler - { - private readonly IMapper mapper; - private readonly PidpDbContext context; - - public QueryHandler(IMapper mapper, PidpDbContext context) - { - this.mapper = mapper; - this.context = context; - } - - public async Task HandleAsync(Query query) - { - return await this.context.Parties - .Where(party => party.Id == query.Id) - .ProjectTo(this.mapper.ConfigurationProvider) - .SingleAsync(); - } - } - - public class CommandHandler : ICommandHandler - { - private readonly PidpDbContext context; - - public CommandHandler(PidpDbContext context) => this.context = context; - - public async Task HandleAsync(Command command) - { - var party = await this.context.Parties - .Include(party => party.Facility) - .SingleAsync(party => party.Id == command.Id); - - party.JobTitle = command.JobTitle; - - if (party.Facility == null) - { - party.Facility = new Facility(); - } - - party.Facility.Name = command.FacilityName; - - if (command.PhysicalAddress == null) - { - party.Facility.PhysicalAddress = null; - } - else - { - party.Facility.PhysicalAddress = new FacilityAddress - { - CountryCode = command.PhysicalAddress.CountryCode, - ProvinceCode = command.PhysicalAddress.ProvinceCode, - Street = command.PhysicalAddress.Street, - City = command.PhysicalAddress.City, - Postal = command.PhysicalAddress.Postal - }; - } - - await this.context.SaveChangesAsync(); - } - } -} diff --git a/backend/webapi/Infrastructure/Services/EmailService.cs b/backend/webapi/Infrastructure/Services/EmailService.cs index 8e974d9a8..569d4d1c7 100644 --- a/backend/webapi/Infrastructure/Services/EmailService.cs +++ b/backend/webapi/Infrastructure/Services/EmailService.cs @@ -12,7 +12,7 @@ namespace Pidp.Infrastructure.Services; public class EmailService : IEmailService { public const string PidpEmail = "OneHealthID@gov.bc.ca"; - public const string PidpSupportPhone = "250-857-1969"; + public const string PidpSupportPhone = "250-448-1262"; private readonly IChesClient chesClient; private readonly IClock clock; diff --git a/backend/webapi/Models/AccessRequest.cs b/backend/webapi/Models/AccessRequest.cs index afd1edf67..a74adfa23 100644 --- a/backend/webapi/Models/AccessRequest.cs +++ b/backend/webapi/Models/AccessRequest.cs @@ -27,15 +27,6 @@ public class HcimAccountTransfer : AccessRequest public string LdapUsername { get; set; } = string.Empty; } -[Table(nameof(HcimEnrolment))] -public class HcimEnrolment : AccessRequest -{ - public bool ManagesTasks { get; set; } - public bool ModifiesPhns { get; set; } - public bool RecordsNewborns { get; set; } - public bool SearchesIdentifiers { get; set; } -} - [Table(nameof(MSTeamsClinicMemberEnrolment))] public class MSTeamsClinicMemberEnrolment : AccessRequest { diff --git a/backend/webapi/Models/Address.cs b/backend/webapi/Models/Address.cs index ed6259b5f..c6b897d0d 100644 --- a/backend/webapi/Models/Address.cs +++ b/backend/webapi/Models/Address.cs @@ -26,13 +26,6 @@ public abstract class Address : BaseAuditable public string Postal { get; set; } = string.Empty; } -public class FacilityAddress : Address -{ - public int FacilityId { get; set; } - - public Facility? Facility { get; set; } -} - public class MSTeamsClinicAddress : Address { public int ClinicId { get; set; } diff --git a/backend/webapi/Models/Facility.cs b/backend/webapi/Models/Facility.cs deleted file mode 100644 index 41a7c208b..000000000 --- a/backend/webapi/Models/Facility.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Pidp.Models; - -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; - -[Table(nameof(Facility))] -public class Facility : BaseAuditable -{ - [Key] - public int Id { get; set; } - - public int PartyId { get; set; } - - public Party? Party { get; set; } - - public string Name { get; set; } = string.Empty; - - public FacilityAddress? PhysicalAddress { get; set; } -} diff --git a/backend/webapi/Models/Lookups/AccessType.cs b/backend/webapi/Models/Lookups/AccessType.cs index 49939e63f..9e70ebe60 100644 --- a/backend/webapi/Models/Lookups/AccessType.cs +++ b/backend/webapi/Models/Lookups/AccessType.cs @@ -7,7 +7,7 @@ public enum AccessTypeCode { SAEforms = 1, HcimAccountTransfer, - HcimEnrolment, + HcimEnrolment, // Currently Unused DriverFitness, MSTeamsPrivacyOfficer, PrescriptionRefillEforms, diff --git a/backend/webapi/Models/Lookups/HealthAuthority.cs b/backend/webapi/Models/Lookups/HealthAuthority.cs deleted file mode 100644 index b5b3b7676..000000000 --- a/backend/webapi/Models/Lookups/HealthAuthority.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace Pidp.Models.Lookups; - -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; - -public enum HealthAuthorityCode -{ - ProvincialHealthServicesAuthority = 1, - VancouverIslandHealthAuthority, - VancouverCoastalHealthAuthority, - FraserHealthAuthority, - InteriorHealthAuthority, - NorthernHealthAuthority, - FirstNationsHealthAuthority -} - -[Table("HealthAuthorityLookup")] -public class HealthAuthority -{ - [Key] - public HealthAuthorityCode Code { get; set; } - - public string Name { get; set; } = string.Empty; -} - -public class HealthAuthorityDataGenerator : ILookupDataGenerator -{ - public IEnumerable Generate() => new[] - { - - new HealthAuthority { Code = HealthAuthorityCode.ProvincialHealthServicesAuthority, Name = "Provincial Health Services Authority" }, - new HealthAuthority { Code = HealthAuthorityCode.VancouverIslandHealthAuthority, Name = "Vancouver Island Health Authority" }, - new HealthAuthority { Code = HealthAuthorityCode.VancouverCoastalHealthAuthority, Name = "Vancouver Coastal Health Authority" }, - new HealthAuthority { Code = HealthAuthorityCode.FraserHealthAuthority, Name = "Fraser Health Authority" }, - new HealthAuthority { Code = HealthAuthorityCode.InteriorHealthAuthority, Name = "Interior Health Authority" }, - new HealthAuthority { Code = HealthAuthorityCode.NorthernHealthAuthority, Name = "Northern Health Authority" }, - new HealthAuthority { Code = HealthAuthorityCode.FirstNationsHealthAuthority, Name = "First Nations Health Authority" } - }; -} diff --git a/backend/webapi/Models/Lookups/Organization.cs b/backend/webapi/Models/Lookups/Organization.cs deleted file mode 100644 index f23794bfd..000000000 --- a/backend/webapi/Models/Lookups/Organization.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Pidp.Models.Lookups; - -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; - -public enum OrganizationCode -{ - HealthAuthority = 1, - BcGovernmentMinistry, - Maximus, - ICBC, - Other -} - -[Table("OrganizationLookup")] -public class Organization -{ - [Key] - public OrganizationCode Code { get; set; } - - public string Name { get; set; } = string.Empty; -} - -public class OrganizationDataGenerator : ILookupDataGenerator -{ - public IEnumerable Generate() => new[] - { - new Organization { Code = OrganizationCode.HealthAuthority, Name = "Health Authority" }, - new Organization { Code = OrganizationCode.BcGovernmentMinistry, Name = "BC Government Ministry" }, - new Organization { Code = OrganizationCode.Maximus, Name = "Maximus" }, - new Organization { Code = OrganizationCode.ICBC, Name = "ICBC" }, - new Organization { Code = OrganizationCode.Other, Name = "Other" } - }; -} diff --git a/backend/webapi/Models/Party.cs b/backend/webapi/Models/Party.cs index 80e593a04..5d07bbc53 100644 --- a/backend/webapi/Models/Party.cs +++ b/backend/webapi/Models/Party.cs @@ -40,18 +40,10 @@ public class Party : BaseAuditable public string? Phone { get; set; } - public PartyAccessAdministrator? AccessAdministrator { get; set; } - public string? Cpn { get; set; } public PartyLicenceDeclaration? LicenceDeclaration { get; set; } - public string? JobTitle { get; set; } - - public Facility? Facility { get; set; } - - public PartyOrgainizationDetail? OrgainizationDetail { get; set; } - public ICollection AccessRequests { get; set; } = new List(); public ICollection Credentials { get; set; } = new List(); diff --git a/backend/webapi/Models/PartyAccessAdministrator.cs b/backend/webapi/Models/PartyAccessAdministrator.cs deleted file mode 100644 index 9f6d871a7..000000000 --- a/backend/webapi/Models/PartyAccessAdministrator.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Pidp.Models; - -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; - -[Table(nameof(PartyAccessAdministrator))] -public class PartyAccessAdministrator : BaseAuditable -{ - [Key] - public int Id { get; set; } - - public int PartyId { get; set; } - - public Party? Party { get; set; } - - public string Email { get; set; } = string.Empty; -} diff --git a/backend/webapi/Models/PartyOrganizationDetail.cs b/backend/webapi/Models/PartyOrganizationDetail.cs deleted file mode 100644 index 4fb462580..000000000 --- a/backend/webapi/Models/PartyOrganizationDetail.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Pidp.Models; - -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; - -using Pidp.Models.Lookups; - -[Table(nameof(PartyOrgainizationDetail))] -public class PartyOrgainizationDetail : BaseAuditable -{ - [Key] - public int Id { get; set; } - - public int PartyId { get; set; } - - public Party? Party { get; set; } - - public OrganizationCode OrganizationCode { get; set; } - - public HealthAuthorityCode HealthAuthorityCode { get; set; } - - public string EmployeeIdentifier { get; set; } = string.Empty; -} diff --git a/workspace/apps/pidp/src/app/features/access/access-routing.routes.ts b/workspace/apps/pidp/src/app/features/access/access-routing.routes.ts index 9cc5238c3..5951e4f19 100644 --- a/workspace/apps/pidp/src/app/features/access/access-routing.routes.ts +++ b/workspace/apps/pidp/src/app/features/access/access-routing.routes.ts @@ -41,39 +41,6 @@ export const routes: Routes = [ './pages/hcim-account-transfer/hcim-account-transfer-routing.routes' ).then((m) => m.routes), }, - { - path: AccessRoutes.HCIM_ENROLMENT, - canActivate: [PermissionsGuard.canActivate], - data: { - roles: [Role.FEATURE_PIDP_DEMO], - }, - loadChildren: (): Promise => - import('./pages/hcim-enrolment/hcim-enrolment-routing.routes').then( - (m) => m.routes, - ), - }, - { - path: AccessRoutes.PHARMANET, - canActivate: [PermissionsGuard.canActivate], - data: { - roles: [Role.FEATURE_PIDP_DEMO], - }, - loadChildren: (): Promise => - import('./pages/pharmanet/pharmanet-routing.routes').then( - (m) => m.routes, - ), - }, - { - path: AccessRoutes.SITE_PRIVACY_SECURITY_CHECKLIST, - canActivate: [PermissionsGuard.canActivate], - data: { - roles: [Role.FEATURE_PIDP_DEMO], - }, - loadChildren: (): Promise => - import( - './pages/site-privacy-security-checklist/site-privacy-security-checklist-routing.routes' - ).then((m) => m.routes), - }, { path: AccessRoutes.DRIVER_FITNESS, loadChildren: (): Promise => diff --git a/workspace/apps/pidp/src/app/features/access/access.routes.ts b/workspace/apps/pidp/src/app/features/access/access.routes.ts index 37967d918..a1000ef86 100644 --- a/workspace/apps/pidp/src/app/features/access/access.routes.ts +++ b/workspace/apps/pidp/src/app/features/access/access.routes.ts @@ -5,14 +5,11 @@ export class AccessRoutes { public static BC_PROVIDER_EDIT = 'bc-provider-edit'; public static DRIVER_FITNESS = 'driver-fitness'; public static HCIM_ACCOUNT_TRANSFER = 'hcim-account-transfer'; - public static HCIM_ENROLMENT = 'hcim-enrolment'; public static IMMSBC_EFORMS = 'immsbc-eforms'; public static MS_TEAMS_PRIVACY_OFFICER = 'ms-teams-privacy-officer'; public static MS_TEAMS_CLINIC_MEMBER = 'ms-teams-clinic-member'; - public static PHARMANET = 'pharmanet'; public static PRESCRIPTION_REFILL_EFORMS = 'prescription-refill-eforms'; public static PROVIDER_REPORTING_PORTAL = 'provider-reporting-portal'; - public static SITE_PRIVACY_SECURITY_CHECKLIST = `site-privacy-and-security-checklist`; public static SPECIAL_AUTH_EFORMS = 'sa-eforms'; public static EDRD_EFORMS = 'edrd-eforms'; diff --git a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-constants.ts b/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-constants.ts deleted file mode 100644 index 0f26b7982..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-constants.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const hcimWebUrl = 'https://hcimweb-cl.hlth.gov.bc.ca'; -export const hcimWebEnrolmentSupport = 'hlth.registriesconnections@gov.bc.ca'; - -// TODO remove unused values copied from HCIMWeb Account Transfer when more info provided -export const healthNetBcPasswordResetUrl = `https://healthnetbc.hlth.gov.bc.ca/?resetPassword`; -export const healthNetBcHelpDeskEmail = 'HLTH.HELPDESK@gov.bc.ca'; -export const healthNetBcHelpDeskPhone = '2509521234'; -export const healthNetBcAdminEmail = 'hlth.registriesadmin@gov.bc.ca'; -export const healthNetBcAdminPhone = '2509529137'; diff --git a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-form-state.ts b/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-form-state.ts deleted file mode 100644 index ca1b8c1ce..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-form-state.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { FormBuilder } from '@angular/forms'; - -import { AbstractFormState, FormControlValidators } from '@bcgov/shared/ui'; - -import { HcimEnrolment } from './hcim-enrolment.model'; - -export class HcimEnrolmentFormState extends AbstractFormState { - public constructor(private fb: FormBuilder) { - super(); - - this.buildForm(); - } - - public get json(): HcimEnrolment | undefined { - if (!this.formInstance) { - return; - } - - return this.formInstance.getRawValue(); - } - - public patchValue(): void { - // Form will never be patched! - throw new Error('Method Not Implemented'); - } - - public buildForm(): void { - this.formInstance = this.fb.group({ - managesTasks: [null, [FormControlValidators.requiredBoolean]], - modifiesPhns: [null, [FormControlValidators.requiredBoolean]], - recordsNewborns: [null, [FormControlValidators.requiredBoolean]], - searchesIdentifiers: [null, [FormControlValidators.requiredBoolean]], - }); - } -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-resource.service.spec.ts b/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-resource.service.spec.ts deleted file mode 100644 index 379cfaa85..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-resource.service.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { TestBed } from '@angular/core/testing'; - -import { APP_CONFIG, APP_DI_CONFIG } from '@app/app.config'; - -import { HcimEnrolmentResource } from './hcim-enrolment-resource.service'; - -describe('HcimEnrolmentResource', () => { - let service: HcimEnrolmentResource; - - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [HttpClientTestingModule], - providers: [ - HcimEnrolmentResource, - { - provide: APP_CONFIG, - useValue: APP_DI_CONFIG, - }, - ], - }); - - service = TestBed.inject(HcimEnrolmentResource); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-resource.service.ts b/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-resource.service.ts deleted file mode 100644 index 55a54f477..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-resource.service.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Injectable } from '@angular/core'; - -import { Observable, catchError, map, of } from 'rxjs'; - -import { NoContent } from '@bcgov/shared/data-access'; - -import { ApiHttpClient } from '@app/core/resources/api-http-client.service'; -import { ProfileStatus } from '@app/features/portal/models/profile-status.model'; -import { PortalResource } from '@app/features/portal/portal-resource.service'; - -import { HcimEnrolment } from './hcim-enrolment.model'; - -export enum HcimEnrolmentStatusCode { - ACCESS_GRANTED, - ACCESS_FAILED, -} - -export interface HcimEnrolmentResponse { - statusCode: HcimEnrolmentStatusCode; -} - -@Injectable({ - providedIn: 'root', -}) -export class HcimEnrolmentResource { - public constructor( - protected apiResource: ApiHttpClient, - private portalResource: PortalResource, - ) {} - - public getProfileStatus(partyId: number): Observable { - return this.portalResource.getProfileStatus(partyId); - } - - public requestAccess( - partyId: number, - hcimEnrolment: HcimEnrolment, - ): Observable { - return this.apiResource - .post( - `parties/${partyId}/access-requests/hcim-enrolment`, - hcimEnrolment, - ) - .pipe( - map(() => ({ statusCode: HcimEnrolmentStatusCode.ACCESS_GRANTED })), - catchError(() => - of({ statusCode: HcimEnrolmentStatusCode.ACCESS_FAILED }), - ), - ); - } -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-routing.routes.ts b/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-routing.routes.ts deleted file mode 100644 index c372f8109..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment-routing.routes.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Routes } from '@angular/router'; - -import { HcimEnrolmentPage } from './hcim-enrolment.page'; -import { hcimEnrolmentResolver } from './hcim-enrolment.resolver'; - -export const routes: Routes = [ - { - path: '', - component: HcimEnrolmentPage, - resolve: { - hcimEnrolmentStatusCode: hcimEnrolmentResolver, - }, - data: { - title: 'OneHealthID Service', - routes: { - root: '../../', - }, - setDashboardTitleGuard: { - titleText: 'Welcome to OneHealthID Service', - titleDescriptionText: - 'Complete your profile to gain access to the systems you are eligible for', - }, - }, - }, -]; diff --git a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.model.ts b/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.model.ts deleted file mode 100644 index 393973a24..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.model.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface HcimEnrolment { - managesTasks: boolean; - modifiesPhns: boolean; - recordsNewborns: boolean; - searchesIdentifiers: boolean; -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.page.html b/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.page.html deleted file mode 100644 index e6faf38de..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.page.html +++ /dev/null @@ -1,104 +0,0 @@ - - {{ title }} - - - - - Next Steps. - - - - -

- Your submission has been sent to your Health Authority Access - Administrator for approval. -

-
-
-
-
- - - - -

- Your request for access to HCIMWeb Enrolment could not be processed at - this time. If this issue persists, contact - - or - - for assistance. -

-
-
- - - - - Provide the next information to complete your HCIMWeb enrolment. - - - - - -

- Each question must be answered in order to submit an HCIMWeb - Enrolment. -

-
-
- - -
    -
  1. - {{ control.question }}
    - - Yes - No - -
  2. -
-
-
-
- - - - - - -
diff --git a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.page.scss b/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.page.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.page.spec.ts b/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.page.spec.ts deleted file mode 100644 index 616753bf4..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.page.spec.ts +++ /dev/null @@ -1,188 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatDialogModule } from '@angular/material/dialog'; -import { ActivatedRoute, Router } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { randBoolean, randNumber, randTextRange } from '@ngneat/falso'; -import { Spy, createSpyFromClass, provideAutoSpy } from 'jest-auto-spies'; - -import { APP_CONFIG, APP_DI_CONFIG } from '@app/app.config'; -import { PartyService } from '@app/core/party/party.service'; -import { FormUtilsService } from '@app/core/services/form-utils.service'; -import { LoggerService } from '@app/core/services/logger.service'; - -import { - HcimEnrolmentResource, - HcimEnrolmentStatusCode, -} from './hcim-enrolment-resource.service'; -import { HcimEnrolment } from './hcim-enrolment.model'; -import { HcimEnrolmentPage } from './hcim-enrolment.page'; - -describe('HcimEnrolmentComponent', () => { - let component: HcimEnrolmentPage; - let partyServiceSpy: Spy; - let hcimEnrolmentResourceSpy: Spy; - let formUtilsServiceSpy: Spy; - let router: Router; - - let mockActivatedRoute: { snapshot: any }; - let mockForm: HcimEnrolment; - - beforeEach(() => { - mockActivatedRoute = { - snapshot: { - data: { - title: randTextRange({ min: 1, max: 4 }), - routes: { - root: '../../', - }, - }, - }, - }; - - TestBed.configureTestingModule({ - imports: [ - HttpClientTestingModule, - MatDialogModule, - ReactiveFormsModule, - RouterTestingModule, - ], - providers: [ - HcimEnrolmentPage, - { - provide: APP_CONFIG, - useValue: APP_DI_CONFIG, - }, - { - provide: ActivatedRoute, - useValue: mockActivatedRoute, - }, - { - provide: PartyService, - useValue: createSpyFromClass(PartyService, { - gettersToSpyOn: ['partyId'], - settersToSpyOn: ['partyId'], - }), - }, - provideAutoSpy(HcimEnrolmentResource), - provideAutoSpy(FormUtilsService), - provideAutoSpy(LoggerService), - provideAutoSpy(Router), - ], - }); - - router = TestBed.inject(Router); - component = TestBed.inject(HcimEnrolmentPage); - partyServiceSpy = TestBed.inject(PartyService); - hcimEnrolmentResourceSpy = TestBed.inject(HcimEnrolmentResource); - formUtilsServiceSpy = TestBed.inject(FormUtilsService); - - mockForm = { - managesTasks: randBoolean(), - modifiesPhns: randBoolean(), - recordsNewborns: randBoolean(), - searchesIdentifiers: randBoolean(), - }; - }); - - describe('INIT', () => { - given('partyId exists and access request completion is not null', () => { - const partyId = randNumber({ min: 1 }); - component.completed = false; - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - - when('resource request resolved', () => { - component.ngOnInit(); - - then('it should not route to root', () => { - expect(router.navigate).not.toHaveBeenCalled(); - }); - }); - }); - - given('partyId exists and access request completion is null', () => { - const partyId = randNumber({ min: 1 }); - component.completed = null; - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - - when('resource request resolved', () => { - component.ngOnInit(); - - then('it should route to root', () => { - const rootRoute = mockActivatedRoute.snapshot.data.routes.root; - expect(router.navigate).toHaveBeenCalledWith([rootRoute]); - }); - }); - }); - - given('partyId does not exists', () => { - const partyId = null; - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - - when('resource request resolved', () => { - component.ngOnInit(); - - then('it should route to root', () => { - const rootRoute = mockActivatedRoute.snapshot.data.routes.root; - expect(router.navigate).toHaveBeenCalledWith([rootRoute]); - }); - }); - }); - }); - - describe('METHOD: onSubmit', () => { - given('a form submission', () => { - const partyId = randNumber({ min: 1 }); - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - component.formState.form.patchValue(mockForm); - - when('no validation errors exist', () => { - formUtilsServiceSpy.checkValidity.mockReturnValue(true); - const response = { - statusCode: HcimEnrolmentStatusCode.ACCESS_GRANTED, - }; - hcimEnrolmentResourceSpy.requestAccess - .mustBeCalledWith(partyId, mockForm) - .nextWith(response); - component.onSubmit(); - - then('access request will be made', () => { - expect(component.completed).toBe(true); - expect(component.accessRequestStatusCode).toBe(response.statusCode); - }); - }); - }); - - given('a form submission', () => { - const partyId = randNumber({ min: 1 }); - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - component.formState.form.patchValue(mockForm); - - when('validation errors exist', () => { - formUtilsServiceSpy.checkValidity.mockReturnValue(false); - component.onSubmit(); - - then('access request will not be made', () => { - expect(component.completed).toBe(false); - expect(component.accessRequestStatusCode).toBeUndefined(); - }); - }); - }); - }); - - describe('METHOD: onBack', () => { - given('user wants to go back to the previous page', () => { - when('onBack is invoked', () => { - component.onBack(); - - then('router should navigate to root route', () => { - const rootRoute = mockActivatedRoute.snapshot.data.routes.root; - expect(router.navigate).toHaveBeenCalledWith([rootRoute]); - }); - }); - }); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.page.ts b/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.page.ts deleted file mode 100644 index d0206b19f..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.page.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { NgFor, NgIf } from '@angular/common'; -import { Component, OnInit } from '@angular/core'; -import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonModule } from '@angular/material/button'; -import { MatRadioModule } from '@angular/material/radio'; -import { ActivatedRoute, Router } from '@angular/router'; - -import { EMPTY, Observable } from 'rxjs'; - -import { - AlertComponent, - AlertContentDirective, - AnchorDirective, - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, -} from '@bcgov/shared/ui'; - -import { - AbstractFormDependenciesService, - AbstractFormPage, -} from '@app/core/classes/abstract-form-page.class'; -import { PartyService } from '@app/core/party/party.service'; -import { LoggerService } from '@app/core/services/logger.service'; -import { StatusCode } from '@app/features/portal/enums/status-code.enum'; - -import { - healthNetBcHelpDeskEmail, - healthNetBcHelpDeskPhone, -} from './hcim-enrolment-constants'; -import { HcimEnrolmentFormState } from './hcim-enrolment-form-state'; -import { - HcimEnrolmentResource, - HcimEnrolmentResponse, - HcimEnrolmentStatusCode, -} from './hcim-enrolment-resource.service'; -import { HcimEnrolment } from './hcim-enrolment.model'; - -@Component({ - selector: 'app-hcim-enrolment', - templateUrl: './hcim-enrolment.page.html', - styleUrls: ['./hcim-enrolment.page.scss'], - standalone: true, - imports: [ - AlertComponent, - AlertContentDirective, - AnchorDirective, - NgFor, - NgIf, - MatButtonModule, - MatRadioModule, - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, - ReactiveFormsModule, - ], -}) -export class HcimEnrolmentPage - extends AbstractFormPage - implements OnInit -{ - public title: string; - public formState: HcimEnrolmentFormState; - public completed: boolean | null; - public controls: { name: keyof HcimEnrolment; question: string }[]; - public accessRequestStatusCode?: HcimEnrolmentStatusCode; - public formInvalid?: boolean; - public readonly healthNetBcHelpDeskEmail: string; - public readonly healthNetBcHelpDeskPhone: string; - - public HcimEnrolmentStatusCode = HcimEnrolmentStatusCode; - - // ui-page is handling this. - public showOverlayOnSubmit = false; - - public constructor( - dependenciesService: AbstractFormDependenciesService, - private route: ActivatedRoute, - private router: Router, - private partyService: PartyService, - private resource: HcimEnrolmentResource, - private logger: LoggerService, - fb: FormBuilder, - ) { - super(dependenciesService); - - const routeData = this.route.snapshot.data; - this.title = routeData.title; - this.formState = new HcimEnrolmentFormState(fb); - this.completed = routeData.hcimEnrolmentStatusCode === StatusCode.COMPLETED; - this.controls = [ - { - name: 'managesTasks', - question: 'Do you manage tasks?', - }, - { - name: 'modifiesPhns', - question: 'Do you need to create or update new PHNs?', - }, - { - name: 'recordsNewborns', - question: 'Do you need to record newborns?', - }, - { - name: 'searchesIdentifiers', - question: 'Do you need to search by source identifiers?', - }, - ]; - this.healthNetBcHelpDeskEmail = healthNetBcHelpDeskEmail; - this.healthNetBcHelpDeskPhone = healthNetBcHelpDeskPhone; - } - - public onBack(): void { - this.navigateToRoot(); - } - - public ngOnInit(): void { - const partyId = this.partyService.partyId; - - if (!partyId) { - this.logger.error('No party ID was provided'); - return this.navigateToRoot(); - } - - if (this.completed === null) { - this.logger.error('No status code was provided'); - return this.navigateToRoot(); - } - } - - protected performSubmission(): Observable { - const partyId = this.partyService.partyId; - - return partyId && this.formState.json - ? this.resource.requestAccess(partyId, this.formState.json) - : EMPTY; - } - - protected onSubmitFormIsValid(): void { - this.formInvalid = false; - } - - protected onSubmitFormIsInvalid(): void { - this.formInvalid = true; - } - - protected afterSubmitIsSuccessful( - accessResponse: HcimEnrolmentResponse, - ): void { - const statusCode = accessResponse.statusCode; - this.completed = statusCode === HcimEnrolmentStatusCode.ACCESS_GRANTED; - this.accessRequestStatusCode = statusCode; - } - - private navigateToRoot(): void { - this.router.navigate([this.route.snapshot.data.routes.root]); - } -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.resolver.spec.ts b/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.resolver.spec.ts deleted file mode 100644 index abeed0154..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.resolver.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { ResolveFn } from '@angular/router'; - -import { StatusCode } from '@app/features/portal/enums/status-code.enum'; - -import { hcimEnrolmentResolver } from './hcim-enrolment.resolver'; - -describe('hcimEnrolmentResolver', () => { - const executeResolver: ResolveFn = ( - ...resolverParameters - ) => - TestBed.runInInjectionContext(() => - hcimEnrolmentResolver(...resolverParameters), - ); - - beforeEach(() => { - TestBed.configureTestingModule({}); - }); - - it('should be created', () => { - expect(executeResolver).toBeTruthy(); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.resolver.ts b/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.resolver.ts deleted file mode 100644 index 15bb4bca2..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/hcim-enrolment/hcim-enrolment.resolver.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { inject } from '@angular/core'; -import { ResolveFn } from '@angular/router'; - -import { catchError, map, of } from 'rxjs'; - -import { PartyService } from '@app/core/party/party.service'; -import { StatusCode } from '@app/features/portal/enums/status-code.enum'; -import { ProfileStatus } from '@app/features/portal/models/profile-status.model'; - -import { HcimEnrolmentResource } from './hcim-enrolment-resource.service'; - -export const hcimEnrolmentResolver: ResolveFn = () => { - const partyService = inject(PartyService); - const resource = inject(HcimEnrolmentResource); - - if (!partyService.partyId) { - return of(null); - } - - return resource.getProfileStatus(partyService.partyId).pipe( - map((profileStatus: ProfileStatus | null) => { - if (!profileStatus) { - return null; - } - - return profileStatus.status.hcimEnrolment.statusCode; - }), - catchError(() => of(null)), - ); -}; diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/next-steps/next-steps.page.html b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/next-steps/next-steps.page.html deleted file mode 100644 index 2490ae9c3..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/next-steps/next-steps.page.html +++ /dev/null @@ -1,97 +0,0 @@ - - {{ title }} - - - - Next Steps. - - - - - - Follow the next steps to access PharmaNet - - - - - - 1. Send your approval to your PharmaNet administrator - - -

- Who is my PharmaNet administrator? - - Lorem ipsum dolor sit, amet consectetur adipisicing elit. Non facilis - eius, nam ipsa repellendus minus repellat. - -

-

- Get your access to PharmaNet set up. Use the email option below to - notify your PharmaNet administrator of your completed enrolment. -

- Care setting here -

- Send your approval to your PharmaNet administrator (e.g., office - manager). If you work in more than one clinic you can include the email - addresses for all the PharmaNet administrators separated by a comma. -

-
- -
- -
- - - 2. Your PharmaNet administrator will let you know when your access is set - up - - - - - 3. Access your verified credential (optional) - - -
- -
-
- - - - - - -
diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/next-steps/next-steps.page.scss b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/next-steps/next-steps.page.scss deleted file mode 100644 index c005575af..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/next-steps/next-steps.page.scss +++ /dev/null @@ -1,3 +0,0 @@ -.row.email-form { - align-items: baseline; -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/next-steps/next-steps.page.spec.ts b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/next-steps/next-steps.page.spec.ts deleted file mode 100644 index 832aa4e0c..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/next-steps/next-steps.page.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { ActivatedRoute } from '@angular/router'; - -import { randTextRange } from '@ngneat/falso'; - -import { NextStepsPage } from './next-steps.page'; - -describe('NextStepsPage', () => { - let component: NextStepsPage; - - let mockActivatedRoute; - - beforeEach(() => { - mockActivatedRoute = { - snapshot: { - data: { - title: randTextRange({ min: 1, max: 4 }), - routes: { - root: '../../', - }, - }, - }, - }; - - TestBed.configureTestingModule({ - providers: [ - NextStepsPage, - { - provide: ActivatedRoute, - useValue: mockActivatedRoute, - }, - ], - }); - - component = TestBed.inject(NextStepsPage); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/next-steps/next-steps.page.ts b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/next-steps/next-steps.page.ts deleted file mode 100644 index de3320632..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/next-steps/next-steps.page.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Component } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { ActivatedRoute, RouterLink } from '@angular/router'; - -import { - AlertComponent, - AlertContentDirective, - ContextHelpComponent, - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, -} from '@bcgov/shared/ui'; - -import { InfoGraphicComponent } from '../../shared/components/info-graphic/info-graphic.component'; - -@Component({ - selector: 'app-next-steps', - templateUrl: './next-steps.page.html', - styleUrls: ['./next-steps.page.scss'], - standalone: true, - imports: [ - AlertComponent, - AlertContentDirective, - ContextHelpComponent, - InfoGraphicComponent, - MatButtonModule, - MatFormFieldModule, - MatInputModule, - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, - RouterLink, - ], -}) -export class NextStepsPage { - public title: string; - - public constructor(private route: ActivatedRoute) { - this.title = this.route.snapshot.data.title; - } - - public onSubmit(): void { - return; - } -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration-questions.ts b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration-questions.ts deleted file mode 100644 index 019e273f3..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration-questions.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { SelfDeclarationType } from './self-declaration.enum'; - -export const selfDeclarationQuestions = { - // Limits or conditions - [SelfDeclarationType.LIMITS_OR_CONDITIONS]: `Are you, or have you ever been, subject to any limits, - conditions or prohibitions imposed as a result of disciplinary actions taken by a governing body of a health - profession in any jurisdiction, that involved improper access to, collection, use, or disclosure of personal - information?`, - // Conviction - [SelfDeclarationType.HAS_CONVICTION]: `Are you, or have you ever been, the subject of an order or a - conviction under legislation in any jurisdiction for a matter that involved improper access to, collection, - use, or disclosure of personal information?`, - // Disciplined or fired - [SelfDeclarationType.DISCIPLINED_OR_FIRED]: `Have you ever been disciplined or fired by an employer, or had - a contract for your services terminated, for a matter that involved improper access to, collection, use, or - disclosure of personal information?`, - // Access suspended or cancelled - [SelfDeclarationType.SUSPENDED_OR_CANCELLED]: `Have you ever had your access to an electronic health record - system, electronic medical record system, pharmacy or laboratory record system, or any similar health information - system, in any jurisdiction, suspended or cancelled?`, -}; diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.enum.ts b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.enum.ts deleted file mode 100644 index 8b2a1c0e6..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.enum.ts +++ /dev/null @@ -1,6 +0,0 @@ -export enum SelfDeclarationType { - HAS_CONVICTION = 1, - LIMITS_OR_CONDITIONS, - SUSPENDED_OR_CANCELLED, - DISCIPLINED_OR_FIRED, -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.page.html b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.page.html deleted file mode 100644 index 8ad736a21..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.page.html +++ /dev/null @@ -1,153 +0,0 @@ - - {{ title }} - - - - - Provide the next information to get access to PharmaNet. - - - - - - - - Self-declaration information is collected under the authority of the - Information Management Regulation of the Pharmaceutical Services Act and - confidentiality is protected under the Freedom of Information and - Protection of Privacy Act. Self-declaration information is used to - verify the applicant is in good standing with their respective - College(s) and to determine eligibility for and access to PharmaNet. - - - -

- {{ selfDeclarationQuestions[SelfDeclarationType.HAS_CONVICTION] }} -

- -

Provide these details:

-
    -
  1. - Describe the events that resulted in the order or conviction, - including when the events occurred -
  2. -
  3. - Provide the name and address of the organization where the events took - place that resulted in the order or conviction -
  4. -
  5. - Provide the name of the entity that issued the order or conviction -
  6. -
  7. - Describe the penalty imposed as a result of the order or conviction - (e.g. fine, imprisonment) -
  8. -
  9. Provide the date of the order or conviction
  10. -
- - Type Here - - -
- -

- {{ selfDeclarationQuestions[SelfDeclarationType.LIMITS_OR_CONDITIONS] }} -

- -

Provide these details:

-
    -
  1. - Describe the events that resulted in limits, conditions or - prohibitions being imposed, including when the events occurred -
  2. -
  3. - Provide the name and address of the organization where the events took - place -
  4. -
  5. - Provide the name of the organization that imposed limits, conditions - or prohibitions -
  6. -
  7. Describe the limits, conditions or prohibitions imposed
  8. -
  9. - Provide the date that the limits, conditions or prohibitions were - imposed and, if applicable, removed -
  10. -
- - Type Here - - -
-

- {{ selfDeclarationQuestions[SelfDeclarationType.SUSPENDED_OR_CANCELLED] }} -

- -

Provide these details:

-
    -
  1. - Describe the events that resulted in the suspension or cancellation of - your access, including when the events occurred -
  2. -
  3. - Provide the name and address of the organization that issued the - suspension or cancellation of access -
  4. -
  5. Describe the suspension or cancellation imposed
  6. -
  7. - Provide the date that the suspension or cancellation of access was - imposed and, if applicable, removed -
  8. -
- - Type Here - - -
-

- {{ selfDeclarationQuestions[SelfDeclarationType.DISCIPLINED_OR_FIRED] }} -

- -

Provide these details:

-
    -
  1. - Describe the events that resulted in the discipline or termination, - including when the events occurred -
  2. -
  3. - Provide the name and address of the organization that issued the - discipline or termination -
  4. -
  5. Describe the discipline imposed
  6. -
  7. - Provide the date that the discipline or termination was imposed and, - if applicable, removed -
  8. -
- - Type Here - - -
-
- - - - - - -
diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.page.scss b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.page.scss deleted file mode 100644 index dd2d0ad87..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.page.scss +++ /dev/null @@ -1,11 +0,0 @@ -.bold { - font-weight: 500; -} - -ol { - margin-bottom: 1.5rem; - - & > li { - font-size: 0.8rem; - } -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.page.spec.ts b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.page.spec.ts deleted file mode 100644 index 807046581..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.page.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { ActivatedRoute } from '@angular/router'; - -import { randTextRange } from '@ngneat/falso'; - -import { SelfDeclarationPage } from './self-declaration.page'; - -describe('SelfDeclarationPage', () => { - let component: SelfDeclarationPage; - - let mockActivatedRoute; - - beforeEach(() => { - mockActivatedRoute = { - snapshot: { - data: { - title: randTextRange({ min: 1, max: 4 }), - routes: { - root: '../../', - }, - }, - }, - }; - - TestBed.configureTestingModule({ - providers: [ - SelfDeclarationPage, - { - provide: ActivatedRoute, - useValue: mockActivatedRoute, - }, - ], - }); - - component = TestBed.inject(SelfDeclarationPage); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.page.ts b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.page.ts deleted file mode 100644 index 0d7d03f4d..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/self-declaration/self-declaration.page.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Component } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { ActivatedRoute, RouterLink } from '@angular/router'; - -import { - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, - YesNoContentComponent, -} from '@bcgov/shared/ui'; - -import { selfDeclarationQuestions } from './self-declaration-questions'; -import { SelfDeclarationType } from './self-declaration.enum'; - -@Component({ - selector: 'app-self-declaration', - templateUrl: './self-declaration.page.html', - styleUrls: ['./self-declaration.page.scss'], - standalone: true, - imports: [ - MatButtonModule, - MatFormFieldModule, - MatInputModule, - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, - RouterLink, - YesNoContentComponent, - ], -}) -export class SelfDeclarationPage { - public title: string; - - public SelfDeclarationType = SelfDeclarationType; - public selfDeclarationQuestions = selfDeclarationQuestions; - - public constructor(private route: ActivatedRoute) { - this.title = this.route.snapshot.data.title; - } -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/terms-of-access/terms-of-access.page.html b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/terms-of-access/terms-of-access.page.html deleted file mode 100644 index e0ae1a781..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/terms-of-access/terms-of-access.page.html +++ /dev/null @@ -1,233 +0,0 @@ - - {{ title }} - - - - - Provide the next information to get access to PharmaNet. - - - - - - 1. On-Behalf of User Access -

You represent and warrant to the Province that:

-
    -
  1. - your employment duties in relation to a Practitioner require you to - access PharmaNet (and PharmaNet Data) to support the Practitioner's - delivery of Direct Patient Care; -
  2. -
  3. - you are directly supervised by a Practitioner who has been granted - access to PharmaNet by the Province; and -
  4. -
  5. - all information provided by you in connection with your application for - PharmaNet access, including all -
  6. -
-
- - - 2. Definitions -

In these terms, capitalized terms will have the following meanings:

-

- "Direct Patient Care" means, for the purposes of this - Agreement, the provision of health services to an individual to whom a - Practitioner provides direct patient care in the context of their - Practice. -

-

- "PharmaCare Newsletter" means the PharmaCare newsletter - published by the Province on the following website (or such other website - as may be specified by the Province from time to time for this - purpose):

- - -

-

- "PharmaNet" means PharmaNet as continued under section 2 - of the Information Management Regulation. -

-

- "PharmaNet Data" includes any record or information - contained in PharmaNet and any record or information in the custody, - control or possession of you or a Practitioner that was obtained through - access to PharmaNet by anyone. -

-

- "Practice" means of Practitioner's practice of their - health profession. -

-

- "Practitioner" means of health professional regulated - under the Health Professions Act who supervises your access and use of - PharmaNet and who has been granted access to PharmaNet by the Province. -

-

- "PRIME" means the online service provided by the Province - that allows users to apply for, and manage, their access to PharmaNet, and - through which users are granted access by the Province. -

-
- - - 3. Terms of Access to PharmaNet -

You must:

-
    -
  1. - access and use PharmaNet and PharmaNet Data only to support Direct - Patient Care delivered by the Practitioner to the individuals whose - PharmaNet Data you are accessing; -
  2. -
  3. - only access PharmaNet as permitted by law and directed by the - Practitioner; -
  4. -
  5. - maintain all PharmaNet Data, where accessed on PharmaNet or otherwise - disclosed to you in any manner, in strict confidence; -
  6. -
  7. - maintain the security of PharmaNet, and any applications, connections, - or networks used to access PharmaNet; -
  8. -
  9. - complete all training required by the Practice's PharmaNet software - vendor and the Province before accessing PharmaNet; -
  10. -
-

You must not:

-
    -
  1. - disclose PharmaNet Data for any purpose other than Direct Patient Care, - except as permitted by law and directed by the Practitioner; -
  2. -
  3. - permit any person to use any user IDs, passwords or credentials provided - to you to access PharmaNet; -
  4. -
  5. - reveal, share or compromise any user IDs, passwords or credentials for - PharmaNet; -
  6. -
  7. - use, or attempt to use, the user IDs, passworsds or credentials of any - other person to access PharmaNet; -
  8. -
  9. - take any action that might compromise the integrity of PharmaNet, its - information, or the provincial drug plan, such as altering information - or submitting false information; -
  10. -
  11. test the security related to PharmaNet;
  12. -
  13. - attempt to access PharmaNet from any location other than the approved - Practice site of the -
  14. -
-

- Your access to PharmaNet and use of PharmaNet Data are governed by the - Pharmaceutical Services Act and you must comply with all your duties under - that Act. -

-

- The Province may, in writing and from time to time, set further limits and - conditions in respect of PharmaNet, either for you or for the - Practitioner(s), and that you must comply with any such further limits -

-
- - - 4. How to Notify the Province -

Notice to the province may be sent in writing to:

- -
- Director, Information and PharmaNet Development
- Ministry of Health
- PO Box 9652, STN PROV GOVT
- Victoria, BC V8W 9P4 -
-
- - - 5. Province may modify these terms -

- The Province may amend these terms, including this section, at any time in - its sole discretion: -

- -
    -
  1. - by written notice to you, in which case the amendment will become - effective upon the later of (A) the date notice of the amendment is - first delivered to you, or (B) the effective date of the amendment - specified by the Province, if any; or -
  2. -
  3. - by publishing notice of any such amendment in the PharmaCare Newsletter, - in which case the notice will specify the effective date of the - amendment, which date will be at least thirty (30) days after the -
  4. -
- -

- If you do not agree with any amendment for which notice has been provided - by the Province in accordance with (i) or (ii) above, you must promptly - (and in any event before the effective date) cease all access or use of - PharmaNet. -

- -

- Any written notice to you under (i) above will be in writing and delivered - by the Province to you using any of the contact mechanisms identified by - you in PRIME, including by mail to a specified postal address, email to a - specified emali address or text message to a specified cell phone number. - You maybe required to. -

-
- - - 6. Governing Law -

- These terms will be governed by and will be construed and interpreted in - accordance with the laws of British Columbia and the laws of Canada - applicable therein -

-

- Unless otherwise specified, a reference to a statute or regulation by name - means the statute or regulation of British Columbia of that name, as - amended or replaced from time to time, and includes any enactment. -

-
- -
- - I have read and accept the Terms of Access. - -
- - - - - - -
diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/terms-of-access/terms-of-access.page.scss b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/terms-of-access/terms-of-access.page.scss deleted file mode 100644 index b45c485bb..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/terms-of-access/terms-of-access.page.scss +++ /dev/null @@ -1,14 +0,0 @@ -@import 'palette'; - -li { - margin-bottom: 1.2rem; -} - -// TODO temporary class used during quick setup, but should be a component -.signature { - display: flex; - justify-content: flex-end; - margin-bottom: 2rem; - padding-top: 1rem; - border-top: 1px solid theme-palette(grey); -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/terms-of-access/terms-of-access.page.spec.ts b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/terms-of-access/terms-of-access.page.spec.ts deleted file mode 100644 index 81fdce852..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/terms-of-access/terms-of-access.page.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { ActivatedRoute } from '@angular/router'; - -import { randTextRange } from '@ngneat/falso'; - -import { TermsOfAccessPage } from './terms-of-access.page'; - -describe('TermsOfAccessPage', () => { - let component: TermsOfAccessPage; - - let mockActivatedRoute; - - beforeEach(() => { - mockActivatedRoute = { - snapshot: { - data: { - title: randTextRange({ min: 1, max: 4 }), - routes: { - root: '../../', - }, - }, - }, - }; - - TestBed.configureTestingModule({ - providers: [ - TermsOfAccessPage, - { - provide: ActivatedRoute, - useValue: mockActivatedRoute, - }, - ], - }); - - component = TestBed.inject(TermsOfAccessPage); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/terms-of-access/terms-of-access.page.ts b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/terms-of-access/terms-of-access.page.ts deleted file mode 100644 index a7623ff2c..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pages/terms-of-access/terms-of-access.page.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Component } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { MatCheckboxModule } from '@angular/material/checkbox'; -import { ActivatedRoute, RouterLink } from '@angular/router'; - -import { - AnchorDirective, - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, - PageSubheaderComponent, -} from '@bcgov/shared/ui'; - -@Component({ - selector: 'app-terms-of-access', - templateUrl: './terms-of-access.page.html', - styleUrls: ['./terms-of-access.page.scss'], - standalone: true, - imports: [ - AnchorDirective, - MatButtonModule, - MatCheckboxModule, - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, - PageSubheaderComponent, - RouterLink, - ], -}) -export class TermsOfAccessPage { - public title: string; - - public constructor(private route: ActivatedRoute) { - this.title = this.route.snapshot.data.title; - } -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pharmanet-routing.routes.ts b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pharmanet-routing.routes.ts deleted file mode 100644 index 65779840c..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pharmanet-routing.routes.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Routes } from '@angular/router'; - -import { NextStepsPage } from './pages/next-steps/next-steps.page'; -import { SelfDeclarationPage } from './pages/self-declaration/self-declaration.page'; -import { TermsOfAccessPage } from './pages/terms-of-access/terms-of-access.page'; -import { PharmanetRoutes } from './pharmanet.routes'; - -export const routes: Routes = [ - { - path: PharmanetRoutes.SELF_DECLARATION, - component: SelfDeclarationPage, - data: { - title: 'OneHealthID Service', - }, - }, - { - path: PharmanetRoutes.TERMS_OF_ACCESS, - component: TermsOfAccessPage, - data: { - title: 'OneHealthID Service', - }, - }, - { - path: PharmanetRoutes.NEXT_STEPS, - component: NextStepsPage, - data: { - title: 'OneHealthID Service', - }, - }, - { - path: '', - redirectTo: PharmanetRoutes.SELF_DECLARATION, - pathMatch: 'full', - }, -]; diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pharmanet.routes.ts b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pharmanet.routes.ts deleted file mode 100644 index ea1a5dedf..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/pharmanet.routes.ts +++ /dev/null @@ -1,15 +0,0 @@ -export class PharmanetRoutes { - public static BASE_PATH = 'pharmanet'; - - public static SELF_DECLARATION = 'self-declaration'; - public static TERMS_OF_ACCESS = 'terms-of-access'; - public static NEXT_STEPS = 'next-steps'; - - /** - * @description - * Useful for redirecting to module root-level routes. - */ - public static routePath(route: string): string { - return `/${PharmanetRoutes.BASE_PATH}/${route}`; - } -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/shared/components/info-graphic/info-graphic.component.html b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/shared/components/info-graphic/info-graphic.component.html deleted file mode 100644 index 8e02788e3..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/shared/components/info-graphic/info-graphic.component.html +++ /dev/null @@ -1,8 +0,0 @@ -
-

- -

-
- -
-
diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/shared/components/info-graphic/info-graphic.component.scss b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/shared/components/info-graphic/info-graphic.component.scss deleted file mode 100644 index 481fc5659..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/shared/components/info-graphic/info-graphic.component.scss +++ /dev/null @@ -1,57 +0,0 @@ -@import 'bootstrap/bootstrap-imports'; - -.info-graphic { - background-repeat: no-repeat; - // Position background to match grid gutter - background-position-x: 15px; - background-size: 75px 75px; - // Minimum height for backgrounds, and allow height to - // resize based on fluid content - min-height: 6rem; - // Constrain content length on larger viewports so it - // doesn't exceed background image length - max-width: 48rem; - margin-bottom: 2rem; - // Prevent overlapping of the background image - padding-left: 5rem; - - h2 { - font-size: 1.2rem; - line-height: 1.5; - margin-top: 0.85rem; - margin-bottom: 0.4rem; - } - - h2, - div { - padding-left: 3rem; - } - - @include media-breakpoint-up(lg) { - background-size: auto; - min-height: 11rem; - padding-left: 9rem; - // Padding for content from the background image - padding-top: 2.5rem; - } -} - -$assets: - 'approval' '/assets/images/info-graphic/approval.svg' - '/assets/images/info-graphic/approval-full.svg', - 'notification' '/assets/images/info-graphic/notification.svg' - '/assets/images/info-graphic/notification-full.svg', - 'moa' '/assets/images/info-graphic/moa.svg' - '/assets/images/info-graphic/moa-full.svg', - 'global' '/assets/images/info-graphic/global.svg' - '/assets/images/info-graphic/global-full.svg'; - -@each $name, $path, $full in $assets { - .#{$name} { - background-image: url($path); - - @include media-breakpoint-up(lg) { - background-image: url($full); - } - } -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/shared/components/info-graphic/info-graphic.component.spec.ts b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/shared/components/info-graphic/info-graphic.component.spec.ts deleted file mode 100644 index 81e6381bf..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/shared/components/info-graphic/info-graphic.component.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { InfoGraphicComponent } from './info-graphic.component'; - -describe('InfoGraphicComponent', () => { - let component: InfoGraphicComponent; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [InfoGraphicComponent], - }); - - component = TestBed.inject(InfoGraphicComponent); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/shared/components/info-graphic/info-graphic.component.ts b/workspace/apps/pidp/src/app/features/access/pages/pharmanet/shared/components/info-graphic/info-graphic.component.ts deleted file mode 100644 index 99015a33a..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/pharmanet/shared/components/info-graphic/info-graphic.component.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; - -@Component({ - selector: 'app-info-graphic', - templateUrl: './info-graphic.component.html', - styleUrls: ['./info-graphic.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, - standalone: true, -}) -export class InfoGraphicComponent { - @Input() public infoGraphicName!: - | 'approval' - | 'notification' - | 'moa' - | 'global'; -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist-routing.routes.ts b/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist-routing.routes.ts deleted file mode 100644 index 9e1e77785..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist-routing.routes.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Routes } from '@angular/router'; - -import { SitePrivacySecurityChecklistPage } from './site-privacy-security-checklist.page'; - -export const routes: Routes = [ - { - path: '', - component: SitePrivacySecurityChecklistPage, - data: { - title: 'OneHealthID Service', - routes: { - root: '../../', - }, - setDashboardTitleGuard: { - titleText: 'Welcome to OneHealthID Service', - titleDescriptionText: - 'Complete your profile to gain access to the systems you are eligible for', - }, - }, - }, -]; diff --git a/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.page.html b/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.page.html deleted file mode 100644 index 67757ec32..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.page.html +++ /dev/null @@ -1,176 +0,0 @@ - - {{ title }} - - - - - Answer the following questions. - - - -

1. The worksite has documented privacy and security.

- -

Provide these details:

- - Type Here - - -
-

- 2. The worksite has a documented Breach Response Plan that aligns with the - provincial Breach Policy. -

- -

Provide these details:

- - Type Here - - -
-

- 3. The worksite has a documented remote access policy, that aligns with - [Policy/Link]. -

- -

Provide these details:

- - Type Here - - -
-

- 4. All worksite passwords for staff (including contractors and vendors) - meet the minimum requirements of the "best practices link". -

- -

Provide these details:

- - Type Here - - -
-

- 5. A separate user account is used for System Administration of teh - worksite's local EMR system. -

- -

Provide these details:

- - Type Here - - -
-

- 6. The worksite agrees to notify teh [System Owner(s)] when a staff member - no longer requires access or is on an extended leave of absence (as - detailed in the enrolment package and Appendix A). As per the DHE Systems - Enrolment package/guide/onboarding, your worksite must have an offboarding - procedure for all staff (including contractors and vendors) that ensures - the System Owner is notified when a staff member no longer require access. -

- -

Provide these details:

- - Type Here - - -
-

- 7. The worksite will retain a record, for two years, of all technical - support activities provided by external vendors that have been conducted - on computers that access your EMR [PCN EMR] or worksite network, either - directly or remotely (i.e. invoice/receipt with name of vendor, - description of work and date of service). -

- -

Provide these details:

- - Type Here - - -
-

- 8. Worksite, if applicable, is equipped with a monitored alarm system. - Server/Network equipment is physically secured from unauthorized access. -

- -

Provide these details:

- - Type Here - - -
-

- 9. The worksite WiFi Network's: SSID, WPA2/WPA3 and WiFi password settings - are as per DTO Technical Bulletin. Guest WiFi access is completely - isolated from the Clinic LAN/WiFi network. -

- -

Provide these details:

- - Type Here - - -
-

- 10. There are no legacy/end-of-support operating systems in use (Windows - XP, MacOS older than the latest 3 versions) at the worksite, and the - operating system(s) is/are enabled for auto updates or manually patched as - soon as updates become available. -

- -

Provide these details:

- - Type Here - - -
-

- 11. Anti-virus software is installed, current, and enabled for auto update - on all worksite devices accessing the System(s) (Please attach a - screenshot of the configuration with your signed declaration). -

- -

Provide these details:

- - Type Here - - -
-

- 12. Where it doesn't conflict with worksite EMR's system requirements: - Desktop software, e.g. MS Office / Other applications are patched as soon - as updates become available. Browser plugin (Adobe Flash, PDF, Java) are - patched as soon as updates become available. OR: Such patching conflicts - with my EMR system requirements. -

- -

Provide these details:

- - Type Here - - -
-
- - - - - -
diff --git a/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.page.scss b/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.page.scss deleted file mode 100644 index 5959c0f99..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.page.scss +++ /dev/null @@ -1,3 +0,0 @@ -.bold { - font-weight: 500; -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.page.spec.ts b/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.page.spec.ts deleted file mode 100644 index 3e5bc23f9..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.page.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { ActivatedRoute } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { randTextRange } from '@ngneat/falso'; - -import { SitePrivacySecurityChecklistPage } from './site-privacy-security-checklist.page'; - -describe('SitePrivacySecurityChecklistPage', () => { - let component: SitePrivacySecurityChecklistPage; - - let mockActivatedRoute; - - beforeEach(() => { - mockActivatedRoute = { - snapshot: { - data: { - title: randTextRange({ min: 1, max: 4 }), - }, - }, - }; - - TestBed.configureTestingModule({ - imports: [RouterTestingModule], - providers: [ - SitePrivacySecurityChecklistPage, - { - provide: ActivatedRoute, - useValue: mockActivatedRoute, - }, - ], - }); - - component = TestBed.inject(SitePrivacySecurityChecklistPage); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.page.ts b/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.page.ts deleted file mode 100644 index 0c5371aa1..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.page.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Component } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { ActivatedRoute, Router } from '@angular/router'; - -import { - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, - YesNoContentComponent, -} from '@bcgov/shared/ui'; - -@Component({ - selector: 'app-site-privacy-security-checklist', - templateUrl: './site-privacy-security-checklist.page.html', - styleUrls: ['./site-privacy-security-checklist.page.scss'], - standalone: true, - imports: [ - MatButtonModule, - MatFormFieldModule, - MatInputModule, - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, - YesNoContentComponent, - ], -}) -export class SitePrivacySecurityChecklistPage { - public title: string; - - public constructor( - private route: ActivatedRoute, - private router: Router, - ) { - this.title = this.route.snapshot.data.title; - } - - public onSubmit(): void { - this.navigateToRoot(); - } - - public onBack(): void { - this.navigateToRoot(); - } - - private navigateToRoot(): void { - this.router.navigate([this.route.snapshot.data.routes.root]); - } -} diff --git a/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.routes.ts b/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.routes.ts deleted file mode 100644 index 3087dc3cd..000000000 --- a/workspace/apps/pidp/src/app/features/access/pages/site-privacy-security-checklist/site-privacy-security-checklist.routes.ts +++ /dev/null @@ -1,11 +0,0 @@ -export class SitePrivacySecurityChecklistRoutes { - public static BASE_PATH = 'site-privacy-and-security-checklist'; - - /** - * @description - * Useful for redirecting to module root-level routes. - */ - public static routePath(route: string): string { - return `/${SitePrivacySecurityChecklistRoutes.BASE_PATH}/${route}`; - } -} diff --git a/workspace/apps/pidp/src/app/features/organization-info/organization-info-routing.routes.ts b/workspace/apps/pidp/src/app/features/organization-info/organization-info-routing.routes.ts index 2c7c53e6a..e286a46a0 100644 --- a/workspace/apps/pidp/src/app/features/organization-info/organization-info-routing.routes.ts +++ b/workspace/apps/pidp/src/app/features/organization-info/organization-info-routing.routes.ts @@ -3,27 +3,6 @@ import { Routes } from '@angular/router'; import { OrganizationInfoRoutes } from './organization-info.routes'; export const routes: Routes = [ - { - path: OrganizationInfoRoutes.ORGANIZATION_DETAILS, - loadChildren: (): Promise => - import( - './pages/organization-details/organization-details-routing.routes' - ).then((m) => m.routes), - }, - { - path: OrganizationInfoRoutes.FACILITY_DETAILS, - loadChildren: (): Promise => - import('./pages/facility-details/facility-details-routing.routes').then( - (m) => m.routes, - ), - }, - { - path: OrganizationInfoRoutes.ADMINISTRATOR_INFO, - loadChildren: (): Promise => - import( - './pages/administrator-information/administrator-information-routing.routes' - ).then((m) => m.routes), - }, { path: OrganizationInfoRoutes.ENDORSEMENTS, loadChildren: (): Promise => diff --git a/workspace/apps/pidp/src/app/features/organization-info/organization-info.routes.ts b/workspace/apps/pidp/src/app/features/organization-info/organization-info.routes.ts index 99446b8f1..d13c97d19 100644 --- a/workspace/apps/pidp/src/app/features/organization-info/organization-info.routes.ts +++ b/workspace/apps/pidp/src/app/features/organization-info/organization-info.routes.ts @@ -1,9 +1,6 @@ export class OrganizationInfoRoutes { public static BASE_PATH = 'organization-info'; - public static ADMINISTRATOR_INFO = 'administrator-info'; - public static ORGANIZATION_DETAILS = 'organization-details'; - public static FACILITY_DETAILS = 'facility-details'; public static ENDORSEMENTS = 'endorsements'; /** diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information-form-state.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information-form-state.ts deleted file mode 100644 index a60bf271c..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information-form-state.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { FormBuilder, Validators } from '@angular/forms'; - -import { AbstractFormState, FormControlValidators } from '@bcgov/shared/ui'; - -import { AdministratorInformation } from './administrator-information.model'; - -export class AdministratorInformationFormState extends AbstractFormState { - public constructor(private fb: FormBuilder) { - super(); - - this.buildForm(); - } - - public get json(): AdministratorInformation | undefined { - if (!this.formInstance) { - return; - } - - return this.formInstance.getRawValue(); - } - - public patchValue(model: AdministratorInformation | null): void { - if (!this.formInstance || !model) { - return; - } - - this.formInstance.patchValue(model); - } - - public buildForm(): void { - this.formInstance = this.fb.group({ - email: [null, [Validators.required, FormControlValidators.email]], - }); - } -} diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information-resource.service.spec.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information-resource.service.spec.ts deleted file mode 100644 index de1251678..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information-resource.service.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { TestBed } from '@angular/core/testing'; -import { MatSnackBarModule } from '@angular/material/snack-bar'; - -import { APP_CONFIG, APP_DI_CONFIG } from '@app/app.config'; - -import { AdministratorInformationResource } from './administrator-information-resource.service'; - -describe('AdministratorInformationResource', () => { - let service: AdministratorInformationResource; - - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [HttpClientTestingModule, MatSnackBarModule], - providers: [ - AdministratorInformationResource, - { - provide: APP_CONFIG, - useValue: APP_DI_CONFIG, - }, - ], - }); - - service = TestBed.inject(AdministratorInformationResource); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information-resource.service.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information-resource.service.ts deleted file mode 100644 index ddd93e9b1..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information-resource.service.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Injectable } from '@angular/core'; - -import { catchError, tap, throwError } from 'rxjs'; - -import { CrudResource, NoContent } from '@bcgov/shared/data-access'; - -import { ApiHttpClient } from '@app/core/resources/api-http-client.service'; -import { ToastService } from '@app/core/services/toast.service'; - -import { AdministratorInformation } from './administrator-information.model'; - -@Injectable({ - providedIn: 'root', -}) -export class AdministratorInformationResource extends CrudResource { - public constructor( - protected apiResource: ApiHttpClient, - private toastService: ToastService, - ) { - super(apiResource); - } - - public update(id: number, payload: AdministratorInformation): NoContent { - return super.update(id, payload).pipe( - tap(() => - this.toastService.openSuccessToast( - 'Administrator information has been updated', - ), - ), - catchError((error: HttpErrorResponse) => { - this.toastService.openErrorToast( - 'Administrator information could not be updated', - ); - return throwError(() => error); - }), - ); - } - - protected getResourcePath(partyId: number): string { - return `parties/${partyId}/access-administrator`; - } -} diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information-routing.routes.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information-routing.routes.ts deleted file mode 100644 index 6e5fb0c07..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information-routing.routes.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Routes } from '@angular/router'; - -import { AdministratorInformationPage } from './administrator-information.page'; - -export const routes: Routes = [ - { - path: '', - component: AdministratorInformationPage, - data: { - title: 'OneHealthID Service', - routes: { - root: '../../', - }, - }, - }, -]; diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information.model.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information.model.ts deleted file mode 100644 index 4b74e6544..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information.model.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface AdministratorInformation { - email: string; -} diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information.page.html b/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information.page.html deleted file mode 100644 index b2c6baca0..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information.page.html +++ /dev/null @@ -1,42 +0,0 @@ - - {{ title }} - - - - - Provide your office administrator's contact information. - - - - - - - - Enter your access administrator's email. - - - - Access administrator email - - Required - - - - - - - - - - diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information.page.scss b/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information.page.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information.page.spec.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information.page.spec.ts deleted file mode 100644 index 41fbf9e68..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information.page.spec.ts +++ /dev/null @@ -1,196 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { HttpStatusCode } from '@angular/common/http'; -import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatDialogModule } from '@angular/material/dialog'; -import { ActivatedRoute, Router } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { randEmail, randNumber, randTextRange } from '@ngneat/falso'; -import { Spy, createSpyFromClass, provideAutoSpy } from 'jest-auto-spies'; - -import { APP_CONFIG, APP_DI_CONFIG } from '@app/app.config'; -import { PartyService } from '@app/core/party/party.service'; -import { FormUtilsService } from '@app/core/services/form-utils.service'; -import { LoggerService } from '@app/core/services/logger.service'; - -import { AdministratorInformationResource } from './administrator-information-resource.service'; -import { AdministratorInformation } from './administrator-information.model'; -import { AdministratorInformationPage } from './administrator-information.page'; - -describe('AdministratorInformationPage', () => { - let component: AdministratorInformationPage; - let partyServiceSpy: Spy; - let administratorInfoResourceSpy: Spy; - let formUtilsServiceSpy: Spy; - let router: Router; - - let mockActivatedRoute: { snapshot: any }; - let mockForm: AdministratorInformation; - - beforeEach(() => { - mockActivatedRoute = { - snapshot: { - data: { - title: randTextRange({ min: 1, max: 4 }), - routes: { - root: '../../', - }, - }, - }, - }; - - TestBed.configureTestingModule({ - imports: [ - HttpClientTestingModule, - MatDialogModule, - ReactiveFormsModule, - RouterTestingModule, - ], - providers: [ - AdministratorInformationPage, - { - provide: APP_CONFIG, - useValue: APP_DI_CONFIG, - }, - { - provide: ActivatedRoute, - useValue: mockActivatedRoute, - }, - { - provide: PartyService, - useValue: createSpyFromClass(PartyService, { - gettersToSpyOn: ['partyId'], - settersToSpyOn: ['partyId'], - }), - }, - provideAutoSpy(AdministratorInformationResource), - provideAutoSpy(FormUtilsService), - provideAutoSpy(LoggerService), - provideAutoSpy(Router), - ], - }); - - router = TestBed.inject(Router); - component = TestBed.inject(AdministratorInformationPage); - partyServiceSpy = TestBed.inject(PartyService); - administratorInfoResourceSpy = TestBed.inject( - AdministratorInformationResource, - ); - formUtilsServiceSpy = TestBed.inject(FormUtilsService); - - mockForm = { - email: randEmail(), - }; - }); - - describe('INIT', () => { - given('partyId exists', () => { - const partyId = randNumber({ min: 1 }); - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - administratorInfoResourceSpy.get.nextOneTimeWith(mockForm); - - when('resource request resolved', () => { - component.ngOnInit(); - - then('it should GET party organization details', () => { - expect(router.navigate).not.toHaveBeenCalled(); - expect(administratorInfoResourceSpy.get).toHaveBeenCalledTimes(1); - expect(administratorInfoResourceSpy.get).toHaveBeenCalledWith( - partyId, - ); - }); - }); - }); - - given('partyId exists', () => { - const partyId = randNumber({ min: 1 }); - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - administratorInfoResourceSpy.get.nextWithValues([ - { - errorValue: { - status: HttpStatusCode.NotFound, - }, - }, - ]); - - when('resource request rejected', () => { - component.ngOnInit(); - - then('router should navigate to root route', () => { - const rootRoute = mockActivatedRoute.snapshot.data.routes.root; - expect(router.navigate).toHaveBeenCalledWith([rootRoute]); - }); - }); - }); - - given('partyId does not exist', () => { - const partyId = null; - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - - when('initializing the component', () => { - component.ngOnInit(); - - then('router should navigate to root route', () => { - const rootRoute = mockActivatedRoute.snapshot.data.routes.root; - expect(router.navigate).toHaveBeenCalledWith([rootRoute]); - }); - }); - }); - }); - - describe('METHOD: onSubmit', () => { - given('a form submission', () => { - const partyId = randNumber({ min: 1 }); - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - component.formState.form.patchValue(mockForm); - - when('no validation errors exist', () => { - formUtilsServiceSpy.checkValidity.mockReturnValue(true); - administratorInfoResourceSpy.update - .mustBeCalledWith(partyId, mockForm) - .nextWith(void 0); - component.onSubmit(); - - then( - 'access administrator will be updated and router navigate to root route', - () => { - expect(router.navigate).toHaveBeenCalled(); - }, - ); - }); - }); - - given('a form submission', () => { - const partyId = randNumber({ min: 1 }); - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - component.formState.form.patchValue(mockForm); - - when('validation errors exist', () => { - formUtilsServiceSpy.checkValidity.mockReturnValue(false); - component.onSubmit(); - - then( - 'access administrator should not be updated and router not navigate', - () => { - expect(router.navigate).not.toHaveBeenCalled(); - }, - ); - }); - }); - }); - - describe('METHOD: onBack', () => { - given('user wants to go back to the previous page', () => { - when('onBack is invoked', () => { - component.onBack(); - - then('router should navigate to root route', () => { - const rootRoute = mockActivatedRoute.snapshot.data.routes.root; - expect(router.navigate).toHaveBeenCalledWith([rootRoute]); - }); - }); - }); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information.page.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information.page.ts deleted file mode 100644 index 16ae52d03..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/administrator-information/administrator-information.page.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonModule } from '@angular/material/button'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { ActivatedRoute, Router } from '@angular/router'; - -import { EMPTY, catchError, of, tap } from 'rxjs'; - -import { NoContent } from '@bcgov/shared/data-access'; -import { - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, -} from '@bcgov/shared/ui'; - -import { - AbstractFormDependenciesService, - AbstractFormPage, -} from '@app/core/classes/abstract-form-page.class'; -import { PartyService } from '@app/core/party/party.service'; -import { LoggerService } from '@app/core/services/logger.service'; - -import { AdministratorInformationFormState } from './administrator-information-form-state'; -import { AdministratorInformationResource } from './administrator-information-resource.service'; -import { AdministratorInformation } from './administrator-information.model'; - -@Component({ - selector: 'app-administrator-information', - templateUrl: './administrator-information.page.html', - styleUrls: ['./administrator-information.page.scss'], - standalone: true, - imports: [ - MatButtonModule, - MatFormFieldModule, - MatInputModule, - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, - ReactiveFormsModule, - ], -}) -export class AdministratorInformationPage - extends AbstractFormPage - implements OnInit -{ - public title: string; - public formState: AdministratorInformationFormState; - - // ui-page is handling this. - public showOverlayOnSubmit = false; - - public constructor( - dependenciesService: AbstractFormDependenciesService, - private route: ActivatedRoute, - private router: Router, - private partyService: PartyService, - private resource: AdministratorInformationResource, - private logger: LoggerService, - fb: FormBuilder, - ) { - super(dependenciesService); - - const routeData = this.route.snapshot.data; - this.title = routeData.title; - this.formState = new AdministratorInformationFormState(fb); - } - - public onBack(): void { - this.navigateToRoot(); - } - - public ngOnInit(): void { - const partyId = this.partyService.partyId; - if (!partyId) { - this.logger.error('No party ID was provided'); - return this.navigateToRoot(); - } - - this.resource - .get(partyId) - .pipe( - tap((model: AdministratorInformation | null) => - this.formState.patchValue(model), - ), - catchError((error: HttpErrorResponse) => { - if (error.status === HttpStatusCode.NotFound) { - this.navigateToRoot(); - } - return of(null); - }), - ) - .subscribe(); - } - - protected performSubmission(): NoContent { - const partyId = this.partyService.partyId; - - return partyId && this.formState.json - ? this.resource.update(partyId, this.formState.json) - : EMPTY; - } - - protected afterSubmitIsSuccessful(): void { - this.navigateToRoot(); - } - - private navigateToRoot(): void { - this.router.navigate([this.route.snapshot.data.routes.root]); - } -} diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/facility-details/facility-details-routing.routes.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/facility-details/facility-details-routing.routes.ts deleted file mode 100644 index 33493b813..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/facility-details/facility-details-routing.routes.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Routes } from '@angular/router'; - -import { FacilityDetailsPage } from './facility-details.page'; - -export const routes: Routes = [ - { - path: '', - component: FacilityDetailsPage, - data: { - title: 'OneHealthID Service', - routes: { - root: '../../', - }, - }, - }, -]; diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/facility-details/facility-details.page.html b/workspace/apps/pidp/src/app/features/organization-info/pages/facility-details/facility-details.page.html deleted file mode 100644 index a6a1d394e..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/facility-details/facility-details.page.html +++ /dev/null @@ -1 +0,0 @@ -

facility-details works!

diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/facility-details/facility-details.page.scss b/workspace/apps/pidp/src/app/features/organization-info/pages/facility-details/facility-details.page.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/facility-details/facility-details.page.spec.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/facility-details/facility-details.page.spec.ts deleted file mode 100644 index 14700c13d..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/facility-details/facility-details.page.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { FacilityDetailsPage } from './facility-details.page'; - -describe('FacilityDetailsPage', () => { - let component: FacilityDetailsPage; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [FacilityDetailsPage], - }); - - component = TestBed.inject(FacilityDetailsPage); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/facility-details/facility-details.page.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/facility-details/facility-details.page.ts deleted file mode 100644 index 3c5d3af1b..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/facility-details/facility-details.page.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'app-facility-details', - templateUrl: './facility-details.page.html', - styleUrls: ['./facility-details.page.scss'], - standalone: true, -}) -export class FacilityDetailsPage {} diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details-form-state.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details-form-state.ts deleted file mode 100644 index 43846f040..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details-form-state.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { FormBuilder, FormControl, Validators } from '@angular/forms'; - -import { AbstractFormState, FormControlValidators } from '@bcgov/shared/ui'; - -import { OrganizationDetails } from './organization-details.model'; - -export class OrganizationDetailsFormState extends AbstractFormState { - public constructor(private fb: FormBuilder) { - super(); - - this.buildForm(); - } - - public get organizationCode(): FormControl { - return this.formInstance.get('organizationCode') as FormControl; - } - - public get json(): OrganizationDetails | undefined { - if (!this.formInstance) { - return; - } - - return this.formInstance.getRawValue(); - } - - public patchValue(model: OrganizationDetails | null): void { - if (!this.formInstance || !model) { - return; - } - - this.formInstance.patchValue(model); - } - - public buildForm(): void { - this.formInstance = this.fb.group({ - organizationCode: [ - 0, - [Validators.required, FormControlValidators.requiredIndex], - ], - healthAuthorityCode: [ - 0, - [Validators.required, FormControlValidators.requiredIndex], - ], - employeeIdentifier: ['', [Validators.required]], - }); - } -} diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details-resource.service.spec.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details-resource.service.spec.ts deleted file mode 100644 index 4ae65fee9..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details-resource.service.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { TestBed } from '@angular/core/testing'; - -import { APP_CONFIG, APP_DI_CONFIG } from '@app/app.config'; - -import { OrganizationDetailsResource } from './organization-details-resource.service'; - -describe('OrganizationDetailsResource', () => { - let service: OrganizationDetailsResource; - - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [HttpClientTestingModule], - providers: [ - OrganizationDetailsResource, - { - provide: APP_CONFIG, - useValue: APP_DI_CONFIG, - }, - ], - }); - - service = TestBed.inject(OrganizationDetailsResource); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details-resource.service.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details-resource.service.ts deleted file mode 100644 index a3b97a67c..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details-resource.service.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Injectable } from '@angular/core'; - -import { CrudResource } from '@bcgov/shared/data-access'; - -import { ApiHttpClient } from '@app/core/resources/api-http-client.service'; - -import { OrganizationDetails } from './organization-details.model'; - -@Injectable({ - providedIn: 'root', -}) -export class OrganizationDetailsResource extends CrudResource { - public constructor(protected apiResource: ApiHttpClient) { - super(apiResource); - } - - protected getResourcePath(partyId: number): string { - return `parties/${partyId}/organization-details`; - } -} diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details-routing.routes.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details-routing.routes.ts deleted file mode 100644 index f06a97136..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details-routing.routes.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Routes } from '@angular/router'; - -import { OrganizationDetailsPage } from './organization-details.page'; - -export const routes: Routes = [ - { - path: '', - component: OrganizationDetailsPage, - data: { - title: 'OneHealthID Service', - routes: { - root: '../../', - }, - }, - }, -]; diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details.model.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details.model.ts deleted file mode 100644 index deeafb1b6..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface OrganizationDetails { - organizationCode: number; - healthAuthorityCode: number; - employeeIdentifier: string; -} diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details.page.html b/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details.page.html deleted file mode 100644 index fcdaf7e50..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details.page.html +++ /dev/null @@ -1,77 +0,0 @@ - - {{ title }} - - - - - Provide your organization's details. - - - - -
- Organization Type -

Select your organization type.

- - - Organization Type - - - {{ organization.name }} - - - Required - -
- - -
- Health Authority -

Select what Health Authority you work in.

- - - Health Authority - - - {{ healthAuthority.name }} - - - Required - -
- -
- Health Authority Employee ID -

Provide your Health Authority employee ID.

- - - Health Authority Employee ID - - Required - -
-
-
-
- - - - - -
diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details.page.scss b/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details.page.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details.page.spec.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details.page.spec.ts deleted file mode 100644 index e091274e6..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details.page.spec.ts +++ /dev/null @@ -1,198 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { HttpStatusCode } from '@angular/common/http'; -import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatDialogModule } from '@angular/material/dialog'; -import { ActivatedRoute, Router } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { randNumber, randTextRange, randWord } from '@ngneat/falso'; -import { Spy, createSpyFromClass, provideAutoSpy } from 'jest-auto-spies'; - -import { APP_CONFIG, APP_DI_CONFIG } from '@app/app.config'; -import { PartyService } from '@app/core/party/party.service'; -import { FormUtilsService } from '@app/core/services/form-utils.service'; -import { LoggerService } from '@app/core/services/logger.service'; - -import { OrganizationDetailsResource } from './organization-details-resource.service'; -import { OrganizationDetails } from './organization-details.model'; -import { OrganizationDetailsPage } from './organization-details.page'; - -describe('OrganizationDetailsPage', () => { - let component: OrganizationDetailsPage; - let partyServiceSpy: Spy; - let organizationDetailsResourceSpy: Spy; - let formUtilsServiceSpy: Spy; - let router: Router; - - let mockActivatedRoute: { snapshot: any }; - let mockForm: OrganizationDetails; - - beforeEach(() => { - mockActivatedRoute = { - snapshot: { - data: { - title: randTextRange({ min: 1, max: 4 }), - routes: { - root: '../../', - }, - }, - }, - }; - - TestBed.configureTestingModule({ - imports: [ - HttpClientTestingModule, - MatDialogModule, - ReactiveFormsModule, - RouterTestingModule, - ], - providers: [ - OrganizationDetailsPage, - { - provide: APP_CONFIG, - useValue: APP_DI_CONFIG, - }, - { - provide: ActivatedRoute, - useValue: mockActivatedRoute, - }, - { - provide: PartyService, - useValue: createSpyFromClass(PartyService, { - gettersToSpyOn: ['partyId'], - settersToSpyOn: ['partyId'], - }), - }, - provideAutoSpy(OrganizationDetailsResource), - provideAutoSpy(FormUtilsService), - provideAutoSpy(LoggerService), - provideAutoSpy(Router), - ], - }); - - router = TestBed.inject(Router); - component = TestBed.inject(OrganizationDetailsPage); - partyServiceSpy = TestBed.inject(PartyService); - organizationDetailsResourceSpy = TestBed.inject( - OrganizationDetailsResource, - ); - formUtilsServiceSpy = TestBed.inject(FormUtilsService); - - mockForm = { - organizationCode: randNumber(), - healthAuthorityCode: randNumber(), - employeeIdentifier: randWord(), - }; - }); - - describe('INIT', () => { - given('partyId exists', () => { - const partyId = randNumber({ min: 1 }); - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - organizationDetailsResourceSpy.get.nextOneTimeWith(mockForm); - - when('resource request resolved', () => { - component.ngOnInit(); - - then('it should GET party organization details information', () => { - expect(router.navigate).not.toHaveBeenCalled(); - expect(organizationDetailsResourceSpy.get).toHaveBeenCalledTimes(1); - expect(organizationDetailsResourceSpy.get).toHaveBeenCalledWith( - partyId, - ); - }); - }); - }); - - given('partyId exists', () => { - const partyId = randNumber({ min: 1 }); - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - organizationDetailsResourceSpy.get.nextWithValues([ - { - errorValue: { - status: HttpStatusCode.NotFound, - }, - }, - ]); - - when('resource request rejected', () => { - component.ngOnInit(); - - then('router should navigate to root route', () => { - const rootRoute = mockActivatedRoute.snapshot.data.routes.root; - expect(router.navigate).toHaveBeenCalledWith([rootRoute]); - }); - }); - }); - - given('partyId does not exist', () => { - const partyId = null; - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - - when('initializing the component', () => { - component.ngOnInit(); - - then('router should navigate to root route', () => { - const rootRoute = mockActivatedRoute.snapshot.data.routes.root; - expect(router.navigate).toHaveBeenCalledWith([rootRoute]); - }); - }); - }); - }); - - describe('METHOD: onSubmit', () => { - given('a form submission', () => { - const partyId = randNumber({ min: 1 }); - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - component.formState.form.patchValue(mockForm); - - when('no validation errors exist', () => { - formUtilsServiceSpy.checkValidity.mockReturnValue(true); - organizationDetailsResourceSpy.update - .mustBeCalledWith(partyId, mockForm) - .nextWith(void 0); - component.onSubmit(); - - then( - 'organization details will be updated and router navigate to root route', - () => { - expect(router.navigate).toHaveBeenCalled(); - }, - ); - }); - }); - - given('a form submission', () => { - const partyId = randNumber({ min: 1 }); - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - component.formState.form.patchValue(mockForm); - - when('validation errors exist', () => { - formUtilsServiceSpy.checkValidity.mockReturnValue(false); - component.onSubmit(); - - then( - 'organization details should not be updated and router not navigate', - () => { - expect(router.navigate).not.toHaveBeenCalled(); - }, - ); - }); - }); - }); - - describe('METHOD: onBack', () => { - given('user wants to go back to the previous page', () => { - when('onBack is invoked', () => { - component.onBack(); - - then('router should navigate to root route', () => { - const rootRoute = mockActivatedRoute.snapshot.data.routes.root; - expect(router.navigate).toHaveBeenCalledWith([rootRoute]); - }); - }); - }); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details.page.ts b/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details.page.ts deleted file mode 100644 index 93c62c537..000000000 --- a/workspace/apps/pidp/src/app/features/organization-info/pages/organization-details/organization-details.page.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { NgFor, NgIf } from '@angular/common'; -import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonModule } from '@angular/material/button'; -import { MatOptionModule } from '@angular/material/core'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatSelectModule } from '@angular/material/select'; -import { ActivatedRoute, Router } from '@angular/router'; - -import { EMPTY, catchError, of, tap } from 'rxjs'; - -import { NoContent, OrganizationCode } from '@bcgov/shared/data-access'; -import { - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, - PageSubheaderComponent, -} from '@bcgov/shared/ui'; - -import { - AbstractFormDependenciesService, - AbstractFormPage, -} from '@app/core/classes/abstract-form-page.class'; -import { PartyService } from '@app/core/party/party.service'; -import { LoggerService } from '@app/core/services/logger.service'; -import { LookupService } from '@app/modules/lookup/lookup.service'; -import { Lookup } from '@app/modules/lookup/lookup.types'; - -import { OrganizationDetailsFormState } from './organization-details-form-state'; -import { OrganizationDetailsResource } from './organization-details-resource.service'; -import { OrganizationDetails } from './organization-details.model'; - -@Component({ - selector: 'app-organization-details', - templateUrl: './organization-details.page.html', - styleUrls: ['./organization-details.page.scss'], - standalone: true, - imports: [ - MatButtonModule, - MatFormFieldModule, - MatInputModule, - MatOptionModule, - MatSelectModule, - NgFor, - NgIf, - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, - PageSubheaderComponent, - ReactiveFormsModule, - ], -}) -export class OrganizationDetailsPage - extends AbstractFormPage - implements OnInit -{ - public title: string; - public formState: OrganizationDetailsFormState; - public organizations: (Lookup & { disabled: boolean })[]; - public healthAuthorities: Lookup[]; - - // ui-page is handling this. - public showOverlayOnSubmit = false; - - public constructor( - dependenciesService: AbstractFormDependenciesService, - private route: ActivatedRoute, - private router: Router, - private partyService: PartyService, - private resource: OrganizationDetailsResource, - private logger: LoggerService, - private lookupService: LookupService, - fb: FormBuilder, - ) { - super(dependenciesService); - - const routeData = this.route.snapshot.data; - this.title = routeData.title; - this.formState = new OrganizationDetailsFormState(fb); - this.organizations = this.lookupService.organizations.map( - (organization) => ({ - ...organization, - disabled: organization.code !== OrganizationCode.HealthAuthority, - }), - ); - this.healthAuthorities = this.lookupService.healthAuthorities; - } - - public onBack(): void { - this.navigateToRoot(); - } - - public ngOnInit(): void { - const partyId = this.partyService.partyId; - if (!partyId) { - this.logger.error('No party ID was provided'); - return this.navigateToRoot(); - } - - this.resource - .get(partyId) - .pipe( - tap((model: OrganizationDetails | null) => - this.formState.patchValue(model), - ), - catchError((error: HttpErrorResponse) => { - if (error.status === HttpStatusCode.NotFound) { - this.navigateToRoot(); - } - return of(null); - }), - ) - .subscribe(); - } - - protected performSubmission(): NoContent { - const partyId = this.partyService.partyId; - - return partyId && this.formState.json - ? this.resource.update(partyId, this.formState.json) - : EMPTY; - } - - protected afterSubmitIsSuccessful(): void { - this.navigateToRoot(); - } - - private navigateToRoot(): void { - this.router.navigate([this.route.snapshot.data.routes.root]); - } -} diff --git a/workspace/apps/pidp/src/app/features/portal/portal.page.ts b/workspace/apps/pidp/src/app/features/portal/portal.page.ts index ec2494411..0a206a924 100644 --- a/workspace/apps/pidp/src/app/features/portal/portal.page.ts +++ b/workspace/apps/pidp/src/app/features/portal/portal.page.ts @@ -8,7 +8,7 @@ import { MatStepperModule } from '@angular/material/stepper'; import { MatTooltipModule } from '@angular/material/tooltip'; import { Router, RouterLink } from '@angular/router'; -import { BehaviorSubject, Observable, tap } from 'rxjs'; +import { BehaviorSubject, Observable, of, switchMap, tap } from 'rxjs'; import { AlertComponent, @@ -36,6 +36,7 @@ import { AuthorizedUserService } from '../auth/services/authorized-user.service' import { BannerExpansionPanelComponent } from './components/banner-expansion-panel/banner-expansion-panel.component'; import { PortalAlertComponent } from './components/portal-alert/portal-alert.component'; import { PortalCarouselComponent } from './components/portal-carousel/portal-carousel.component'; +import { StatusCode } from './enums/status-code.enum'; import { ProfileStatusAlert } from './models/profile-status-alert.model'; import { ProfileStatus } from './models/profile-status.model'; import { PortalResource } from './portal-resource.service'; @@ -106,7 +107,6 @@ export class PortalPage implements OnInit { public selectedIndex: number; private readonly lastSelectedIndex: number; public hasCpn: boolean | undefined; - public collegeLicenceDeclared: boolean | undefined; public destination$: Observable; public IdentityProvider = IdentityProvider; public identityProvider$: Observable; @@ -143,11 +143,11 @@ export class PortalPage implements OnInit { } public navigateTo(): void { - if (this.bcProviderStatusCode !== 2) { + if (this.bcProviderStatusCode !== StatusCode.COMPLETED) { this.router.navigateByUrl('/access/bc-provider-application'); } else if ( - this.bcProviderStatusCode === 2 && - this.rosteringStatusCode === 1 + this.bcProviderStatusCode === StatusCode.COMPLETED && + this.rosteringStatusCode === StatusCode.AVAILABLE ) { this.navigateToExternalUrl('https://bchealthprovider.ca'); this.authService.logout(this.logoutRedirectUrl); @@ -176,42 +176,83 @@ export class PortalPage implements OnInit { } public ngOnInit(): void { - this.portalResource - .getProfileStatus(this.partyService.partyId) + const profileStatus$ = this.portalResource.getProfileStatus( + this.partyService.partyId, + ); + + this.updateStateAndAlerts(profileStatus$); + this.handlePasBannerStatus(profileStatus$); + this.handlePasBannerRosteringStatus(profileStatus$); + } + + private updateStateAndAlerts( + profileStatus$: Observable, + ): void { + profileStatus$ .pipe( tap((profileStatus: ProfileStatus | null) => { this.portalService.updateState(profileStatus); this.alerts = this.portalService.alerts; }), ) - .subscribe((profileStatus) => { - let selectedIndex = this.lastSelectedIndex; - this.hasCpn = profileStatus?.status.collegeCertification.hasCpn; - this.collegeLicenceDeclared = - profileStatus?.status.collegeCertification.licenceDeclared; - - this.bcProviderStatusCode = profileStatus?.status.bcProvider.statusCode; - if (this.bcProviderStatusCode === 2) { - this.bcProvider$.next(true); - this.bcProviderResource - .get(this.partyService.partyId) - .subscribe((bcProviderObject: BcProviderEditInitialStateModel) => { - this.bcProviderUsername = bcProviderObject.bcProviderId; - }); - } else if (selectedIndex === this.lastSelectedIndex) { - // BCrovider step - selectedIndex = 0; - } - this.rosteringStatusCode = - profileStatus?.status.primaryCareRostering.statusCode; - if (this.rosteringStatusCode === 1) { - this.rostering$.next(false); - } else if (selectedIndex === this.lastSelectedIndex) { - // PAS step - selectedIndex = 1; - } - this.selectedIndex = selectedIndex; - }); + .subscribe(); + } + + private handlePasBannerStatus( + profileStatus$: Observable, + ): void { + profileStatus$ + .pipe( + switchMap( + ( + profileStatus, + ): Observable => { + let selectedIndex = this.lastSelectedIndex; + this.hasCpn = profileStatus?.status.collegeCertification.hasCpn; + + this.bcProviderStatusCode = + profileStatus?.status.bcProvider.statusCode; + if (this.bcProviderStatusCode === StatusCode.COMPLETED) { + this.bcProvider$.next(true); + return this.bcProviderResource.get(this.partyService.partyId); + } else { + if (selectedIndex === this.lastSelectedIndex) { + // BCProvider step + selectedIndex = 0; + } + this.selectedIndex = selectedIndex; + return of(null); + } + }, + ), + tap((bcProviderObject: BcProviderEditInitialStateModel | null) => { + if (bcProviderObject) { + this.bcProviderUsername = bcProviderObject.bcProviderId; + } + }), + ) + .subscribe(); + } + + private handlePasBannerRosteringStatus( + profileStatus$: Observable, + ): void { + profileStatus$ + .pipe( + tap((profileStatus: ProfileStatus | null) => { + let selectedIndex = this.lastSelectedIndex; + this.rosteringStatusCode = + profileStatus?.status.primaryCareRostering.statusCode; + if (this.rosteringStatusCode === StatusCode.AVAILABLE) { + this.rostering$.next(false); + } else if (selectedIndex === this.lastSelectedIndex) { + // PAS step + selectedIndex = 1; + } + this.selectedIndex = selectedIndex; + }), + ) + .subscribe(); } private navigateToExternalUrl(url: string): void { diff --git a/workspace/apps/pidp/src/app/features/portal/state/access/access-group.model.ts b/workspace/apps/pidp/src/app/features/portal/state/access/access-group.model.ts index 5a1378287..249a0d8d3 100644 --- a/workspace/apps/pidp/src/app/features/portal/state/access/access-group.model.ts +++ b/workspace/apps/pidp/src/app/features/portal/state/access/access-group.model.ts @@ -11,9 +11,7 @@ export const accessSectionKeys = [ 'saEforms', 'prescription-refill-eforms', 'hcimAccountTransfer', - 'hcimEnrolment', 'immsBCEforms', - 'sitePrivacySecurityChecklist', 'driverFitness', 'msTeamsPrivacyOfficer', 'msTeamsClinicMember', @@ -41,9 +39,7 @@ export interface AccessGroup extends IAccessGroup { prescriptionRefillEforms: Section; bcProvider: Section; hcimAccountTransfer: Section; - hcimEnrolment: Section; immsBCEforms: Section; - sitePrivacySecurityChecklist: Section; driverFitness: Section; msTeamsPrivacyOfficer: Section; msTeamsClinicMember: Section; diff --git a/workspace/apps/pidp/src/app/features/portal/state/access/hcim-enrolment-portal-section.class.ts b/workspace/apps/pidp/src/app/features/portal/state/access/hcim-enrolment-portal-section.class.ts deleted file mode 100644 index e211572bc..000000000 --- a/workspace/apps/pidp/src/app/features/portal/state/access/hcim-enrolment-portal-section.class.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Router } from '@angular/router'; - -import { Observable } from 'rxjs'; - -import { AlertType } from '@bcgov/shared/ui'; - -import { AccessRoutes } from '@app/features/access/access.routes'; -import { ShellRoutes } from '@app/features/shell/shell.routes'; - -import { StatusCode } from '../../enums/status-code.enum'; -import { ProfileStatus } from '../../models/profile-status.model'; -import { PortalSectionAction } from '../portal-section-action.model'; -import { PortalSectionKey } from '../portal-section-key.type'; -import { IPortalSection } from '../portal-section.model'; - -export class HcimEnrolmentPortalSection implements IPortalSection { - public readonly key: PortalSectionKey; - public heading: string; - public description: string; - - public constructor( - private profileStatus: ProfileStatus, - private router: Router, - ) { - this.key = 'hcimEnrolment'; - this.heading = 'HCIMWeb Enrolment'; - this.description = `First time users enrol here for access to the HCIMWeb application.`; - } - - public get hint(): string { - return '3 minutes to complete'; - } - - /** - * @description - * Get the properties that define the action on the section. - */ - public get action(): PortalSectionAction { - const statusCode = this.getStatusCode(); - return { - label: statusCode === StatusCode.COMPLETED ? 'View' : 'Request', - route: AccessRoutes.routePath(AccessRoutes.HCIM_ENROLMENT), - disabled: statusCode === StatusCode.NOT_AVAILABLE, - }; - } - - public get statusType(): AlertType { - return this.getStatusCode() === StatusCode.COMPLETED ? 'success' : 'warn'; - } - - public get status(): string { - return this.getStatusCode() === StatusCode.COMPLETED - ? 'Completed' - : 'Incomplete'; - } - - public performAction(): void | Observable { - this.router.navigate([ShellRoutes.routePath(this.action.route)]); - } - - private getStatusCode(): StatusCode { - return this.profileStatus.status.hcimEnrolment.statusCode; - } -} diff --git a/workspace/apps/pidp/src/app/features/portal/state/access/site-privacy-security-checklist-portal-section.class.ts b/workspace/apps/pidp/src/app/features/portal/state/access/site-privacy-security-checklist-portal-section.class.ts deleted file mode 100644 index adbb8ca84..000000000 --- a/workspace/apps/pidp/src/app/features/portal/state/access/site-privacy-security-checklist-portal-section.class.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Router } from '@angular/router'; - -import { Observable } from 'rxjs'; - -import { AlertType } from '@bcgov/shared/ui'; - -import { AccessRoutes } from '@app/features/access/access.routes'; -import { ShellRoutes } from '@app/features/shell/shell.routes'; - -import { StatusCode } from '../../enums/status-code.enum'; -import { ProfileStatus } from '../../models/profile-status.model'; -import { PortalSectionAction } from '../portal-section-action.model'; -import { PortalSectionKey } from '../portal-section-key.type'; -import { IPortalSection } from '../portal-section.model'; - -export class SitePrivacySecurityPortalSection implements IPortalSection { - public readonly key: PortalSectionKey; - public heading: string; - public description: string; - - public constructor( - private profileStatus: ProfileStatus, - private router: Router, - ) { - this.key = 'sitePrivacySecurityChecklist'; - this.heading = 'Site Privacy and Security Readiness Checklist'; - this.description = 'Description of the checklist.'; - } - - public get hint(): string { - return '10 minutes to complete'; - } - - /** - * @description - * Get the properties that define the action on the section. - */ - public get action(): PortalSectionAction { - const demographicsStatusCode = - this.profileStatus.status.demographics.statusCode; - return { - label: this.getStatusCode() === StatusCode.COMPLETED ? 'View' : 'Update', - route: AccessRoutes.routePath( - AccessRoutes.SITE_PRIVACY_SECURITY_CHECKLIST, - ), - disabled: demographicsStatusCode !== StatusCode.COMPLETED, - }; - } - - public get statusType(): AlertType { - return this.getStatusCode() === StatusCode.COMPLETED ? 'success' : 'warn'; - } - - public get status(): string { - const statusCode = this.getStatusCode(); - return statusCode === StatusCode.COMPLETED ? 'Completed' : 'Incomplete'; - } - - public performAction(): Observable | void { - this.router.navigate([ShellRoutes.routePath(this.action.route)]); - } - - private getStatusCode(): StatusCode { - // TODO remove null check once API exists - return this.profileStatus.status.sitePrivacySecurityChecklist?.statusCode; - } -} diff --git a/workspace/apps/pidp/src/app/features/portal/state/organization/administrator-information-portal-section.spec.ts b/workspace/apps/pidp/src/app/features/portal/state/organization/administrator-information-portal-section.spec.ts deleted file mode 100644 index b4e716fa8..000000000 --- a/workspace/apps/pidp/src/app/features/portal/state/organization/administrator-information-portal-section.spec.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { Router } from '@angular/router'; - -import { MockProfileStatus } from '@test/mock-profile-status'; -import { provideAutoSpy } from 'jest-auto-spies'; - -import { StatusCode } from '../../enums/status-code.enum'; -import { ProfileStatus } from '../../models/profile-status.model'; -import { AdministratorInfoPortalSection } from './administrator-information-portal-section'; - -describe('AdministratorInfoPortalSection', () => { - let router: Router; - let mockProfileStatus: ProfileStatus; - let section: AdministratorInfoPortalSection; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [provideAutoSpy(Router)], - }); - - router = TestBed.inject(Router); - mockProfileStatus = MockProfileStatus.get(); - - section = new AdministratorInfoPortalSection(mockProfileStatus, router); - }); - - describe('INIT', () => { - given('default status and ProfileStatus', () => { - when('the class is instanciated', () => { - then('property are filled out', () => { - expect(section.key).toBe('facilityDetails'); - expect(section.heading).toBe('Administrator Information'); - expect(section.description).toBe( - `Provide your office administrator's contact information.`, - ); - }); - }); - }); - }); - - describe('PROPERTY: get hint', () => { - given('administratorInfo StatusCode is AVAILABLE', () => { - mockProfileStatus.status.administratorInfo.statusCode = - StatusCode.AVAILABLE; - when('the class is instanciated', () => { - then('hint should return a text', () => { - expect(section.hint).toBe('1 minute to complete'); - }); - }); - }); - - given('administratorInfo StatusCode is COMPLETED', () => { - mockProfileStatus.status.administratorInfo.statusCode = - StatusCode.COMPLETED; - when('the class is instanciated', () => { - then('hint should return an empty text', () => { - expect(section.hint).toBe(''); - }); - }); - }); - }); - - describe('PROPERTY: get properties', () => { - given('administratorInfo StatusCode is AVAILABLE', () => { - mockProfileStatus.status.administratorInfo.statusCode = - StatusCode.AVAILABLE; - when('the class is instanciated', () => { - then('properties should return an empty array', () => { - expect(section.properties).toStrictEqual([]); - }); - }); - }); - - given('administratorInfo StatusCode is COMPLETED', () => { - mockProfileStatus.status.administratorInfo.statusCode = - StatusCode.COMPLETED; - when('the class is instanciated', () => { - then('properties should return an array with 1 property', () => { - expect(section.properties).toStrictEqual([ - { - key: 'email', - value: mockProfileStatus.status.administratorInfo.email, - label: 'Access Administrator Email:', - }, - ]); - }); - }); - }); - }); - - describe('PROPERTY: get action', () => { - given('demographics StatusCode is AVAILABLE', () => { - mockProfileStatus.status.demographics.statusCode = StatusCode.AVAILABLE; - when('the class is instanciated', () => { - then( - 'action should return a PortalSectionAction object with disabled property set to true', - () => { - expect(section.action).toStrictEqual({ - label: 'Update', - route: '/organization-info/administrator-info', - disabled: true, - }); - }, - ); - }); - }); - - given('demographics StatusCode is COMPLETED', () => { - mockProfileStatus.status.demographics.statusCode = StatusCode.COMPLETED; - when('the class is instanciated', () => { - then( - 'action should return a PortalSectionAction object with disabled property set to false', - () => { - expect(section.action).toStrictEqual({ - label: 'Update', - route: '/organization-info/administrator-info', - disabled: false, - }); - }, - ); - }); - }); - }); - - describe('PROPERTY: get statusType', () => { - given('administratorInfo StatusCode is AVAILABLE', () => { - mockProfileStatus.status.administratorInfo.statusCode = - StatusCode.AVAILABLE; - when('the class is instanciated', () => { - then('should return a string "warn"', () => { - expect(section.statusType).toBe('warn'); - }); - }); - }); - - given('administratorInfo StatusCode is COMPLETED', () => { - mockProfileStatus.status.administratorInfo.statusCode = - StatusCode.COMPLETED; - when('the class is instanciated', () => { - then('should return a string "success"', () => { - expect(section.statusType).toBe('success'); - }); - }); - }); - - given('administratorInfo StatusCode is ERROR', () => { - mockProfileStatus.status.administratorInfo.statusCode = StatusCode.ERROR; - when('the class is instanciated', () => { - then('should return a string "danger"', () => { - expect(section.statusType).toBe('danger'); - }); - }); - }); - }); - - describe('PROPERTY: get status', () => { - given('administratorInfo StatusCode is AVAILABLE', () => { - mockProfileStatus.status.administratorInfo.statusCode = - StatusCode.AVAILABLE; - when('the class is instanciated', () => { - then('should return a string "Incomplete"', () => { - expect(section.status).toBe('Incomplete'); - }); - }); - }); - - given('administratorInfo StatusCode is COMPLETED', () => { - mockProfileStatus.status.administratorInfo.statusCode = - StatusCode.COMPLETED; - when('the class is instanciated', () => { - then('should return a string "Completed"', () => { - expect(section.status).toBe('Completed'); - }); - }); - }); - }); - - describe('METHOD: performAction', () => { - given('the class is instanciated', () => { - when('performAction function is called', () => { - section.performAction(); - then('the user navigate to administrator-info page', () => { - expect(router.navigate).toHaveBeenCalledWith([ - '///organization-info/administrator-info', - ]); - }); - }); - }); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/portal/state/organization/administrator-information-portal-section.ts b/workspace/apps/pidp/src/app/features/portal/state/organization/administrator-information-portal-section.ts deleted file mode 100644 index e7d164c6b..000000000 --- a/workspace/apps/pidp/src/app/features/portal/state/organization/administrator-information-portal-section.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Router } from '@angular/router'; - -import { Observable } from 'rxjs'; - -import { AlertType } from '@bcgov/shared/ui'; - -import { OrganizationInfoRoutes } from '@app/features/organization-info/organization-info.routes'; -import { ShellRoutes } from '@app/features/shell/shell.routes'; - -import { StatusCode } from '../../enums/status-code.enum'; -import { ProfileStatus } from '../../models/profile-status.model'; -import { PortalSectionAction } from '../portal-section-action.model'; -import { PortalSectionKey } from '../portal-section-key.type'; -import { PortalSectionProperty } from '../portal-section-property.model'; -import { IPortalSection } from '../portal-section.model'; -import { AdministratorInfoSection } from './administrator-information-section.model'; - -export class AdministratorInfoPortalSection implements IPortalSection { - public readonly key: PortalSectionKey; - public heading: string; - public description: string; - - public constructor( - private profileStatus: ProfileStatus, - private router: Router, - ) { - this.key = 'facilityDetails'; - this.heading = 'Administrator Information'; - this.description = `Provide your office administrator's contact information.`; - } - - public get hint(): string { - return [StatusCode.ERROR, StatusCode.COMPLETED].includes( - this.getStatusCode(), - ) - ? '' - : '1 minute to complete'; - } - - public get properties(): PortalSectionProperty[] { - const statusCode = this.getStatusCode(); - const { email } = this.getSectionStatus(); - return [StatusCode.ERROR, StatusCode.COMPLETED].includes(statusCode) - ? [ - { - key: 'email', - value: email, - label: 'Access Administrator Email:', - }, - ] - : []; - } - - /** - * @description - * Get the properties that define the action on the section. - */ - public get action(): PortalSectionAction { - const demographicsStatusCode = - this.profileStatus.status.demographics.statusCode; - return { - label: 'Update', - route: OrganizationInfoRoutes.routePath( - OrganizationInfoRoutes.ADMINISTRATOR_INFO, - ), - disabled: demographicsStatusCode !== StatusCode.COMPLETED, - }; - } - - public get statusType(): AlertType { - const statusCode = this.getStatusCode(); - return statusCode === StatusCode.ERROR - ? 'danger' - : statusCode === StatusCode.COMPLETED - ? 'success' - : 'warn'; - } - - public get status(): string { - const statusCode = this.getStatusCode(); - return statusCode === StatusCode.COMPLETED ? 'Completed' : 'Incomplete'; - } - - public performAction(): void | Observable { - this.router.navigate([ShellRoutes.routePath(this.action.route)]); - } - - private getSectionStatus(): AdministratorInfoSection { - return this.profileStatus.status.administratorInfo; - } - - private getStatusCode(): StatusCode { - return this.getSectionStatus().statusCode; - } -} diff --git a/workspace/apps/pidp/src/app/features/portal/state/organization/administrator-information-section.model.ts b/workspace/apps/pidp/src/app/features/portal/state/organization/administrator-information-section.model.ts deleted file mode 100644 index cb4b65613..000000000 --- a/workspace/apps/pidp/src/app/features/portal/state/organization/administrator-information-section.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Section } from '../section.model'; - -export interface AdministratorInfoSection extends Section { - email: string; -} diff --git a/workspace/apps/pidp/src/app/features/portal/state/organization/facility-details-portal-section.class.spec.ts b/workspace/apps/pidp/src/app/features/portal/state/organization/facility-details-portal-section.class.spec.ts deleted file mode 100644 index bc81ca22c..000000000 --- a/workspace/apps/pidp/src/app/features/portal/state/organization/facility-details-portal-section.class.spec.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { Router } from '@angular/router'; - -import { MockProfileStatus } from '@test/mock-profile-status'; -import { provideAutoSpy } from 'jest-auto-spies'; - -import { StatusCode } from '../../enums/status-code.enum'; -import { ProfileStatus } from '../../models/profile-status.model'; -import { FacilityDetailsPortalSection } from './facility-details-portal-section.class'; - -describe('FacilityDetailsPortalSection', () => { - let router: Router; - let mockProfileStatus: ProfileStatus; - let section: FacilityDetailsPortalSection; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [provideAutoSpy(Router)], - }); - - router = TestBed.inject(Router); - mockProfileStatus = MockProfileStatus.get(); - - section = new FacilityDetailsPortalSection(mockProfileStatus, router); - }); - - describe('INIT', () => { - given('default status and ProfileStatus', () => { - when('the class is instanciated', () => { - then('property are filled out', () => { - expect(section.key).toBe('facilityDetails'); - expect(section.heading).toBe('Facility Details'); - expect(section.description).toBe( - `Provide details about your work place (facility).`, - ); - }); - }); - }); - }); - - describe('PROPERTY: get hint', () => { - given('facilityDetails StatusCode is AVAILABLE', () => { - mockProfileStatus.status.facilityDetails.statusCode = - StatusCode.AVAILABLE; - when('the class is instanciated', () => { - then('hint should return a text', () => { - expect(section.hint).toBe('2 minutes to complete'); - }); - }); - }); - - given('facilityDetails StatusCode is COMPLETED', () => { - mockProfileStatus.status.facilityDetails.statusCode = - StatusCode.COMPLETED; - when('the class is instanciated', () => { - then('hint should return an empty text', () => { - expect(section.hint).toBe(''); - }); - }); - }); - }); - - describe('PROPERTY: get action', () => { - given('demographics StatusCode is AVAILABLE', () => { - mockProfileStatus.status.demographics.statusCode = StatusCode.AVAILABLE; - when('the class is instanciated', () => { - then( - 'action should return a PortalSectionAction object with disabled property set to true', - () => { - expect(section.action).toStrictEqual({ - label: 'Update', - route: '/organization-info/facility-details', - disabled: true, - }); - }, - ); - }); - }); - - given('demographics StatusCode is COMPLETED', () => { - mockProfileStatus.status.demographics.statusCode = StatusCode.COMPLETED; - when('the class is instanciated', () => { - then( - 'action should return a PortalSectionAction object with disabled property set to false', - () => { - expect(section.action).toStrictEqual({ - label: 'Update', - route: '/organization-info/facility-details', - disabled: false, - }); - }, - ); - }); - }); - }); - - describe('PROPERTY: get statusType', () => { - given('facilityDetails StatusCode is AVAILABLE', () => { - mockProfileStatus.status.facilityDetails.statusCode = - StatusCode.AVAILABLE; - when('the class is instanciated', () => { - then('should return a string "warn"', () => { - expect(section.statusType).toBe('warn'); - }); - }); - }); - - given('facilityDetails StatusCode is COMPLETED', () => { - mockProfileStatus.status.facilityDetails.statusCode = - StatusCode.COMPLETED; - when('the class is instanciated', () => { - then('should return a string "success"', () => { - expect(section.statusType).toBe('success'); - }); - }); - }); - - given('facilityDetails StatusCode is ERROR', () => { - mockProfileStatus.status.facilityDetails.statusCode = StatusCode.ERROR; - when('the class is instanciated', () => { - then('should return a string "danger"', () => { - expect(section.statusType).toBe('danger'); - }); - }); - }); - }); - - describe('PROPERTY: get status', () => { - given('facilityDetails StatusCode is AVAILABLE', () => { - mockProfileStatus.status.facilityDetails.statusCode = - StatusCode.AVAILABLE; - when('the class is instanciated', () => { - then('should return a string "Incomplete"', () => { - expect(section.status).toBe('Incomplete'); - }); - }); - }); - - given('facilityDetails StatusCode is COMPLETED', () => { - mockProfileStatus.status.facilityDetails.statusCode = - StatusCode.COMPLETED; - when('the class is instanciated', () => { - then('should return a string "Completed"', () => { - expect(section.status).toBe('Completed'); - }); - }); - }); - }); - - describe('METHOD: performAction', () => { - given('the class is instanciated', () => { - when('performAction function is called', () => { - section.performAction(); - then('the user navigate to facility-details page', () => { - expect(router.navigate).toHaveBeenCalledWith([ - '///organization-info/facility-details', - ]); - }); - }); - }); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/portal/state/organization/facility-details-portal-section.class.ts b/workspace/apps/pidp/src/app/features/portal/state/organization/facility-details-portal-section.class.ts deleted file mode 100644 index 99e21b192..000000000 --- a/workspace/apps/pidp/src/app/features/portal/state/organization/facility-details-portal-section.class.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Router } from '@angular/router'; - -import { Observable } from 'rxjs'; - -import { AlertType } from '@bcgov/shared/ui'; - -import { OrganizationInfoRoutes } from '@app/features/organization-info/organization-info.routes'; -import { ShellRoutes } from '@app/features/shell/shell.routes'; - -import { StatusCode } from '../../enums/status-code.enum'; -import { ProfileStatus } from '../../models/profile-status.model'; -import { PortalSectionAction } from '../portal-section-action.model'; -import { PortalSectionKey } from '../portal-section-key.type'; -import { IPortalSection } from '../portal-section.model'; - -export class FacilityDetailsPortalSection implements IPortalSection { - public readonly key: PortalSectionKey; - public heading: string; - public description: string; - - public constructor( - private profileStatus: ProfileStatus, - private router: Router, - ) { - this.key = 'facilityDetails'; - this.heading = 'Facility Details'; - this.description = 'Provide details about your work place (facility).'; - } - - public get hint(): string { - return [StatusCode.ERROR, StatusCode.COMPLETED].includes( - this.getStatusCode(), - ) - ? '' - : '2 minutes to complete'; - } - - /** - * @description - * Get the properties that define the action on the section. - */ - public get action(): PortalSectionAction { - const demographicsStatusCode = - this.profileStatus.status.demographics.statusCode; - return { - label: 'Update', - route: OrganizationInfoRoutes.routePath( - OrganizationInfoRoutes.FACILITY_DETAILS, - ), - disabled: demographicsStatusCode !== StatusCode.COMPLETED, - }; - } - - public get statusType(): AlertType { - const statusCode = this.getStatusCode(); - return statusCode === StatusCode.ERROR - ? 'danger' - : statusCode === StatusCode.COMPLETED - ? 'success' - : 'warn'; - } - - public get status(): string { - const statusCode = this.getStatusCode(); - return statusCode === StatusCode.COMPLETED ? 'Completed' : 'Incomplete'; - } - - public performAction(): void | Observable { - this.router.navigate([ShellRoutes.routePath(this.action.route)]); - } - - private getStatusCode(): StatusCode { - // TODO remove null check once API exists - return this.profileStatus.status.facilityDetails?.statusCode; - } -} diff --git a/workspace/apps/pidp/src/app/features/portal/state/organization/organization-details-portal-section.class.spec.ts b/workspace/apps/pidp/src/app/features/portal/state/organization/organization-details-portal-section.class.spec.ts deleted file mode 100644 index 50b1068f2..000000000 --- a/workspace/apps/pidp/src/app/features/portal/state/organization/organization-details-portal-section.class.spec.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { Router } from '@angular/router'; - -import { MockProfileStatus } from '@test/mock-profile-status'; -import { provideAutoSpy } from 'jest-auto-spies'; - -import { StatusCode } from '../../enums/status-code.enum'; -import { ProfileStatus } from '../../models/profile-status.model'; -import { OrganizationDetailsPortalSection } from './organization-details-portal-section.class'; - -describe('OrganizationDetailsPortalSection', () => { - let router: Router; - let mockProfileStatus: ProfileStatus; - let section: OrganizationDetailsPortalSection; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [provideAutoSpy(Router)], - }); - - router = TestBed.inject(Router); - mockProfileStatus = MockProfileStatus.get(); - - section = new OrganizationDetailsPortalSection(mockProfileStatus, router); - }); - - describe('INIT', () => { - given('default status and ProfileStatus', () => { - when('the class is instanciated', () => { - then('property are filled out', () => { - expect(section.key).toBe('organizationDetails'); - expect(section.heading).toBe('Organization Details'); - expect(section.description).toBe( - `Provide details about your organization.`, - ); - }); - }); - }); - }); - - describe('PROPERTY: get hint', () => { - given('organizationDetails StatusCode is AVAILABLE', () => { - mockProfileStatus.status.organizationDetails.statusCode = - StatusCode.AVAILABLE; - when('the class is instanciated', () => { - then('hint should return a text', () => { - expect(section.hint).toBe('2 minutes to complete'); - }); - }); - }); - - given('organizationDetails StatusCode is COMPLETED', () => { - mockProfileStatus.status.organizationDetails.statusCode = - StatusCode.COMPLETED; - when('the class is instanciated', () => { - then('hint should return an empty text', () => { - expect(section.hint).toBe(''); - }); - }); - }); - }); - - describe('PROPERTY: get action', () => { - given('demographics StatusCode is AVAILABLE', () => { - mockProfileStatus.status.demographics.statusCode = StatusCode.AVAILABLE; - when('the class is instanciated', () => { - then( - 'action should return a PortalSectionAction object with disabled property set to true', - () => { - expect(section.action).toStrictEqual({ - label: 'Update', - route: '/organization-info/organization-details', - disabled: true, - }); - }, - ); - }); - }); - - given('demographics StatusCode is COMPLETED', () => { - mockProfileStatus.status.demographics.statusCode = StatusCode.COMPLETED; - when('the class is instanciated', () => { - then( - 'action should return a PortalSectionAction object with disabled property set to false', - () => { - expect(section.action).toStrictEqual({ - label: 'Update', - route: '/organization-info/organization-details', - disabled: false, - }); - }, - ); - }); - }); - }); - - describe('PROPERTY: get statusType', () => { - given('organizationDetails StatusCode is AVAILABLE', () => { - mockProfileStatus.status.organizationDetails.statusCode = - StatusCode.AVAILABLE; - when('the class is instanciated', () => { - then('should return a string "warn"', () => { - expect(section.statusType).toBe('warn'); - }); - }); - }); - - given('organizationDetails StatusCode is COMPLETED', () => { - mockProfileStatus.status.organizationDetails.statusCode = - StatusCode.COMPLETED; - when('the class is instanciated', () => { - then('should return a string "success"', () => { - expect(section.statusType).toBe('success'); - }); - }); - }); - - given('organizationDetails StatusCode is ERROR', () => { - mockProfileStatus.status.organizationDetails.statusCode = - StatusCode.ERROR; - when('the class is instanciated', () => { - then('should return a string "danger"', () => { - expect(section.statusType).toBe('danger'); - }); - }); - }); - }); - - describe('PROPERTY: get status', () => { - given('organizationDetails StatusCode is AVAILABLE', () => { - mockProfileStatus.status.organizationDetails.statusCode = - StatusCode.AVAILABLE; - when('the class is instanciated', () => { - then('should return a string "Incomplete"', () => { - expect(section.status).toBe('Incomplete'); - }); - }); - }); - - given('organizationDetails StatusCode is COMPLETED', () => { - mockProfileStatus.status.organizationDetails.statusCode = - StatusCode.COMPLETED; - when('the class is instanciated', () => { - then('should return a string "Completed"', () => { - expect(section.status).toBe('Completed'); - }); - }); - }); - }); - - describe('METHOD: performAction', () => { - given('the class is instanciated', () => { - when('performAction function is called', () => { - section.performAction(); - then('the user navigate to organization-details page', () => { - expect(router.navigate).toHaveBeenCalledWith([ - '///organization-info/organization-details', - ]); - }); - }); - }); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/portal/state/organization/organization-details-portal-section.class.ts b/workspace/apps/pidp/src/app/features/portal/state/organization/organization-details-portal-section.class.ts deleted file mode 100644 index 730e7c85a..000000000 --- a/workspace/apps/pidp/src/app/features/portal/state/organization/organization-details-portal-section.class.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Router } from '@angular/router'; - -import { Observable } from 'rxjs'; - -import { AlertType } from '@bcgov/shared/ui'; - -import { OrganizationInfoRoutes } from '@app/features/organization-info/organization-info.routes'; -import { ShellRoutes } from '@app/features/shell/shell.routes'; - -import { StatusCode } from '../../enums/status-code.enum'; -import { ProfileStatus } from '../../models/profile-status.model'; -import { PortalSectionAction } from '../portal-section-action.model'; -import { PortalSectionKey } from '../portal-section-key.type'; -import { IPortalSection } from '../portal-section.model'; - -export class OrganizationDetailsPortalSection implements IPortalSection { - public readonly key: PortalSectionKey; - public heading: string; - public description: string; - - public constructor( - private profileStatus: ProfileStatus, - private router: Router, - ) { - this.key = 'organizationDetails'; - this.heading = 'Organization Details'; - this.description = 'Provide details about your organization.'; - } - - public get hint(): string { - return [StatusCode.ERROR, StatusCode.COMPLETED].includes( - this.getStatusCode(), - ) - ? '' - : '2 minutes to complete'; - } - - /** - * @description - * Get the properties that define the action on the section. - */ - public get action(): PortalSectionAction { - const demographicsStatusCode = - this.profileStatus.status.demographics.statusCode; - return { - label: 'Update', - route: OrganizationInfoRoutes.routePath( - OrganizationInfoRoutes.ORGANIZATION_DETAILS, - ), - disabled: demographicsStatusCode !== StatusCode.COMPLETED, - }; - } - - public get statusType(): AlertType { - const statusCode = this.getStatusCode(); - return statusCode === StatusCode.ERROR - ? 'danger' - : statusCode === StatusCode.COMPLETED - ? 'success' - : 'warn'; - } - - public get status(): string { - const statusCode = this.getStatusCode(); - return statusCode === StatusCode.COMPLETED ? 'Completed' : 'Incomplete'; - } - - public performAction(): void | Observable { - this.router.navigate([ShellRoutes.routePath(this.action.route)]); - } - - private getStatusCode(): StatusCode { - // TODO remove null check once API exists - return this.profileStatus.status.organizationDetails?.statusCode; - } -} diff --git a/workspace/apps/pidp/src/app/features/portal/state/organization/organization-group.model.ts b/workspace/apps/pidp/src/app/features/portal/state/organization/organization-group.model.ts index 7d60a6347..c5f621b07 100644 --- a/workspace/apps/pidp/src/app/features/portal/state/organization/organization-group.model.ts +++ b/workspace/apps/pidp/src/app/features/portal/state/organization/organization-group.model.ts @@ -1,5 +1,4 @@ import { Section } from '../section.model'; -import { AdministratorInfoSection } from './administrator-information-section.model'; /** * @description @@ -7,12 +6,7 @@ import { AdministratorInfoSection } from './administrator-information-section.mo * over keys at runtime to allow filtering or grouping * sections. */ -export const organizationSectionKeys = [ - 'organizationDetails', - 'facilityDetails', - 'administratorInfo', - 'endorsements', -] as const; +export const organizationSectionKeys = ['endorsements'] as const; /** * @description @@ -29,8 +23,5 @@ export type IOrganizationGroup = { }; export interface OrganizationGroup extends IOrganizationGroup { - organizationDetails: Section; - facilityDetails: Section; - administratorInfo: AdministratorInfoSection; endorsements: Section; } diff --git a/workspace/apps/pidp/src/app/features/portal/state/portal-state.builder.ts b/workspace/apps/pidp/src/app/features/portal/state/portal-state.builder.ts index ec85ee4c0..04975df78 100644 --- a/workspace/apps/pidp/src/app/features/portal/state/portal-state.builder.ts +++ b/workspace/apps/pidp/src/app/features/portal/state/portal-state.builder.ts @@ -11,7 +11,6 @@ import { BcProviderPortalSection } from './access/bc-provider-portal-section.cla import { DriverFitnessPortalSection } from './access/driver-fitness-portal-section.class'; import { EdrdEformsPortalSection } from './access/edrd-eforms-portal-section.class'; import { HcimAccountTransferPortalSection } from './access/hcim-account-transfer-portal-section.class'; -import { HcimEnrolmentPortalSection } from './access/hcim-enrolment-portal-section.class'; import { ImmsBCEformsPortalSection } from './access/immsbc-eforms-portal-section.class'; import { MsTeamsClinicMemberPortalSection } from './access/ms-teams-clinic-member-portal-section.class'; import { MsTeamsPrivacyOfficerPortalSection } from './access/ms-teams-privacy-officer-portal-section.class'; @@ -19,14 +18,10 @@ import { PrescriptionRefillEformsPortalSection } from './access/prescription-ref import { PrimaryCareRosteringPortalSection } from './access/primary-care-rostering-portal-section.class'; import { ProviderReportingPortalSection } from './access/provider-reporting-portal-section.class'; import { SaEformsPortalSection } from './access/sa-eforms-portal-section.class'; -import { SitePrivacySecurityPortalSection } from './access/site-privacy-security-checklist-portal-section.class'; import { MfaSetupPortalSection } from './faq/mfa-setup-portal-section.class'; import { SignedAcceptedDocumentsPortalSection } from './history/signed-accepted-documents-portal-section.class'; import { TransactionsPortalSection } from './history/transactions-portal-section.class'; -import { AdministratorInfoPortalSection } from './organization/administrator-information-portal-section'; import { EndorsementsPortalSection } from './organization/endorsements-portal-section.class'; -import { FacilityDetailsPortalSection } from './organization/facility-details-portal-section.class'; -import { OrganizationDetailsPortalSection } from './organization/organization-details-portal-section.class'; import { PortalSectionStatusKey } from './portal-section-status-key.type'; import { IPortalSection } from './portal-section.model'; import { CollegeCertificationPortalSection } from './profile/college-certification-portal-section.class'; @@ -107,27 +102,6 @@ export class PortalStateBuilder { profileStatus: ProfileStatus, ): IPortalSection[] { return [ - ...ArrayUtils.insertResultIf( - // TODO remove permissions when ready for production - this.insertSection('organizationDetails', profileStatus) && - this.permissionsService.hasRole([Role.FEATURE_PIDP_DEMO]), - () => [ - new OrganizationDetailsPortalSection(profileStatus, this.router), - ], - ), - ...ArrayUtils.insertResultIf( - // TODO add insertSection call when it exists in the ProfileStatus API - // TODO remove permissions when ready for production - // this.insertSection('facilityDetails', profileStatus) && - this.permissionsService.hasRole([Role.FEATURE_PIDP_DEMO]), - () => [new FacilityDetailsPortalSection(profileStatus, this.router)], - ), - ...ArrayUtils.insertResultIf( - // TODO remove permissions when ready for production - this.insertSection('administratorInfo', profileStatus) && - this.permissionsService.hasRole([Role.FEATURE_PIDP_DEMO]), - () => [new AdministratorInfoPortalSection(profileStatus, this.router)], - ), ...ArrayUtils.insertResultIf( this.insertSection('endorsements', profileStatus), () => [new EndorsementsPortalSection(profileStatus, this.router)], @@ -157,21 +131,6 @@ export class PortalStateBuilder { new HcimAccountTransferPortalSection(profileStatus, this.router), ], ), - ...ArrayUtils.insertResultIf( - // TODO remove permissions when ready for production - this.insertSection('hcimEnrolment', profileStatus) && - this.permissionsService.hasRole([Role.FEATURE_PIDP_DEMO]), - () => [new HcimEnrolmentPortalSection(profileStatus, this.router)], - ), - ...ArrayUtils.insertResultIf( - // TODO add insertSection call when it exists in the ProfileStatus API - // TODO remove permissions when ready for production - // this.insertSection('sitePrivacySecurityChecklist', profileStatus) && - this.permissionsService.hasRole([Role.FEATURE_PIDP_DEMO]), - () => [ - new SitePrivacySecurityPortalSection(profileStatus, this.router), - ], - ), ...ArrayUtils.insertResultIf( this.insertSection('driverFitness', profileStatus), () => [new DriverFitnessPortalSection(profileStatus, this.router)], diff --git a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information-form-state.ts b/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information-form-state.ts deleted file mode 100644 index b5ff467ab..000000000 --- a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information-form-state.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; - -import { AbstractFormState } from '@bcgov/shared/ui'; - -import { FormUtilsService } from '@app/core/services/form-utils.service'; - -import { WorkAndRoleInformation } from './work-and-role-information.model'; - -export class WorkAndRoleInformationFormState extends AbstractFormState { - public constructor( - private fb: FormBuilder, - private formUtilsService: FormUtilsService, - ) { - super(); - - this.buildForm(); - } - - public get facilityAddress(): FormGroup { - return this.form.get('facilityAddress') as FormGroup; - } - - public get json(): WorkAndRoleInformation | undefined { - if (!this.formInstance) { - return; - } - - return this.formInstance.getRawValue(); - } - - public patchValue(model: WorkAndRoleInformation | null): void { - if (!this.formInstance || !model) { - return; - } - - this.formInstance.patchValue(model); - } - - public buildForm(): void { - this.formInstance = this.fb.group({ - jobTitle: ['', [Validators.required]], - facilityName: ['', [Validators.required]], - facilityAddress: this.formUtilsService.buildAddressForm({ - areRequired: true, - }), - }); - } -} diff --git a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information-resource.service.spec.ts b/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information-resource.service.spec.ts deleted file mode 100644 index 379343e05..000000000 --- a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information-resource.service.spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { provideAutoSpy } from 'jest-auto-spies'; - -import { ApiHttpClient } from '@app/core/resources/api-http-client.service'; -import { ToastService } from '@app/core/services/toast.service'; - -import { WorkAndRoleInformationResource } from './work-and-role-information-resource.service'; - -describe('WorkAndRoleInformationResource', () => { - let service: WorkAndRoleInformationResource; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [ - WorkAndRoleInformationResource, - provideAutoSpy(ApiHttpClient), - provideAutoSpy(ToastService), - ], - }); - - service = TestBed.inject(WorkAndRoleInformationResource); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information-resource.service.ts b/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information-resource.service.ts deleted file mode 100644 index 9b64eeae1..000000000 --- a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information-resource.service.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { HttpErrorResponse } from '@angular/common/http'; -import { Injectable } from '@angular/core'; - -import { catchError, tap, throwError } from 'rxjs'; - -import { CrudResource, NoContent } from '@bcgov/shared/data-access'; - -import { ApiHttpClient } from '@app/core/resources/api-http-client.service'; - -import { ToastService } from '@core/services/toast.service'; - -import { WorkAndRoleInformation } from './work-and-role-information.model'; - -@Injectable() -export class WorkAndRoleInformationResource extends CrudResource { - public constructor( - protected apiResource: ApiHttpClient, - private toastService: ToastService, - ) { - super(apiResource); - } - - public update(id: number, payload: WorkAndRoleInformation): NoContent { - return super.update(id, payload).pipe( - tap(() => - this.toastService.openSuccessToast( - 'College licence information has been updated', - ), - ), - catchError((error: HttpErrorResponse) => { - this.toastService.openErrorToast( - 'College licence information could not be updated', - ); - return throwError(() => error); - }), - ); - } - - protected getResourcePath(partyId: number): string { - return `parties/${partyId}/work-setting`; - } -} diff --git a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information-routing.routes.ts b/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information-routing.routes.ts deleted file mode 100644 index c744a7b41..000000000 --- a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information-routing.routes.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Routes } from '@angular/router'; - -import { canDeactivateFormGuard } from '@app/core/guards/can-deactivate-form.guard'; - -import { WorkAndRoleInformationPage } from './work-and-role-information.page'; - -export const routes: Routes = [ - { - path: '', - component: WorkAndRoleInformationPage, - canDeactivate: [canDeactivateFormGuard], - data: { - title: 'OneHealthID Service', - routes: { - root: '../../', - }, - setDashboardTitleGuard: { - titleText: 'Welcome to OneHealthID Service', - titleDescriptionText: - 'Complete your profile to gain access to the systems you are eligible for', - }, - }, - }, -]; diff --git a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.model.ts b/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.model.ts deleted file mode 100644 index d7db97da9..000000000 --- a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.model.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Facility, Party } from '@bcgov/shared/data-access'; - -export interface WorkAndRoleInformation - extends Pick, - Pick {} diff --git a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.page.html b/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.page.html deleted file mode 100644 index 373e246ec..000000000 --- a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.page.html +++ /dev/null @@ -1,83 +0,0 @@ - - {{ title }} - - - - - Provide your work and role information for every facility you work for. - - - - - - - - - Identify your job title(s). - - - -
-
- - Job Title - - Type in your job title - -
-
-
- - - - - Provide the following information. - - - -
-
- - Facility Name - - Type your Facility Name - Required - -
-
-
- - - - - Provide your work address. - - - - - -
- - - - - -
diff --git a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.page.scss b/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.page.scss deleted file mode 100644 index 1c648132a..000000000 --- a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.page.scss +++ /dev/null @@ -1,13 +0,0 @@ -.viewport-all { - --gap: 1rem; -} - -.viewport-small, -.viewport-medium, -.viewport-large { - --gap: 1.25rem; -} - -.row > div.col-12:not(:last-child) { - margin-bottom: 1.75rem; -} diff --git a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.page.spec.ts b/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.page.spec.ts deleted file mode 100644 index f569b1fbd..000000000 --- a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.page.spec.ts +++ /dev/null @@ -1,170 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { HttpStatusCode } from '@angular/common/http'; -import { TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatDialogModule } from '@angular/material/dialog'; -import { ActivatedRoute, Router } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { - randCity, - randCountryCode, - randNumber, - randStateAbbr, - randStreetAddress, - randTextRange, - randZipCode, -} from '@ngneat/falso'; -import { Spy, createSpyFromClass, provideAutoSpy } from 'jest-auto-spies'; - -import { APP_CONFIG, APP_DI_CONFIG } from '@app/app.config'; -import { PartyService } from '@app/core/party/party.service'; -import { FormUtilsService } from '@app/core/services/form-utils.service'; -import { LoggerService } from '@app/core/services/logger.service'; - -import { WorkAndRoleInformationResource } from './work-and-role-information-resource.service'; -import { WorkAndRoleInformation } from './work-and-role-information.model'; -import { WorkAndRoleInformationPage } from './work-and-role-information.page'; - -describe('WorkAndRoleInformationPage', () => { - let component: WorkAndRoleInformationPage; - let partyServiceSpy: Spy; - let workAndRoleInformationResourceSpy: Spy; - let router: Router; - - let mockActivatedRoute: { snapshot: any }; - let mockForm: Pick; - let mockParty: WorkAndRoleInformation; - - beforeEach(() => { - mockActivatedRoute = { - snapshot: { - data: { - title: randTextRange({ min: 1, max: 4 }), - routes: { - root: '../../', - }, - }, - }, - }; - - TestBed.configureTestingModule({ - imports: [MatDialogModule, ReactiveFormsModule, RouterTestingModule], - providers: [ - WorkAndRoleInformationPage, - { - provide: APP_CONFIG, - useValue: APP_DI_CONFIG, - }, - { - provide: ActivatedRoute, - useValue: mockActivatedRoute, - }, - { - provide: PartyService, - useValue: createSpyFromClass(PartyService, { - gettersToSpyOn: ['partyId'], - settersToSpyOn: ['partyId'], - }), - }, - provideAutoSpy(WorkAndRoleInformationResource), - provideAutoSpy(FormUtilsService), - provideAutoSpy(LoggerService), - provideAutoSpy(Router), - ], - }); - - component = TestBed.inject(WorkAndRoleInformationPage); - partyServiceSpy = TestBed.inject(PartyService); - workAndRoleInformationResourceSpy = TestBed.inject( - WorkAndRoleInformationResource, - ); - router = TestBed.inject(Router); - - mockForm = { - jobTitle: randTextRange({ min: 4, max: 15 }), - facilityName: randTextRange({ min: 4, max: 15 }), - }; - - mockParty = { - facilityAddress: { - countryCode: randCountryCode(), - provinceCode: randStateAbbr(), - street: randStreetAddress(), - city: randCity(), - postal: randZipCode(), - }, - ...mockForm, - }; - }); - - describe('INIT', () => { - given('partyId exists', () => { - const partyId = randNumber({ min: 1 }); - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - workAndRoleInformationResourceSpy.get.nextOneTimeWith(mockParty); - - when('resource request resolved', () => { - component.ngOnInit(); - - then('it should GET party work and role information', () => { - expect(router.navigate).not.toHaveBeenCalled(); - expect(workAndRoleInformationResourceSpy.get).toHaveBeenCalledTimes( - 1, - ); - expect(workAndRoleInformationResourceSpy.get).toHaveBeenCalledWith( - partyId, - ); - }); - }); - }); - - given('partyId exists', () => { - const partyId = randNumber({ min: 1 }); - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - workAndRoleInformationResourceSpy.get.nextWithValues([ - { - errorValue: { - status: HttpStatusCode.NotFound, - }, - }, - ]); - - when('resource request rejected', () => { - component.ngOnInit(); - - then('router should navigate to root route', () => { - const rootRoute = mockActivatedRoute.snapshot.data.routes.root; - expect(router.navigate).toHaveBeenCalledWith([rootRoute]); - }); - }); - }); - - given('partyId does not exist', () => { - const partyId = null; - partyServiceSpy.accessorSpies.getters.partyId.mockReturnValue(partyId); - - when('initializing the component', () => { - component.ngOnInit(); - - then('router should navigate to root route', () => { - const rootRoute = mockActivatedRoute.snapshot.data.routes.root; - expect(router.navigate).toHaveBeenCalledWith([rootRoute]); - }); - }); - }); - }); - - describe('METHOD: onBack', () => { - given('user wants to go back to the previous page', () => { - when('onBack is invoked', () => { - component.onBack(); - - then('router should navigate to root route', () => { - const rootRoute = mockActivatedRoute.snapshot.data.routes.root; - expect(router.navigate).toHaveBeenCalledWith([rootRoute]); - }); - }); - }); - }); -}); diff --git a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.page.ts b/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.page.ts deleted file mode 100644 index 98dc82228..000000000 --- a/workspace/apps/pidp/src/app/features/profile/pages/work-and-role-information/work-and-role-information.page.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { FormBuilder, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonModule } from '@angular/material/button'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { ActivatedRoute, Router } from '@angular/router'; - -import { EMPTY, Observable, catchError, of, tap } from 'rxjs'; - -import { - InjectViewportCssClassDirective, - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, -} from '@bcgov/shared/ui'; - -import { PartyService } from '@app/core/party/party.service'; -import { LoggerService } from '@app/core/services/logger.service'; -import { AddressFormComponent } from '@app/shared/components/address-form/address-form.component'; - -import { - AbstractFormDependenciesService, - AbstractFormPage, -} from '@core/classes/abstract-form-page.class'; - -import { WorkAndRoleInformationFormState } from './work-and-role-information-form-state'; -import { WorkAndRoleInformationResource } from './work-and-role-information-resource.service'; -import { WorkAndRoleInformation } from './work-and-role-information.model'; - -@Component({ - selector: 'app-work-and-role-information', - templateUrl: './work-and-role-information.page.html', - styleUrls: ['./work-and-role-information.page.scss'], - viewProviders: [WorkAndRoleInformationResource], - standalone: true, - imports: [ - AddressFormComponent, - InjectViewportCssClassDirective, - MatButtonModule, - MatFormFieldModule, - MatInputModule, - PageComponent, - PageFooterActionDirective, - PageFooterComponent, - PageHeaderComponent, - PageSectionComponent, - PageSectionSubheaderComponent, - PageSectionSubheaderDescDirective, - ReactiveFormsModule, - ], -}) -export class WorkAndRoleInformationPage - extends AbstractFormPage - implements OnInit -{ - public title: string; - public formState: WorkAndRoleInformationFormState; - public hasFacilityAddress: boolean; - - // ui-page is handling this. - public showOverlayOnSubmit = false; - - public constructor( - private route: ActivatedRoute, - private router: Router, - private partyService: PartyService, - private resource: WorkAndRoleInformationResource, - private logger: LoggerService, - fb: FormBuilder, - dependenciesService: AbstractFormDependenciesService, - ) { - super(dependenciesService); - - this.title = this.route.snapshot.data.title; - this.formState = new WorkAndRoleInformationFormState( - fb, - dependenciesService.formUtilsService, - ); - this.hasFacilityAddress = false; - } - - public onBack(): void { - this.navigateToRoot(); - } - - public ngOnInit(): void { - const partyId = this.partyService.partyId; - if (!partyId) { - this.logger.error('No party ID was provided'); - return this.navigateToRoot(); - } - - this.resource - .get(partyId) - .pipe( - tap((model: WorkAndRoleInformation | null) => - this.formState.patchValue(model), - ), - catchError((error: HttpErrorResponse) => { - if (error.status === HttpStatusCode.NotFound) { - this.navigateToRoot(); - } - return of(null); - }), - ) - .subscribe( - (model: WorkAndRoleInformation | null) => - (this.hasFacilityAddress = !!model?.facilityAddress), - ); - } - - protected performSubmission(): Observable { - const partyId = this.partyService.partyId; - - return partyId && this.formState.json - ? this.resource.update(partyId, this.formState.json) - : EMPTY; - } - - protected afterSubmitIsSuccessful(): void { - this.navigateToRoot(); - } - - private navigateToRoot(): void { - this.router.navigate([this.route.snapshot.data.routes.root]); - } -} diff --git a/workspace/apps/pidp/src/app/features/profile/profile-routing.routes.ts b/workspace/apps/pidp/src/app/features/profile/profile-routing.routes.ts index d7f2e30ef..7df907b9c 100644 --- a/workspace/apps/pidp/src/app/features/profile/profile-routing.routes.ts +++ b/workspace/apps/pidp/src/app/features/profile/profile-routing.routes.ts @@ -1,8 +1,5 @@ import { Routes } from '@angular/router'; -import { PermissionsGuard } from '@app/modules/permissions/permissions.guard'; -import { Role } from '@app/shared/enums/roles.enum'; - import { ProfileRoutes } from './profile.routes'; export const routes: Routes = [ @@ -20,17 +17,6 @@ export const routes: Routes = [ './pages/college-licence/college-licence-declaration/college-licence-declaration-routing.routes' ).then((m) => m.routes), }, - { - path: ProfileRoutes.WORK_AND_ROLE_INFO, - canMatch: [PermissionsGuard.canMatch], - data: { - roles: [Role.FEATURE_PIDP_DEMO], - }, - loadChildren: (): Promise => - import( - './pages/work-and-role-information/work-and-role-information-routing.routes' - ).then((m) => m.routes), - }, { path: ProfileRoutes.USER_ACCESS_AGREEMENT, loadChildren: (): Promise => diff --git a/workspace/apps/pidp/src/app/features/profile/profile.routes.ts b/workspace/apps/pidp/src/app/features/profile/profile.routes.ts index 0a9525bc9..377b7002e 100644 --- a/workspace/apps/pidp/src/app/features/profile/profile.routes.ts +++ b/workspace/apps/pidp/src/app/features/profile/profile.routes.ts @@ -1,15 +1,11 @@ import { Routes } from '@angular/router'; -import { PermissionsGuard } from '@app/modules/permissions/permissions.guard'; -import { Role } from '@app/shared/enums/roles.enum'; - export class ProfileRoutes { public static BASE_PATH = 'profile'; public static PERSONAL_INFO = 'personal-information'; public static COLLEGE_LICENCE_DECLARATION = 'college-licence-declaration'; public static COLLEGE_LICENCE_INFO = 'college-licence-info'; - public static WORK_AND_ROLE_INFO = 'work-and-role-information'; public static USER_ACCESS_AGREEMENT = 'user-access-agreement'; /** @@ -36,17 +32,6 @@ export const routes: Routes = [ './pages/college-licence/college-licence-declaration/college-licence-declaration-routing.routes' ).then((m) => m.routes), }, - { - path: ProfileRoutes.WORK_AND_ROLE_INFO, - canMatch: [PermissionsGuard.canMatch], - data: { - roles: [Role.FEATURE_PIDP_DEMO], - }, - loadChildren: (): Promise => - import( - './pages/work-and-role-information/work-and-role-information-routing.routes' - ).then((m) => m.routes), - }, { path: ProfileRoutes.USER_ACCESS_AGREEMENT, loadChildren: (): Promise => diff --git a/workspace/apps/pidp/src/app/shared/components/get-support/get-support.component.ts b/workspace/apps/pidp/src/app/shared/components/get-support/get-support.component.ts index 8b01d6bfa..f82438855 100644 --- a/workspace/apps/pidp/src/app/shared/components/get-support/get-support.component.ts +++ b/workspace/apps/pidp/src/app/shared/components/get-support/get-support.component.ts @@ -74,13 +74,6 @@ export class GetSupportComponent implements OnInit { name: 'HCIMWeb Account Transfer', email: this.config.emails.hcimAccountTransferSupport, }, - ...ArrayUtils.insertIf( - this.permissionsService.hasRole(Role.FEATURE_PIDP_DEMO), - { - name: 'HCIMWeb Enrolment', - email: this.config.emails.hcimEnrolmentSupport, - }, - ), ...ArrayUtils.insertIf( this.permissionsService.hasRole(Role.FEATURE_PIDP_DEMO), { diff --git a/workspace/apps/pidp/src/environments/environment.model.ts b/workspace/apps/pidp/src/environments/environment.model.ts index df080ffee..b5ecd5df7 100644 --- a/workspace/apps/pidp/src/environments/environment.model.ts +++ b/workspace/apps/pidp/src/environments/environment.model.ts @@ -17,7 +17,6 @@ export interface AppEnvironment extends EnvironmentConfig { providerIdentitySupport: string; specialAuthorityEformsSupport: string; hcimAccountTransferSupport: string; - hcimEnrolmentSupport: string; prescriptionRefillRequestEformsSupport: string; driverFitnessSupport: string; msTeamsSupport: string; diff --git a/workspace/apps/pidp/src/environments/environment.prod.ts b/workspace/apps/pidp/src/environments/environment.prod.ts index 3ea7b4984..ccc77f9e2 100644 --- a/workspace/apps/pidp/src/environments/environment.prod.ts +++ b/workspace/apps/pidp/src/environments/environment.prod.ts @@ -1,6 +1,5 @@ import { driverFitnessSupportEmail } from '@app/features/access/pages/driver-fitness/driver-fitness.constants'; import { hcimWebAccountTransferSupport } from '@app/features/access/pages/hcim-account-transfer/hcim-account-transfer-constants'; -import { hcimWebEnrolmentSupport } from '@app/features/access/pages/hcim-enrolment/hcim-enrolment-constants'; import { immsBCEformsSupportEmail } from '@app/features/access/pages/immsbc-eforms/immsbc-eforms.constants'; import { doctorsTechnologyOfficeEmail, @@ -41,7 +40,6 @@ export const environment: AppEnvironment = { providerIdentitySupport: 'OneHealthID@gov.bc.ca', specialAuthorityEformsSupport: specialAuthorityEformsSupportEmail, hcimAccountTransferSupport: hcimWebAccountTransferSupport, - hcimEnrolmentSupport: hcimWebEnrolmentSupport, prescriptionRefillRequestEformsSupport: prescriptionRefillRequestEformsSupportEmail, driverFitnessSupport: driverFitnessSupportEmail, @@ -60,7 +58,7 @@ export const environment: AppEnvironment = { prescriptionRenewal: prescriptionRenewalEformsSupportUrl, }, phones: { - additionalSupport: '250-857-1969', + additionalSupport: '250-448-1262', }, keycloakConfig: { config: { diff --git a/workspace/apps/pidp/src/test/mock-profile-status.ts b/workspace/apps/pidp/src/test/mock-profile-status.ts index 8c7311853..b5113a45a 100644 --- a/workspace/apps/pidp/src/test/mock-profile-status.ts +++ b/workspace/apps/pidp/src/test/mock-profile-status.ts @@ -1,4 +1,4 @@ -import { randEmail, randFullName, randNumber } from '@ngneat/falso'; +import { randFullName, randNumber } from '@ngneat/falso'; import { StatusCode } from '@app/features/portal/enums/status-code.enum'; import { ProfileStatus } from '@app/features/portal/models/profile-status.model'; @@ -22,12 +22,6 @@ export class MockProfileStatus { statusCode: StatusCode.AVAILABLE, isComplete: false, }, - administratorInfo: { - email: randEmail(), - statusCode: StatusCode.AVAILABLE, - }, - organizationDetails: { statusCode: StatusCode.AVAILABLE }, - facilityDetails: { statusCode: StatusCode.AVAILABLE }, endorsements: { statusCode: StatusCode.AVAILABLE }, userAccessAgreement: { statusCode: StatusCode.AVAILABLE }, saEforms: { @@ -38,13 +32,11 @@ export class MockProfileStatus { 'prescription-refill-eforms': { statusCode: StatusCode.AVAILABLE }, bcProvider: { statusCode: StatusCode.AVAILABLE }, hcimAccountTransfer: { statusCode: StatusCode.AVAILABLE }, - hcimEnrolment: { statusCode: StatusCode.AVAILABLE }, driverFitness: { statusCode: StatusCode.AVAILABLE }, msTeamsPrivacyOfficer: { statusCode: StatusCode.AVAILABLE }, msTeamsClinicMember: { statusCode: StatusCode.AVAILABLE }, providerReportingPortal: { statusCode: StatusCode.AVAILABLE }, 'provider-reporting-portal': { statusCode: StatusCode.AVAILABLE }, - sitePrivacySecurityChecklist: { statusCode: StatusCode.AVAILABLE }, complianceTraining: { statusCode: StatusCode.AVAILABLE }, primaryCareRostering: { statusCode: StatusCode.AVAILABLE }, immsBCEforms: { statusCode: StatusCode.AVAILABLE }, diff --git a/workspace/libs/shared/data-access/src/lib/models/party.model.ts b/workspace/libs/shared/data-access/src/lib/models/party.model.ts index 3282bfd35..4c240a5fa 100644 --- a/workspace/libs/shared/data-access/src/lib/models/party.model.ts +++ b/workspace/libs/shared/data-access/src/lib/models/party.model.ts @@ -6,7 +6,6 @@ import { User } from './user.model'; export enum AccessTypeCode { SAEforms = 1, HcimAccountTransfer, - HcimEnrolment, DriverFitness, MSTeams, }