diff --git a/src/app/app-provider-admin/provider-admin/configurations/change-username/change-username.component.css b/src/app/app-provider-admin/provider-admin/configurations/change-username/change-username.component.css
new file mode 100644
index 00000000..6c6c1510
--- /dev/null
+++ b/src/app/app-provider-admin/provider-admin/configurations/change-username/change-username.component.css
@@ -0,0 +1,15 @@
+.screen-note {
+ font-size: 12px;
+ color: rgba(0, 0, 0, 0.6);
+ margin: 4px 0 0 0;
+}
+
+.validation-note {
+ font-size: 12px;
+ color: #d32f2f;
+ margin: 4px 0 0 0;
+}
+
+.m-l-10 {
+ margin-left: 10px;
+}
diff --git a/src/app/app-provider-admin/provider-admin/configurations/change-username/change-username.component.html b/src/app/app-provider-admin/provider-admin/configurations/change-username/change-username.component.html
new file mode 100644
index 00000000..1a5ffc55
--- /dev/null
+++ b/src/app/app-provider-admin/provider-admin/configurations/change-username/change-username.component.html
@@ -0,0 +1,125 @@
+
+
+
+
Change Username
+
+ Renaming a user also repoints the Created By and Modified By records
+ they own. Fill in only what you want to change — leave a field blank to
+ keep its current value. This cannot be undone.
+
+
+
+
+
+ Select User
+
+
+ {{ item.userName }}
+
+
+
+
+
+
+
+ Current Username
+
+
+
+
+
+
+ New Username
+
+ Maximum {{ effectiveMaxLength }} characters
+
+
+
+
+
+
+
+
+
+ Also update contact numbers
+
+
+ Only tick this where the username is the user's mobile number. It
+ overwrites Contact No and Emergency Contact No, which limits the new
+ username to {{ maxContactLength }} characters.
+
+
+
+
+
+
+
{{ validationMessage }}
+
+
+
+
+
+
+
+
Update complete
+
+ Username: {{ renameResult.oldUserName }} →
+ {{ renameResult.newUserName }}
+
+
+ Employee ID: {{ renameResult.oldEmployeeId || "not set" }} →
+ {{ renameResult.newEmployeeId }}
+
+
+ Employee ID unchanged ({{ renameResult.oldEmployeeId || "not set" }})
+
+
+
+
diff --git a/src/app/app-provider-admin/provider-admin/configurations/change-username/change-username.component.ts b/src/app/app-provider-admin/provider-admin/configurations/change-username/change-username.component.ts
new file mode 100644
index 00000000..de3802ec
--- /dev/null
+++ b/src/app/app-provider-admin/provider-admin/configurations/change-username/change-username.component.ts
@@ -0,0 +1,236 @@
+/*
+ * AMRIT – Accessible Medical Records via Integrated Technology
+ * Integrated EHR (Electronic Health Records) Solution
+ *
+ * Copyright (C) "Piramal Swasthya Management and Research Institute"
+ *
+ * This file is part of AMRIT.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ */
+import { Component, OnInit } from '@angular/core';
+import { ChangeUsernameService } from 'src/app/core/services/ProviderAdminServices/change-username.service';
+import { ConfirmationDialogsService } from 'src/app/core/services/dialog/confirmation.service';
+import { SessionStorageService } from 'Common-UI/src/registrar/services/session-storage.service';
+
+@Component({
+ selector: 'app-change-username',
+ templateUrl: './change-username.component.html',
+ styleUrls: ['./change-username.component.css'],
+})
+export class ChangeUsernameComponent implements OnInit {
+ serviceProviderID: any;
+ user: any;
+ newUserName = '';
+
+ currentEmployeeId = '';
+ newEmployeeId = '';
+
+ userNamesList: any = [];
+
+ updateContactFields = true;
+
+ renameResult: any = null;
+ submitting = false;
+
+ userNameTaken = false;
+ employeeIdTaken = false;
+
+ readonly maxUserNameLength = 20;
+ readonly maxContactLength = 12;
+ readonly maxEmployeeIdLength = 20;
+
+ constructor(
+ private changeUsernameService: ChangeUsernameService,
+ private alertService: ConfirmationDialogsService,
+ readonly sessionstorage: SessionStorageService,
+ ) {}
+
+ ngOnInit() {
+ this.serviceProviderID = this.sessionstorage.getItem('service_providerID');
+ this.getUserList();
+ }
+
+ getUserList() {
+ this.changeUsernameService.getUserList(this.serviceProviderID).subscribe(
+ (response: any) => {
+ this.userNamesList = response.data;
+ },
+ (err: any) => this.alertService.alert(err.errorMessage, 'error'),
+ );
+ }
+
+ onSelectionChange() {
+ this.renameResult = null;
+ }
+
+ onUserChange() {
+ this.onSelectionChange();
+ this.currentEmployeeId = '';
+ this.newUserName = '';
+ this.newEmployeeId = '';
+ this.userNameTaken = false;
+ this.employeeIdTaken = false;
+ if (!this.user) {
+ return;
+ }
+ this.changeUsernameService.getUserDetail(this.user.userName).subscribe(
+ (response: any) => {
+ this.currentEmployeeId = response.data?.employeeID || '';
+ },
+ (err: any) => this.alertService.alert(err.errorMessage, 'error'),
+ );
+ }
+
+ checkUserNameAvailability() {
+ this.onSelectionChange();
+ this.userNameTaken = false;
+ const newUserName = (this.newUserName || '').trim();
+ if (!this.user || !newUserName || newUserName === this.user.userName) {
+ return;
+ }
+ this.changeUsernameService.checkUserAvailability(newUserName).subscribe(
+ (response: any) => {
+ this.userNameTaken = response.data?.response === 'userexist';
+ },
+ (err: any) => console.log('error', err),
+ );
+ }
+
+ checkEmployeeIdAvailability() {
+ this.onSelectionChange();
+ this.employeeIdTaken = false;
+ const newEmployeeId = (this.newEmployeeId || '').trim();
+ if (!newEmployeeId || newEmployeeId === this.currentEmployeeId) {
+ return;
+ }
+ this.changeUsernameService.checkEmpIdAvailability(newEmployeeId).subscribe(
+ (response: any) => {
+ this.employeeIdTaken = response.data?.response === 'true';
+ },
+ (err: any) => console.log('error', err),
+ );
+ }
+
+ get effectiveMaxLength(): number {
+ return this.updateContactFields
+ ? this.maxContactLength
+ : this.maxUserNameLength;
+ }
+
+ get validationMessage(): string | null {
+ if (!this.user) {
+ return 'Select a user';
+ }
+ const newUserName = (this.newUserName || '').trim();
+ const newEmployeeId = (this.newEmployeeId || '').trim();
+
+ const userNameChanged = !!newUserName && newUserName !== this.user.userName;
+ const employeeIdChanged =
+ !!newEmployeeId && newEmployeeId !== this.currentEmployeeId;
+
+ if (!userNameChanged && !employeeIdChanged) {
+ return 'Enter a new username or a new employee ID';
+ }
+ if (userNameChanged) {
+ if (newUserName.length > this.effectiveMaxLength) {
+ return this.updateContactFields
+ ? `Maximum ${this.maxContactLength} characters while contact numbers are being updated`
+ : `Maximum ${this.maxUserNameLength} characters`;
+ }
+ if (this.userNameTaken) {
+ return `Username ${newUserName} is already in use`;
+ }
+ }
+ if (employeeIdChanged) {
+ if (newEmployeeId.length > this.maxEmployeeIdLength) {
+ return `Employee ID: maximum ${this.maxEmployeeIdLength} characters`;
+ }
+ if (this.employeeIdTaken) {
+ return `Employee ID ${newEmployeeId} is already in use`;
+ }
+ }
+ return null;
+ }
+
+ get canSubmit(): boolean {
+ return this.validationMessage === null && !this.submitting;
+ }
+
+ private buildRequest() {
+ const newUserName = (this.newUserName || '').trim();
+ const newEmployeeId = (this.newEmployeeId || '').trim();
+ return {
+ userID: this.user.userID,
+ oldUserName: this.user.userName,
+ newUserName: newUserName || null,
+ newEmployeeId: newEmployeeId || null,
+ updateContactFields: this.updateContactFields,
+ };
+ }
+
+ confirmAndRename() {
+ if (!this.canSubmit) {
+ return;
+ }
+ const request = this.buildRequest();
+ this.alertService
+ .confirm('Confirm', this.confirmMessage(request))
+ .subscribe((accept: any) => {
+ if (accept) {
+ this.rename(request);
+ }
+ });
+ }
+
+ private confirmMessage(request: any): string {
+ const changes: string[] = [];
+ if (request.newUserName) {
+ changes.push(
+ `username from ${request.oldUserName} to ${request.newUserName}`,
+ );
+ }
+ if (request.newEmployeeId) {
+ changes.push(
+ `employee ID from ${this.currentEmployeeId || 'not set'} to ${request.newEmployeeId}`,
+ );
+ }
+ const audit = request.newUserName
+ ? ' This also repoints the Created By and Modified By records they own.'
+ : '';
+ return `Change ${changes.join(' and ')}?${audit} This cannot be undone.`;
+ }
+
+ private rename(request: any) {
+ this.submitting = true;
+ this.changeUsernameService.renameUsername(request).subscribe(
+ (response: any) => {
+ this.submitting = false;
+ this.renameResult = response.data;
+ this.alertService.alert('Username updated successfully', 'success');
+ this.newUserName = '';
+ this.newEmployeeId = '';
+ this.currentEmployeeId = '';
+ this.userNameTaken = false;
+ this.employeeIdTaken = false;
+ this.user = null;
+ this.getUserList();
+ },
+ (err: any) => {
+ this.submitting = false;
+ this.alertService.alert(err.errorMessage, 'error');
+ },
+ );
+ }
+}
diff --git a/src/app/app-provider-admin/provider-admin/configurations/configurations.module.ts b/src/app/app-provider-admin/provider-admin/configurations/configurations.module.ts
index 78b36204..1a051bac 100644
--- a/src/app/app-provider-admin/provider-admin/configurations/configurations.module.ts
+++ b/src/app/app-provider-admin/provider-admin/configurations/configurations.module.ts
@@ -24,8 +24,10 @@ import { UserRoleAgentID_MappingService } from './services/user-role-agentID-map
import { HospitalInstituteDirectorySubdirectoryMappingComponent } from './hospital-institute-directory-subdirectory-mapping/hospital-institute-directory-subdirectory-mapping.component';
import { HospitalInstituteMappingService } from '../activities/services/hospital-institute-mapping-service.service';
import { ResetUserPasswordService } from 'src/app/core/services/ProviderAdminServices/reset-user-password.service';
+import { ChangeUsernameService } from 'src/app/core/services/ProviderAdminServices/change-username.service';
import { UtcDatePipe } from './utc-date.pipe';
import { ResetUserPasswordComponent } from './reset-user-password/reset-user-password.component';
+import { ChangeUsernameComponent } from './change-username/change-username.component';
import { SwymedUserMappingComponent } from './swymed-user-mapping/swymed-user-mapping.component';
import { SwymedUserConfigurationService } from './services/swymed-user-service';
import { ServicePointVillageMapComponent } from './service-point-village-mapping/service-point-village-mapping.component';
@@ -63,6 +65,7 @@ import { MatInputModule } from '@angular/material/input';
AgentIDMappingModalComponent,
HospitalInstituteDirectorySubdirectoryMappingComponent,
ResetUserPasswordComponent,
+ ChangeUsernameComponent,
SwymedUserMappingComponent,
UtcDatePipe,
ServicePointVillageMapComponent,
@@ -98,6 +101,7 @@ import { MatInputModule } from '@angular/material/input';
UserRoleAgentID_MappingService,
HospitalInstituteMappingService,
ResetUserPasswordService,
+ ChangeUsernameService,
SwymedUserConfigurationService,
ServicePointVillageMapService,
VanServicePointMappingService,
@@ -120,6 +124,7 @@ import { MatInputModule } from '@angular/material/input';
AgentIDMappingModalComponent,
HospitalInstituteDirectorySubdirectoryMappingComponent,
ResetUserPasswordComponent,
+ ChangeUsernameComponent,
SwymedUserMappingComponent,
UtcDatePipe,
ServicePointVillageMapComponent,
diff --git a/src/app/app-provider-admin/provider-admin/provider-admin.component.html b/src/app/app-provider-admin/provider-admin/provider-admin.component.html
index bc38e96d..bdd779c6 100644
--- a/src/app/app-provider-admin/provider-admin/provider-admin.component.html
+++ b/src/app/app-provider-admin/provider-admin/provider-admin.component.html
@@ -125,6 +125,7 @@
Email and Contact Number Configuration
Reset User Password
+ Change Username
User Swymed Mapping
Wrapup Time Configuration
@@ -284,6 +285,7 @@
*ngSwitchCase="23"
>
+
diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts
index 8f266fd3..f8ae7a7c 100644
--- a/src/app/core/core.module.ts
+++ b/src/app/core/core.module.ts
@@ -173,7 +173,7 @@ export class CoreModule {
dataService,
HttpServices,
DashboardHttpServices,
- ],
+ ],
};
}
}
diff --git a/src/app/core/services/ProviderAdminServices/change-username.service.ts b/src/app/core/services/ProviderAdminServices/change-username.service.ts
new file mode 100644
index 00000000..4c5535af
--- /dev/null
+++ b/src/app/core/services/ProviderAdminServices/change-username.service.ts
@@ -0,0 +1,76 @@
+/*
+ * AMRIT – Accessible Medical Records via Integrated Technology
+ * Integrated EHR (Electronic Health Records) Solution
+ *
+ * Copyright (C) "Piramal Swasthya Management and Research Institute"
+ *
+ * This file is part of AMRIT.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/.
+ */
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { Observable } from 'rxjs';
+import { ConfigService } from '../config/config.service';
+
+@Injectable()
+export class ChangeUsernameService {
+ adminBaseUrl: any;
+ getUserListUrl: any;
+ getUserDetailUrl: any;
+ checkUserAvailabilityUrl: any;
+ checkEmpIdAvailabilityUrl: any;
+ renameUsernameUrl: any;
+
+ constructor(
+ private http: HttpClient,
+ private basepaths: ConfigService,
+ ) {
+ this.adminBaseUrl = this.basepaths.getAdminBaseUrl();
+
+ this.getUserListUrl = this.adminBaseUrl + 'm/SearchEmployee4';
+ this.getUserDetailUrl =
+ this.adminBaseUrl + 'm/FindEmployeeDetailsByUserName';
+ this.checkUserAvailabilityUrl = this.adminBaseUrl + 'm/FindEmployeeByName';
+ this.checkEmpIdAvailabilityUrl =
+ this.adminBaseUrl + 'm/FindEmployeeDetails';
+ this.renameUsernameUrl = this.adminBaseUrl + 'username/renameUsername';
+ }
+
+ getUserList(serviceProviderID: any): Observable {
+ return this.http.post(this.getUserListUrl, {
+ serviceProviderID: serviceProviderID,
+ });
+ }
+
+ getUserDetail(userName: any): Observable {
+ return this.http.post(this.getUserDetailUrl, { userName: userName });
+ }
+
+ checkUserAvailability(userName: any): Observable {
+ return this.http.post(this.checkUserAvailabilityUrl, {
+ userName: userName,
+ });
+ }
+
+ checkEmpIdAvailability(employeeId: any): Observable {
+ return this.http.post(this.checkEmpIdAvailabilityUrl, {
+ employeeID: employeeId,
+ });
+ }
+
+ renameUsername(renameObject: any): Observable {
+ return this.http.post(this.renameUsernameUrl, renameObject);
+ }
+}