Added Doctor Module

This commit is contained in:
Sk Shaifat Murshed 2025-02-12 17:52:30 +05:30
parent 8545975107
commit 2b5b7be681
38 changed files with 6756 additions and 170 deletions

View File

@ -48,6 +48,10 @@ const routes: Routes = [
path: 'departments',
loadChildren: () => import('./departments/departments.module').then(m => m.DepartmentsModule),
},
{
path: 'doctors',
loadChildren: () => import('./doctors/doctors.module').then(m => m.DoctorsModule),
},
];
@NgModule({

View File

@ -30,12 +30,10 @@ import { AccountLayoutModule } from '@abp/ng.theme.lepton-x/account';
CoreModule,
ThemeSharedModule,
InternetConnectionStatusComponent,
ThemeLeptonXModule.forRoot(),
SideMenuLayoutModule.forRoot(),
AccountLayoutModule.forRoot(),
ThemeLeptonXModule.forRoot(),
SideMenuLayoutModule.forRoot(),
AccountLayoutModule.forRoot(),
],
declarations: [AppComponent],
providers: [

View File

@ -39,7 +39,6 @@ export class AppointmentCalendarComponent implements OnInit {
search: event.globalFilter == null ? '' : event.globalFilter,
};
this.appointmentService.getAppointmentList(this.params).subscribe(data => {
debugger
this.appointments = data.items;
this.updateCalendarEvents();
});
@ -65,7 +64,6 @@ export class AppointmentCalendarComponent implements OnInit {
};
}
combineDateTime(dateStr: string, timeStr: string): string {
debugger
if (!timeStr) return dateStr;
const date = new Date(dateStr);
const [hours, minutes] = timeStr.split(':');
@ -82,7 +80,6 @@ export class AppointmentCalendarComponent implements OnInit {
],
};
closeDialog() {
debugger;
this.isModalVisible = false;
this.loadAppointments({
first: 0,
@ -93,7 +90,6 @@ export class AppointmentCalendarComponent implements OnInit {
});
}
handleDateClick(arg) {
debugger;
this.selectedDate = arg.dateStr;
this.isModalVisible = true;
this.isEditMode = false;
@ -107,7 +103,6 @@ export class AppointmentCalendarComponent implements OnInit {
}
onEventClick(info: any) {
debugger;
this.appointmentIdToEdit = info.event.id;
this.isEditMode = true;
this.isModalVisible = true;

View File

@ -4,15 +4,15 @@
role="dialog"
style="background: rgba(0, 0, 0, 0.5)"
*ngIf="visible"
aria-label="l('name')"
aria-label="l('Doctor')"
>
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header py-4">
<h4 class="text-success mb-0 fs-3 fw-normal">
{{ isEditMode ? 'Edit ' : 'Create ' }}{{name}}
{{ isEditMode ? 'Edit ' : 'Create ' }} Doctor
</h4>
<button
<button
tabindex="0"
type="button"
(click)="onClose()"
@ -20,126 +20,57 @@
aria-label="Close"
></button>
</div>
<form #departmentForm="ngForm" (ngSubmit)="saveDepartment(departmentForm)">
<form #doctorForm="ngForm" (ngSubmit)="saveDoctor(doctorForm)">
<div class="p-fluid grid justify-content-center">
<div class="field col-md-5">
<label for="departmentNo">Department No <span class="text-danger">*</span></label>
<div class="field col-md-5" *ngFor="let field of ['firstName', 'lastName', 'mobile', 'email']; let i = index">
<label [for]="field">{{ field | titlecase }} <span class="text-danger">*</span></label>
<span class="p-input-icon-left p-input-icon-right">
<i class="pi pi-hashtag"></i>
<input
pInputText
id="departmentNo"
name="departmentNo"
[(ngModel)]="department.departmentNo"
#departmentNoCtrl="ngModel"
required
[ngClass]="{ 'is-valid': departmentNoCtrl.valid && departmentNoCtrl.touched, 'is-invalid': departmentNoCtrl.invalid && departmentNoCtrl.touched }"
/>
<i *ngIf="departmentNoCtrl.valid && departmentNoCtrl.touched" class="pi pi-check text-success"></i>
<i *ngIf="departmentNoCtrl.invalid && departmentNoCtrl.touched" class="pi pi-times text-danger"></i>
</span>
<small class="text-danger" *ngIf="departmentNoCtrl.invalid && departmentNoCtrl.touched">
<span *ngIf="departmentNoCtrl.errors?.required">Department No is required.</span>
</small>
</div>
<div class="field col-md-1"></div>
<div class="field col-md-5">
<label for="departmentName">Department Name <span class="text-danger">*</span></label>
<span class="p-input-icon-left p-input-icon-right">
<i class="pi pi-building"></i>
<input
pInputText
id="departmentName"
name="departmentName"
[(ngModel)]="department.departmentName"
#departmentNameCtrl="ngModel"
required
/>
</span>
<small class="text-danger" *ngIf="departmentNameCtrl.invalid && departmentNameCtrl.touched">
<span *ngIf="departmentNameCtrl.errors?.required">Department Name is required.</span>
</small>
</div>
<div class="field col-md-5">
<label for="departmentDate">Department Date</label>
<p-calendar
id="departmentDate"
name="departmentDate"
[(ngModel)]="Departmentdate"
[showIcon]="true">
</p-calendar>
</div>
<div class="field col-md-1"></div>
<div class="field col-md-5">
<label for="departmentHead">Department Head</label>
<span class="p-input-icon-left">
<i class="pi pi-user"></i>
<input
pInputText
id="departmentHead"
name="departmentHead"
[(ngModel)]="department.departmentHead"
/>
<i class="pi" [ngClass]="{'pi-user': i < 2, 'pi-phone': field === 'mobile', 'pi-envelope': field === 'email'}"></i>
<input pInputText [id]="field" [name]="field" [(ngModel)]="doctor[field]" required #ctrl="ngModel"
[ngClass]="{'is-valid': ctrl.valid && ctrl.touched, 'is-invalid': ctrl.invalid && ctrl.touched}" />
<i *ngIf="ctrl.valid && ctrl.touched" class="pi pi-check text-success"></i>
<i *ngIf="ctrl.invalid && ctrl.touched" class="pi pi-times text-danger"></i>
</span>
<small class="text-danger" *ngIf="ctrl.invalid && ctrl.touched">{{ field | titlecase }} is required.</small>
</div>
<div class="field col-md-5">
<label>Status</label>
<div class="flex align-items-center p-input-icon-right">
<p-radioButton
name="status"
value="Active"
[(ngModel)]="department.status"
inputId="active"
></p-radioButton>
<label for="active" class="ml-2 mr-3">Active</label>
<p-radioButton
name="status"
value="Inactive"
[(ngModel)]="department.status"
inputId="inactive"
></p-radioButton>
<label for="inactive" class="ml-2">Inactive</label>
</div>
<label for="specialization">Specialization</label>
<input pInputText id="specialization" name="specialization" [(ngModel)]="doctor.specialization" />
</div>
<div class="field col-md-5">
<label for="degree">Degree</label>
<input pInputText id="degree" name="degree" [(ngModel)]="doctor.degree" />
</div>
<div class="field col-md-5">
<label for="experience">Experience (Years)</label>
<input type="number" pInputText id="experience" name="experience" [(ngModel)]="doctor.experience" min="0" />
</div>
<div class="field col-md-5">
<label for="consultationFee">Consultation Fee</label>
<input type="number" pInputText id="consultationFee" name="consultationFee" [(ngModel)]="doctor.consultationFee" min="0" />
</div>
<div class="field col-md-5">
<label for="clinicLocation">Clinic Location</label>
<input pInputText id="clinicLocation" name="clinicLocation" [(ngModel)]="doctor.clinicLocation" />
</div>
<div class="field col-md-5">
<label for="rating">Rating</label>
<p-rating [(ngModel)]="doctor.rating" [stars]="4" [cancel]="false" name="rating"></p-rating>
</div>
<div class="field col-md-5">
<label for="availability">Availability</label>
<p-dropdown [options]="workScheduleOptions" [(ngModel)]="doctor.availability" name="availability" placeholder="Select Availability"></p-dropdown>
</div>
<div class="field col-md-6"></div>
<div class="field col-11">
<label for="description">Description</label>
<textarea
id="description"
name="description"
[(ngModel)]="department.description"
rows="5"
cols="30"
pInputTextarea>
</textarea>
<textarea id="description" name="description" [(ngModel)]="doctor.description" rows="5" cols="30" pInputTextarea></textarea>
</div>
<div class="field col-11 flex justify-content-end">
<button
pButton
type="submit"
label="Save"
class="p-button-success"
[disabled]="departmentForm.invalid">
</button>
<button
pButton
type="button"
label="Cancel"
class="p-button-secondary ml-2"
(click)="onClose()">
</button>
<button pButton type="submit" label="Save" class="p-button-success" [disabled]="doctorForm.invalid"></button>
<button pButton type="button" label="Cancel" class="p-button-secondary ml-2" (click)="onClose()"></button>
</div>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DepartmentDialogComponent } from './department-dialog.component';
describe('DepartmentDialogComponent', () => {
let component: DepartmentDialogComponent;
let fixture: ComponentFixture<DepartmentDialogComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [DepartmentDialogComponent]
})
.compileComponents();
fixture = TestBed.createComponent(DepartmentDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -50,7 +50,6 @@ export class DepartmentDialogComponent implements OnInit {
private toaster: ToasterService
) {}
ngOnInit(): void {
debugger;
if(this.isEditMode){
this.fetchDepartmentData();
}
@ -69,8 +68,6 @@ export class DepartmentDialogComponent implements OnInit {
this.DepartmentService.getDepartmentById(this.Id).subscribe(result => {
this.department = result;
this.Departmentdate = new Date(result.departmentDate);
});
}
saveDepartment(form: NgForm) {

View File

@ -0,0 +1,99 @@
<div
class="modal fade show d-block"
tabindex="-1"
role="dialog"
style="background: rgba(0, 0, 0, 0.5)"
*ngIf="visible"
aria-label="l('Doctor')"
>
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header py-4">
<h4 class="text-success mb-0 fs-3 fw-normal">
{{ isEditMode ? 'Edit ' : 'Create ' }} Doctor
</h4>
<button
tabindex="0"
type="button"
(click)="onClose()"
class="btn-close"
aria-label="Close"
></button>
</div>
<form #doctorForm="ngForm" (ngSubmit)="saveDoctor(doctorForm)">
<div class="p-fluid grid justify-content-center">
<div class="field col-md-5">
<label for="firstName">First Name <span class="text-danger">*</span></label>
<input pInputText id="firstName" name="firstName" [(ngModel)]="doctor.firstName" required #firstNameCtrl="ngModel"
[ngClass]="{'is-invalid': firstNameCtrl.invalid && firstNameCtrl.touched}" />
<small class="text-danger" *ngIf="firstNameCtrl.invalid && firstNameCtrl.touched">First Name is required.</small>
</div>
<div class="field col-md-1"></div>
<div class="field col-md-5">
<label for="lastName">Last Name <span class="text-danger">*</span></label>
<input pInputText id="lastName" name="lastName" [(ngModel)]="doctor.lastName" required #lastNameCtrl="ngModel"
[ngClass]="{'is-invalid': lastNameCtrl.invalid && lastNameCtrl.touched}" />
<small class="text-danger" *ngIf="lastNameCtrl.invalid && lastNameCtrl.touched">Last Name is required.</small>
</div>
<div class="field col-md-5">
<label for="mobile">Mobile <span class="text-danger">*</span></label>
<input pInputText id="mobile" name="mobile" [(ngModel)]="doctor.mobile" required #mobileCtrl="ngModel"
[ngClass]="{'is-invalid': mobileCtrl.invalid && mobileCtrl.touched}" />
<small class="text-danger" *ngIf="mobileCtrl.invalid && mobileCtrl.touched">Mobile is required.</small>
</div>
<div class="field col-md-1"></div>
<div class="field col-md-5">
<label for="email">Email <span class="text-danger">*</span></label>
<input pInputText id="email" name="email" [(ngModel)]="doctor.email" required type="email" #emailCtrl="ngModel"
[ngClass]="{'is-invalid': emailCtrl.invalid && emailCtrl.touched}" />
<small class="text-danger" *ngIf="emailCtrl.invalid && emailCtrl.touched">Valid Email is required.</small>
</div>
<div class="field col-md-5">
<label for="specialization">Specialization</label>
<input pInputText id="specialization" name="specialization" [(ngModel)]="doctor.specialization" />
</div>
<div class="field col-md-1"></div>
<div class="field col-md-5">
<label for="experience">Experience (Years)</label>
<input type="number" pInputText id="experience" name="experience" [(ngModel)]="doctor.experience" min="0" />
</div>
<div class="field col-md-5">
<label for="consultationFee">Consultation Fee</label>
<input type="number" pInputText id="consultationFee" name="consultationFee" [(ngModel)]="doctor.consultationFee" min="0" />
</div>
<div class="field col-md-1"></div>
<div class="field col-md-5">
<label for="clinicLocation">Clinic Location</label>
<input pInputText id="clinicLocation" name="clinicLocation" [(ngModel)]="doctor.clinicLocation" />
</div>
<div class="field col-md-3">
<label for="rating">Rating</label><br>
<p-rating [(ngModel)]="doctor.rating" [stars]="5" [cancel]="false" name="rating"></p-rating>
</div>
<div class="field col-md-4">
<label for="degree">Degree</label>
<input pInputText id="degree" name="degree" [(ngModel)]="doctor.degree" />
</div>
<div class="field col-md-1"></div>
<div class="field col-md-3">
<label for="availability">Availability</label>
<p-dropdown [options]="workScheduleOptions" [(ngModel)]="doctor.availability" name="availability" placeholder="Select Availability"></p-dropdown>
</div>
<div class="field col-11">
<label for="description">Description</label>
<textarea id="description" name="description" [(ngModel)]="doctor.description" rows="5" cols="30" pInputTextarea></textarea>
</div>
<div class="field col-11 flex justify-content-end">
<button pButton type="submit" label="Save" class="p-button-success" [disabled]="doctorForm.invalid"></button>
<button pButton type="button" label="Cancel" class="p-button-secondary ml-2" (click)="onClose()"></button>
</div>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,23 @@
.hide_body{
scrollbar-width: auto !important;
min-height: 150px;
max-height: calc(100vh - 13rem);
overflow-y: auto;
}
.is-valid {
border-color: green !important;
}
.is-invalid {
border-color: red !important;
}
/* Adjust the z-index of the calendar dropdown */
.p-calendar .p-datepicker {
z-index: 1050 !important; /* Make sure it's above other elements */
}
/* You can also adjust modal z-index if necessary */
.modal {
z-index: 1040; /* Set lower z-index to ensure modal is behind the calendar */
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DoctorDialogComponent } from './doctor-dialog.component';
describe('DoctorDialogComponent', () => {
let component: DoctorDialogComponent;
let fixture: ComponentFixture<DoctorDialogComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [DoctorDialogComponent]
})
.compileComponents();
fixture = TestBed.createComponent(DoctorDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,129 @@
import { ToasterService } from '@abp/ng.theme.shared';
import { CommonModule } from '@angular/common';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormsModule, NgForm } from '@angular/forms';
import { DoctorService } from '@proxy/doctors';
import { CreateDoctorDto } from '@proxy/dtos';
import { ButtonModule } from 'primeng/button';
import { CalendarModule } from 'primeng/calendar';
import { ChipModule } from 'primeng/chip';
import { DialogModule } from 'primeng/dialog';
import { DropdownModule } from 'primeng/dropdown';
import { InputTextModule } from 'primeng/inputtext';
import { InputTextareaModule } from 'primeng/inputtextarea';
import { RadioButtonModule } from 'primeng/radiobutton';
import { TableModule } from 'primeng/table';
import { RatingModule } from 'primeng/rating';
import { workScheduleOptions } from '@proxy/global-enum';
@Component({
selector: 'app-doctor-dialog',
standalone: true,
imports: [
TableModule,
DialogModule,
FormsModule,
TableModule,
ButtonModule,
DialogModule,
InputTextModule,
CalendarModule,
DropdownModule,
RadioButtonModule,
InputTextareaModule,
ChipModule,
CommonModule,
RatingModule
],
templateUrl: './doctor-dialog.component.html',
styleUrl: './doctor-dialog.component.scss',
})
export class DoctorDialogComponent implements OnInit {
@Input() visible: boolean = false;
@Input() name: string;
@Input() isEditMode: boolean = false;
@Output() save = new EventEmitter<any>();
@Output() close = new EventEmitter<void>();
@Input() Id: string;
doctorDialog: boolean;
JoiningDate: Date;
dateofbirth: Date;
constructor(private DoctorService: DoctorService, private toaster: ToasterService) {}
ngOnInit(): void {
if (this.isEditMode) {
this.fetchDoctorData();
}
}
doctor: CreateDoctorDto = {
id: '',
firstName: '',
lastName: '',
gender: '',
mobile: '',
password: '',
designation: '',
departmentId: '',
address: '',
email: '',
dob: '',
education: '',
specialization: '',
degree: '',
joiningDate: '',
experience: 0,
consultationFee: 0,
availability: null,
rating: 0,
clinicLocation: '',
};
workScheduleOptions = Object.keys(workScheduleOptions)
.filter(key => isNaN(Number(key)))
.map(key => ({
label: key.replace(/([A-Z])/g, ' $1').trim(),
value: workScheduleOptions[key as keyof typeof workScheduleOptions]
}));
fetchDoctorData() {
this.DoctorService.getDoctorById(this.Id).subscribe(result => {
this.doctor = result;
this.JoiningDate = new Date(result.joiningDate);
this.dateofbirth = new Date(result.dob);
});
}
saveDoctor(form: NgForm) {
if (form.invalid) {
Object.values(form.controls).forEach(control => control.markAsTouched());
return;
}
this.doctor.dob = this.dateofbirth.toDateString();
if (this.isEditMode) {
this.DoctorService.updatDoctor(this.doctor).subscribe(
() => {
this.toaster.success('Updated Successfully', 'Success');
this.onClose();
},
error => {
this.toaster.error(error, 'Error');
}
);
} else {
this.DoctorService.createDoctor(this.doctor).subscribe(
() => {
this.toaster.success('created successfully', 'Success');
this.onClose();
},
error => {
this.toaster.error(error, 'Error');
}
);
}
}
onClose() {
this.Id = '';
this.close.emit();
}
}

View File

@ -0,0 +1,11 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { DoctorsComponent } from './doctors.component';
const routes: Routes = [{ path: '', component: DoctorsComponent }];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class DoctorsRoutingModule {}

View File

@ -0,0 +1,81 @@
<div>
<p-table
#dt
dataKey="id"
[value]="doctors"
[paginator]="true"
[rows]="10"
[totalRecords]="totalRecords"
[lazy]="true"
(onLazyLoad)="loadDoctors($event)"
[rowsPerPageOptions]="[10, 20, 50]"
[responsiveLayout]="'scroll'"
[globalFilterFields]="['id', 'firstName', 'lastName', 'mobile', 'email', 'specialization']"
[filters]="{ global: { value: '', matchMode: 'contains' } }"
class="table table-striped"
>
<ng-template pTemplate="caption">
<div class="flex align-items-center justify-content-between mb-3 gap-3">
<h4 class="m-0">Doctor List</h4>
<div class="flex-grow-1 flex justify-content-center">
<div class="input-group">
<span class="input-group-text"><i class="pi pi-search"></i></span>
<input
pInputText
type="text"
class="form-control"
(input)="dt.filterGlobal($event.target.value, 'contains')"
[(ngModel)]="globalFilter"
placeholder="Search keyword"
/>
</div>
</div>
<div>
<button pButton class="p-button-rounded p-button-secondary ml-2" (click)="loadDoctors($event)">
<i class="pi pi-refresh"></i>
</button>
<button pButton class="p-button-rounded p-button-success ml-2" (click)="openNewDoctorDialog()" pTooltip="Add Doctor" tooltipPosition="left">
<i class="pi pi-plus-circle"></i>
</button>
<button pButton class="p-button-rounded p-button-warning ml-2" (click)="exportDoctors()">
<i class="pi pi-download"></i>
</button>
</div>
</div>
</ng-template>
<ng-template pTemplate="header">
<tr>
<th pSortableColumn="firstName">First Name <p-sortIcon field="firstName" /></th>
<th pSortableColumn="lastName">Last Name <p-sortIcon field="lastName" /></th>
<th pSortableColumn="mobile">Mobile <p-sortIcon field="mobile" /></th>
<th pSortableColumn="email">Email <p-sortIcon field="email" /></th>
<th pSortableColumn="specialization">Specialization <p-sortIcon field="specialization" /></th>
<th pSortableColumn="experience">Experience <p-sortIcon field="experience" /></th>
<th pSortableColumn="rating">Rating <p-sortIcon field="rating" /></th>
<th>Actions</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-doctor>
<tr>
<td>{{ doctor.firstName }}</td>
<td>{{ doctor.lastName }}</td>
<td>{{ doctor.mobile }}</td>
<td>{{ doctor.email }}</td>
<td>{{ doctor.specialization }}</td>
<td>{{ doctor.experience }} years</td>
<td>{{ doctor.rating }}</td>
<td class="d-flex">
<button class="btn btn-warning btn-sm ml-1" (click)="editDoctor(doctor)">
<i class="pi pi-pencil"></i>
</button>
<button class="btn btn-danger btn-sm ml-1" (click)="deleteDoctor(doctor.id)">
<i class="pi pi-trash"></i>
</button>
</td>
</tr>
</ng-template>
</p-table>
</div>
<app-doctor-dialog [Id]="DoctorIdToEdit"[isEditMode]="isEditMode"
[visible]="isModalVisible"*ngIf="isModalVisible" [name]="'Doctor'" (close)="closeDialog()"></app-doctor-dialog>

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DoctorsComponent } from './doctors.component';
describe('DoctorsComponent', () => {
let component: DoctorsComponent;
let fixture: ComponentFixture<DoctorsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [DoctorsComponent]
})
.compileComponents();
fixture = TestBed.createComponent(DoctorsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,108 @@
import { ConfirmationService, ToasterService } from '@abp/ng.theme.shared';
import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { DoctorService } from '@proxy/doctors';
import { PagingSortResultDto } from '@proxy/dto';
import { workScheduleOptions } from '@proxy/global-enum';
@Component({
selector: 'app-doctors',
templateUrl: './doctors.component.html',
styleUrl: './doctors.component.scss',
})
export class DoctorsComponent implements OnInit {
totalRecords: number = 0;
doctors = [];
loading: boolean = false;
params: PagingSortResultDto;
isModalVisible: boolean=false;
isEditMode: boolean = false;
DoctorIdToEdit: string;
ngOnInit(): void {
this.loadDoctors({
first: 0,
rows: 10,
sortField: 'id',
sortOrder: 1,
globalFilter: null,
});
}
constructor(
private DoctorService: DoctorService,
private http: HttpClient,
private confirmation: ConfirmationService,
private toaster: ToasterService
) {}
workSchedule = Object.keys(workScheduleOptions)
.filter(key => !isNaN(Number(key)))
.map(key => ({
label: workScheduleOptions[key as unknown as keyof typeof workScheduleOptions],
value: Number(key),
}));
loadDoctors(event: any) {
this.loading = true;
let order = event.sortOrder == 1 ? ' asc' : ' desc';
event.sortField = event.sortField == undefined ? 'id' : event.sortField;
this.params = {
skipCount: event.first,
maxResultCount: event.rows,
sorting: event.sortField + order,
search: event.globalFilter == null ? '' : event.globalFilter,
};
this.DoctorService.getDoctorList(this.params).subscribe(data => {
this.doctors = data.items;
this.totalRecords = data.totalCount;
this.loading = false;
});
}
openNewDoctorDialog() {
this.isModalVisible=true;
this.isEditMode = false;
}
editDoctor(Doctor: any) {
this.isEditMode = true;
this.DoctorIdToEdit = Doctor.id;
this.isModalVisible=true;
}
closeDialog() {
this.isModalVisible = false;
this.loadDoctors({
first: 0,
rows: 10,
sortField: 'id',
sortOrder: 1,
globalFilter: null,
});
}
exportDoctors() {
this.DoctorService.getExportDoctorsRecord().subscribe(result => {
const binary = atob(result.fileContent);
const len = binary.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binary.charCodeAt(i);
}
const blob = new Blob([bytes], { type: 'application/xlsx' });
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = result.fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
});
}
}

View File

@ -0,0 +1,39 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DoctorsRoutingModule } from './doctors-routing.module';
import { DoctorsComponent } from './doctors.component';
import { FormsModule } from '@angular/forms';
import { ButtonModule } from 'primeng/button';
import { CalendarModule } from 'primeng/calendar';
import { ChipModule } from 'primeng/chip';
import { DialogModule } from 'primeng/dialog';
import { DropdownModule } from 'primeng/dropdown';
import { InputTextModule } from 'primeng/inputtext';
import { InputTextareaModule } from 'primeng/inputtextarea';
import { RadioButtonModule } from 'primeng/radiobutton';
import { TableModule } from 'primeng/table';
import { DoctorDialogComponent } from './doctor-dialog.component';
@NgModule({
declarations: [DoctorsComponent],
imports: [
CommonModule,
DoctorsRoutingModule,
TableModule,
DialogModule,
FormsModule,
TableModule,
ButtonModule,
DialogModule,
InputTextModule,
CalendarModule,
DropdownModule,
RadioButtonModule,
InputTextareaModule,
ChipModule,
DoctorDialogComponent
],
})
export class DoctorsModule {}

View File

@ -1,6 +1,8 @@
import type { DoctorDto } from './dto/models';
import { RestService, Rest } from '@abp/ng.core';
import { Injectable } from '@angular/core';
import type { PagedResultDto } from '../abp/application/services/dto/models';
import type { FileDownloadDto, PagingSortResultDto } from '../dto/models';
import type { CreateDoctorDto } from '../dtos/models';
@Injectable({
@ -10,15 +12,23 @@ export class DoctorService {
apiName = 'Default';
create = (input: CreateDoctorDto, config?: Partial<Rest.Config>) =>
this.restService.request<any, DoctorDto>({
createDoctor = (input: CreateDoctorDto, config?: Partial<Rest.Config>) =>
this.restService.request<any, void>({
method: 'POST',
url: '/api/app/doctor',
url: '/api/app/doctor/doctor',
body: input,
},
{ apiName: this.apiName,...config });
deleteDoctorRecord = (id: string, config?: Partial<Rest.Config>) =>
this.restService.request<any, void>({
method: 'DELETE',
url: `/api/app/doctor/${id}/doctor-record`,
},
{ apiName: this.apiName,...config });
get = (config?: Partial<Rest.Config>) =>
this.restService.request<any, DoctorDto[]>({
method: 'GET',
@ -26,5 +36,39 @@ export class DoctorService {
},
{ apiName: this.apiName,...config });
getDoctorById = (id: string, config?: Partial<Rest.Config>) =>
this.restService.request<any, DoctorDto>({
method: 'GET',
url: `/api/app/doctor/${id}/doctor-by-id`,
},
{ apiName: this.apiName,...config });
getDoctorList = (input: PagingSortResultDto, config?: Partial<Rest.Config>) =>
this.restService.request<any, PagedResultDto<DoctorDto>>({
method: 'GET',
url: '/api/app/doctor/doctor-list',
params: { search: input.search, sorting: input.sorting, skipCount: input.skipCount, maxResultCount: input.maxResultCount },
},
{ apiName: this.apiName,...config });
getExportDoctorsRecord = (config?: Partial<Rest.Config>) =>
this.restService.request<any, FileDownloadDto>({
method: 'GET',
url: '/api/app/doctor/export-doctors-record',
},
{ apiName: this.apiName,...config });
updatDoctor = (input: CreateDoctorDto, config?: Partial<Rest.Config>) =>
this.restService.request<any, void>({
method: 'POST',
url: '/api/app/doctor/updat-doctor',
body: input,
},
{ apiName: this.apiName,...config });
constructor(private restService: RestService) {}
}

View File

@ -1,4 +1,5 @@
import type { FullAuditedEntity } from '../../volo/abp/domain/entities/auditing/models';
import type { WorkSchedule } from '../../global-enum/work-schedule.enum';
export interface DoctorDto extends FullAuditedEntity<string> {
id?: string;
@ -12,4 +13,12 @@ export interface DoctorDto extends FullAuditedEntity<string> {
email?: string;
dob?: string;
education?: string;
specialization?: string;
degree?: string;
joiningDate?: string;
experience?: number;
consultationFee?: number;
availability?: WorkSchedule;
rating?: number;
clinicLocation?: string;
}

View File

@ -1,3 +1,4 @@
import type { WorkSchedule } from '../global-enum/work-schedule.enum';
import type { FullAuditedEntity } from '../volo/abp/domain/entities/auditing/models';
export interface CreateDepartmentDto {
@ -11,6 +12,7 @@ export interface CreateDepartmentDto {
}
export interface CreateDoctorDto {
id?: string;
firstName?: string;
lastName?: string;
gender?: string;
@ -22,6 +24,14 @@ export interface CreateDoctorDto {
email?: string;
dob?: string;
education?: string;
specialization?: string;
degree?: string;
joiningDate?: string;
experience?: number;
consultationFee?: number;
availability?: WorkSchedule;
rating?: number;
clinicLocation?: string;
}
export interface DepartmentDto extends FullAuditedEntity<string> {

View File

@ -1404,22 +1404,7 @@
"isIntegrationService": false,
"apiVersion": null,
"type": "HospitalManagementSystem.Doctors.DoctorAppService",
"interfaces": [
{
"type": "HospitalManagementSystem.Doctors.IDoctorAppService",
"name": "IDoctorAppService",
"methods": [
{
"name": "GetAsync",
"parametersOnMethod": [],
"returnValue": {
"type": "System.Collections.Generic.List<HospitalManagementSystem.Doctors.Dto.DoctorDto>",
"typeSimple": "[HospitalManagementSystem.Doctors.Dto.DoctorDto]"
}
}
]
}
],
"interfaces": [],
"actions": {
"GetAsync": {
"uniqueName": "GetAsync",
@ -1434,13 +1419,138 @@
"typeSimple": "[HospitalManagementSystem.Doctors.Dto.DoctorDto]"
},
"allowAnonymous": null,
"implementFrom": "HospitalManagementSystem.Doctors.IDoctorAppService"
"implementFrom": "HospitalManagementSystem.Doctors.DoctorAppService"
},
"CreateAsyncByInput": {
"uniqueName": "CreateAsyncByInput",
"name": "CreateAsync",
"GetDoctorListAsyncByInput": {
"uniqueName": "GetDoctorListAsyncByInput",
"name": "GetDoctorListAsync",
"httpMethod": "GET",
"url": "api/app/doctor/doctor-list",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "HospitalManagementSystem.Dto.PagingSortResultDto, HospitalManagementSystem.Domain.Shared",
"type": "HospitalManagementSystem.Dto.PagingSortResultDto",
"typeSimple": "HospitalManagementSystem.Dto.PagingSortResultDto",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "input",
"name": "Search",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "Sorting",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "SkipCount",
"jsonName": null,
"type": "System.Int32",
"typeSimple": "number",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "MaxResultCount",
"jsonName": null,
"type": "System.Int32",
"typeSimple": "number",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
}
],
"returnValue": {
"type": "Abp.Application.Services.Dto.PagedResultDto<HospitalManagementSystem.Doctors.Dto.DoctorDto>",
"typeSimple": "Abp.Application.Services.Dto.PagedResultDto<HospitalManagementSystem.Doctors.Dto.DoctorDto>"
},
"allowAnonymous": false,
"implementFrom": "HospitalManagementSystem.Doctors.DoctorAppService"
},
"GetDoctorByIdAsyncById": {
"uniqueName": "GetDoctorByIdAsyncById",
"name": "GetDoctorByIdAsync",
"httpMethod": "GET",
"url": "api/app/doctor/{id}/doctor-by-id",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "id",
"typeAsString": "System.Guid, System.Private.CoreLib",
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "id",
"name": "id",
"jsonName": null,
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": [],
"bindingSourceId": "Path",
"descriptorName": ""
}
],
"returnValue": {
"type": "HospitalManagementSystem.Doctors.Dto.DoctorDto",
"typeSimple": "HospitalManagementSystem.Doctors.Dto.DoctorDto"
},
"allowAnonymous": false,
"implementFrom": "HospitalManagementSystem.Doctors.DoctorAppService"
},
"GetExportDoctorsRecordAsync": {
"uniqueName": "GetExportDoctorsRecordAsync",
"name": "GetExportDoctorsRecordAsync",
"httpMethod": "GET",
"url": "api/app/doctor/export-doctors-record",
"supportedVersions": [],
"parametersOnMethod": [],
"parameters": [],
"returnValue": {
"type": "HospitalManagementSystem.Dto.FileDownloadDto",
"typeSimple": "HospitalManagementSystem.Dto.FileDownloadDto"
},
"allowAnonymous": false,
"implementFrom": "HospitalManagementSystem.Doctors.DoctorAppService"
},
"CreateDoctorAsyncByInput": {
"uniqueName": "CreateDoctorAsyncByInput",
"name": "CreateDoctorAsync",
"httpMethod": "POST",
"url": "api/app/doctor",
"url": "api/app/doctor/doctor",
"supportedVersions": [],
"parametersOnMethod": [
{
@ -1467,10 +1577,84 @@
}
],
"returnValue": {
"type": "HospitalManagementSystem.Doctors.Dto.DoctorDto",
"typeSimple": "HospitalManagementSystem.Doctors.Dto.DoctorDto"
"type": "System.Void",
"typeSimple": "System.Void"
},
"allowAnonymous": null,
"allowAnonymous": false,
"implementFrom": "HospitalManagementSystem.Doctors.DoctorAppService"
},
"UpdatDoctorAsyncByInput": {
"uniqueName": "UpdatDoctorAsyncByInput",
"name": "UpdatDoctorAsync",
"httpMethod": "POST",
"url": "api/app/doctor/updat-doctor",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "HospitalManagementSystem.Dtos.CreateDoctorDto, HospitalManagementSystem.Application",
"type": "HospitalManagementSystem.Dtos.CreateDoctorDto",
"typeSimple": "HospitalManagementSystem.Dtos.CreateDoctorDto",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "input",
"name": "input",
"jsonName": null,
"type": "HospitalManagementSystem.Dtos.CreateDoctorDto",
"typeSimple": "HospitalManagementSystem.Dtos.CreateDoctorDto",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "Body",
"descriptorName": ""
}
],
"returnValue": {
"type": "System.Void",
"typeSimple": "System.Void"
},
"allowAnonymous": false,
"implementFrom": "HospitalManagementSystem.Doctors.DoctorAppService"
},
"DeleteDoctorRecordAsyncById": {
"uniqueName": "DeleteDoctorRecordAsyncById",
"name": "DeleteDoctorRecordAsync",
"httpMethod": "DELETE",
"url": "api/app/doctor/{id}/doctor-record",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "id",
"typeAsString": "System.Guid, System.Private.CoreLib",
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "id",
"name": "id",
"jsonName": null,
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": [],
"bindingSourceId": "Path",
"descriptorName": ""
}
],
"returnValue": {
"type": "System.Void",
"typeSimple": "System.Void"
},
"allowAnonymous": false,
"implementFrom": "HospitalManagementSystem.Doctors.DoctorAppService"
}
}
@ -5447,6 +5631,18 @@
{
"name": "DOB",
"jsonName": null,
"type": "System.DateTime?",
"typeSimple": "string?",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "Education",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isRequired": false,
@ -5457,7 +5653,91 @@
"regex": null
},
{
"name": "Education",
"name": "Specialization",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "Degree",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "JoiningDate",
"jsonName": null,
"type": "System.DateTime?",
"typeSimple": "string?",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "Experience",
"jsonName": null,
"type": "System.Int32?",
"typeSimple": "number?",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "ConsultationFee",
"jsonName": null,
"type": "System.Decimal?",
"typeSimple": "number?",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "Availability",
"jsonName": null,
"type": "HospitalManagementSystem.GlobalEnum.WorkSchedule?",
"typeSimple": "HospitalManagementSystem.GlobalEnum.WorkSchedule?",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "Rating",
"jsonName": null,
"type": "System.Decimal?",
"typeSimple": "number?",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "ClinicLocation",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
@ -5750,6 +6030,18 @@
"enumValues": null,
"genericArguments": null,
"properties": [
{
"name": "Id",
"jsonName": null,
"type": "System.Guid",
"typeSimple": "string",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "FirstName",
"jsonName": null,
@ -5861,6 +6153,18 @@
{
"name": "DOB",
"jsonName": null,
"type": "System.DateTime?",
"typeSimple": "string?",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "Education",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isRequired": false,
@ -5871,7 +6175,91 @@
"regex": null
},
{
"name": "Education",
"name": "Specialization",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "Degree",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "JoiningDate",
"jsonName": null,
"type": "System.DateTime?",
"typeSimple": "string?",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "Experience",
"jsonName": null,
"type": "System.Int32?",
"typeSimple": "number?",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "ConsultationFee",
"jsonName": null,
"type": "System.Decimal?",
"typeSimple": "number?",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "Availability",
"jsonName": null,
"type": "HospitalManagementSystem.GlobalEnum.WorkSchedule?",
"typeSimple": "HospitalManagementSystem.GlobalEnum.WorkSchedule?",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "Rating",
"jsonName": null,
"type": "System.Decimal?",
"typeSimple": "number?",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "ClinicLocation",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
@ -6041,6 +6429,58 @@
"genericArguments": null,
"properties": null
},
"HospitalManagementSystem.GlobalEnum.WorkSchedule": {
"baseType": "System.Enum",
"isEnum": true,
"enumNames": [
"MondayToFriday",
"TuesdayToSaturday",
"WednesdayToSunday",
"ThursdayToMonday",
"FridayToTuesday",
"SaturdayToWednesday",
"SundayToThursday",
"MondayToThursday",
"TuesdayToFriday",
"WednesdayToSaturday",
"ThursdayToSunday",
"FridayToMonday",
"SaturdayToTuesday",
"SundayToWednesday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
],
"enumValues": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21
],
"genericArguments": null,
"properties": null
},
"HospitalManagementSystem.Patients.Dto.CreateUpdatePatientDto": {
"baseType": null,
"isEnum": false,
@ -6794,6 +7234,41 @@
}
]
},
"System.Nullable<T0>": {
"baseType": "System.ValueType",
"isEnum": false,
"enumNames": null,
"enumValues": null,
"genericArguments": [
"T"
],
"properties": [
{
"name": "HasValue",
"jsonName": null,
"type": "System.Boolean",
"typeSimple": "boolean",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
},
{
"name": "Value",
"jsonName": null,
"type": "T",
"typeSimple": "T",
"isRequired": false,
"minLength": null,
"maxLength": null,
"minimum": null,
"maximum": null,
"regex": null
}
]
},
"Volo.Abp.Account.ChangePasswordInput": {
"baseType": null,
"isEnum": false,

View File

@ -3,3 +3,4 @@ export * from './gender.enum';
export * from './payment-status.enum';
export * from './status.enum';
export * from './visit-type.enum';
export * from './work-schedule.enum';

View File

@ -0,0 +1,27 @@
import { mapEnumToOptions } from '@abp/ng.core';
export enum WorkSchedule {
MondayToFriday = 1,
TuesdayToSaturday = 2,
WednesdayToSunday = 3,
ThursdayToMonday = 4,
FridayToTuesday = 5,
SaturdayToWednesday = 6,
SundayToThursday = 7,
MondayToThursday = 8,
TuesdayToFriday = 9,
WednesdayToSaturday = 10,
ThursdayToSunday = 11,
FridayToMonday = 12,
SaturdayToTuesday = 13,
SundayToWednesday = 14,
Monday = 15,
Tuesday = 16,
Wednesday = 17,
Thursday = 18,
Friday = 19,
Saturday = 20,
Sunday = 21,
}
export const workScheduleOptions = mapEnumToOptions(WorkSchedule);

View File

@ -76,7 +76,21 @@ function configureRoutes(routesService: RoutesService) {
order: 302,
requiredPolicy:'HospitalManagementSystem.Department'
},
{
path: '',
name: 'Doctors',
order: 401,
iconClass: 'fas fa-user-md',
layout: eLayoutType.application,
},
{
path: '/doctors',
name: 'All Doctors',
parentName: 'Doctors',
iconClass: 'fas fa-clock',
order: 402,
requiredPolicy:'HospitalManagementSystem.Doctor'
},
]);
};
}

View File

@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<title>HospitalManagementSystem</title>
<title>Hospital Management System</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

View File

@ -1,4 +1,5 @@
using System;
using HospitalManagementSystem.GlobalEnum;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -18,7 +19,15 @@ namespace HospitalManagementSystem.Doctors.Dto
public Guid? DepartmentId { get; set; }
public string? Address { get; set; }
public string? Email { get; set; }
public string? DOB { get; set; }
public DateTime? DOB { get; set; }
public string? Education { get; set; }
public string? Specialization { get; set; }
public string? Degree { get; set; }
public DateTime? JoiningDate { get; set; }
public int? Experience { get; set; }
public decimal? ConsultationFee { get; set; }
public WorkSchedule? Availability { get; set; }
public decimal? Rating { get; set; }
public string? ClinicLocation { get; set; }
}
}

View File

@ -21,7 +21,11 @@ public class HospitalManagementSystemPermissionDefinitionProvider : PermissionDe
DepartmentPermission.AddChild(HospitalManagementSystemPermissions.Department.Edit);
DepartmentPermission.AddChild(HospitalManagementSystemPermissions.Department.Delete);
//Doctors
var DoctorsPermission = HostipalManagementGroup.AddPermission(HospitalManagementSystemPermissions.Doctor.Default);
DoctorsPermission.AddChild(HospitalManagementSystemPermissions.Doctor.Create);
DoctorsPermission.AddChild(HospitalManagementSystemPermissions.Doctor.Edit);
DoctorsPermission.AddChild(HospitalManagementSystemPermissions.Doctor.Delete);

View File

@ -20,4 +20,11 @@ public static class HospitalManagementSystemPermissions
public const string Edit = Default + ".Edit";
public const string Delete = Default + ".Delete";
}
public static class Doctor
{
public const string Default = GroupName + ".Doctor";
public const string Create = Default + ".Create";
public const string Edit = Default + ".Edit";
public const string Delete = Default + ".Delete";
}
}

View File

@ -1,19 +1,34 @@
using HospitalManagementSystem.Departments;
using Abp.Application.Services.Dto;
using ClosedXML.Excel;
using HospitalManagementSystem.Departments;
using HospitalManagementSystem.Doctors.Dto;
using HospitalManagementSystem.Dto;
using HospitalManagementSystem.Dtos;
using HospitalManagementSystem.Permissions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
using System.IO;
using System.Linq;
using System.Linq.Dynamic.Core;
using Abp.UI;
namespace HospitalManagementSystem.Doctors
{
public class DoctorAppService : ApplicationService, IDoctorAppService
public class DoctorAppService : ApplicationService
{
private readonly IRepository<Doctor, Guid> _doctorRepository;
public DoctorAppService(IRepository<Doctor, Guid> doctorRepository)
private readonly IWebHostEnvironment _env;
public DoctorAppService(IRepository<Doctor, Guid> doctorRepository, IWebHostEnvironment env)
{
_doctorRepository = doctorRepository;
_env = env;
}
public async Task<List<DoctorDto>> GetAsync()
{
@ -22,11 +37,160 @@ namespace HospitalManagementSystem.Doctors
doctorDtos = ObjectMapper.Map<List<Doctor>, List<DoctorDto>>(data);
return doctorDtos;
}
public async Task<DoctorDto> CreateAsync(CreateDoctorDto input)
//public async Task<DoctorDto> CreateAsync(CreateDoctorDto input)
//{
// var doctor = new Doctor(Guid.NewGuid(), input.FirstName, input.LastName, input.Gender, input.Mobile, input.Password, input.Designation, input.DepartmentId, input.Address, input.Email, input.DOB, input.Education);
// await _doctorRepository.InsertAsync(doctor);
// return ObjectMapper.Map<Doctor, DoctorDto>(doctor);
//}
#region Get Doctors List with Paging and Searching
[Authorize(HospitalManagementSystemPermissions.Doctor.Default)]
public async Task<PagedResultDto<DoctorDto>> GetDoctorListAsync(PagingSortResultDto input)
{
var doctor = new Doctor(Guid.NewGuid(), input.FirstName, input.LastName, input.Gender, input.Mobile, input.Password, input.Designation, input.DepartmentId, input.Address, input.Email, input.DOB, input.Education);
await _doctorRepository.InsertAsync(doctor);
var queryable = await _doctorRepository.GetQueryableAsync();
var filteredQuery = queryable
.WhereIf(!string.IsNullOrEmpty(input.Search), x => x.FirstName.ToLower().Contains(input.Search.ToLower()) || x.LastName.ToLower().Contains(input.Search.ToLower()) || x.Mobile.ToLower().Contains(input.Search.ToLower()));
var totalCount = await filteredQuery.CountAsync();
filteredQuery = !string.IsNullOrEmpty(input.Sorting)
? filteredQuery.OrderBy(input.Sorting)
: filteredQuery.OrderBy(x => x.Id);
var pagedQuery = await filteredQuery
.Skip(input.SkipCount)
.Take(input.MaxResultCount)
.ToListAsync();
var doctorDto = ObjectMapper.Map<List<Doctor>, List<DoctorDto>>(pagedQuery);
return new PagedResultDto<DoctorDto>(
totalCount,
doctorDto
);
}
#endregion
#region Get Doctors by ID
[Authorize(HospitalManagementSystemPermissions.Doctor.Default)]
public async Task<DoctorDto> GetDoctorByIdAsync(Guid id)
{
var doctor = await _doctorRepository.FirstOrDefaultAsync(x => x.Id == id);
if (doctor == null)
{
throw new UserFriendlyException("Doctor Details not found");
}
return ObjectMapper.Map<Doctor, DoctorDto>(doctor);
}
#endregion
#region Export Doctors Data to Excel
[Authorize(HospitalManagementSystemPermissions.Doctor.Default)]
public async Task<FileDownloadDto> GetExportDoctorsRecordAsync()
{
var DoctorRecord = await _doctorRepository.ToListAsync();
var folderPath = Path.Combine(_env.WebRootPath, "temp");
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
var filename = "Doctors_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".xlsx";
var filePath = Path.Combine(folderPath, filename);
// Create a workbook and worksheet
using (var workbook = new XLWorkbook())
{
var worksheet = workbook.Worksheets.Add("Doctor");
// Add headers
worksheet.Cell(1, 1).Value = "Name";
worksheet.Cell(1, 2).Value = "Email";
worksheet.Cell(1, 3).Value = "Specialization";
worksheet.Cell(1, 4).Value = "Date";
worksheet.Cell(1, 5).Value = "Department";
worksheet.Cell(1, 6).Value = "Mobile";
worksheet.Cell(1, 7).Value = "Degree";
worksheet.Cell(1, 8).Value = "Experience Years";
worksheet.Cell(1, 9).Value = "Fees";
worksheet.Cell(1, 10).Value = "Availability";
worksheet.Cell(1, 11).Value = "Rating";
worksheet.Cell(1, 12).Value = "Clinic Location";
for (int i = 0; i < DoctorRecord.Count; i++)
{
worksheet.Cell(i + 2, 1).Value = DoctorRecord[i].FirstName+" "+ DoctorRecord[i].LastName;
worksheet.Cell(i + 2, 2).Value = DoctorRecord[i].Email;
worksheet.Cell(i + 2, 3).Value = DoctorRecord[i].Specialization;
worksheet.Cell(i + 2, 4).Value = DoctorRecord[i].JoiningDate?.ToShortDateString();
worksheet.Cell(i + 2, 5).Value = DoctorRecord[i].Department.DepartmentName;
worksheet.Cell(i + 2, 6).Value = DoctorRecord[i].Mobile;
worksheet.Cell(i + 2, 6).Value = DoctorRecord[i].Degree;
worksheet.Cell(i + 2, 6).Value = DoctorRecord[i].Experience;
worksheet.Cell(i + 2, 6).Value = DoctorRecord[i].ConsultationFee;
worksheet.Cell(i + 2, 6).Value = DoctorRecord[i].Availability.ToString();
worksheet.Cell(i + 2, 6).Value = DoctorRecord[i].Rating;
worksheet.Cell(i + 2, 6).Value = DoctorRecord[i].ClinicLocation;
}
worksheet.Columns().AdjustToContents();
workbook.SaveAs(filePath);
}
byte[] fileBytes = await File.ReadAllBytesAsync(filePath);
File.Delete(filePath);
return new FileDownloadDto
{
FileName = filename,
FileContent = Convert.ToBase64String(fileBytes)
};
}
#endregion
#region Create Doctors
[Authorize(HospitalManagementSystemPermissions.Doctor.Create)]
public async Task CreateDoctorAsync(CreateDoctorDto input)
{
var newdata = ObjectMapper.Map<CreateDoctorDto, Doctor>(input);
await _doctorRepository.InsertAsync(newdata);
}
#endregion
#region Update Doctors
[Authorize(HospitalManagementSystemPermissions.Doctor.Edit)]
public async Task UpdatDoctorAsync(CreateDoctorDto input)
{
try
{
var newdata = ObjectMapper.Map<CreateDoctorDto, Doctor>(input);
await _doctorRepository.UpdateAsync(newdata);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
#endregion
#region Delete Doctors
[Authorize(HospitalManagementSystemPermissions.Doctor.Delete)]
public async Task DeleteDoctorRecordAsync(Guid id)
{
await _doctorRepository.DeleteAsync(id);
}
#endregion
}
}

View File

@ -1,4 +1,5 @@
using HospitalManagementSystem.Enums;
using HospitalManagementSystem.GlobalEnum;
using System;
using System.Collections.Generic;
using System.Linq;
@ -9,6 +10,8 @@ namespace HospitalManagementSystem.Dtos
{
public class CreateDoctorDto
{
public Guid Id { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? Gender { get; set; }
@ -18,7 +21,15 @@ namespace HospitalManagementSystem.Dtos
public Guid? DepartmentId { get; set; }
public string? Address { get; set; }
public string? Email { get; set; }
public string? DOB { get; set; }
public DateTime? DOB { get; set; }
public string? Education { get; set; }
public string? Specialization { get; set; }
public string? Degree { get; set; }
public DateTime? JoiningDate { get; set; }
public int? Experience { get; set; }
public decimal? ConsultationFee { get; set; }
public WorkSchedule? Availability { get; set; }
public decimal? Rating { get; set; }
public string? ClinicLocation { get; set; }
}
}

View File

@ -50,6 +50,8 @@ namespace HospitalManagementSystem
#region Doctor
CreateMap<Doctor, DoctorDto>();
CreateMap<DoctorDto, Doctor>();
CreateMap<Doctor, CreateDoctorDto>();
CreateMap<CreateDoctorDto, Doctor>();
#endregion
}
}

View File

@ -31,12 +31,12 @@ namespace HospitalManagementSystem.Patients
private IRepository<Patient, Guid> _patientRepository;
private IRepository<EntityDocument, Guid> _entityDocumentRepository;
private IRepository<PatientDocument, Guid> _patientDocumentRepository;
private IRepository<Doctor, Guid> _doctorrepository;
private IRepository<Doctors.Doctor, Guid> _doctorrepository;
private readonly IWebHostEnvironment _env;
private SharedAppService _sharedappService;
List<Guid> uniqueid = new List<Guid>();
public PatientAppService(IRepository<PatientRecord, Guid> patientrecordRepository, IRepository<Patient, Guid> patientRepository, IWebHostEnvironment env, IRepository<EntityDocument, Guid> entityDocumentRepository, IRepository<PatientDocument, Guid> patientDocumentRepository, SharedAppService sharedappService, IRepository<Doctor, Guid> doctorrepository)
public PatientAppService(IRepository<PatientRecord, Guid> patientrecordRepository, IRepository<Patient, Guid> patientRepository, IWebHostEnvironment env, IRepository<EntityDocument, Guid> entityDocumentRepository, IRepository<PatientDocument, Guid> patientDocumentRepository, SharedAppService sharedappService, IRepository<Doctors.Doctor, Guid> doctorrepository)
{
_patientrecordRepository = patientrecordRepository;
_patientRepository = patientRepository;

View File

@ -37,4 +37,30 @@ namespace HospitalManagementSystem.GlobalEnum
Unpaid = 3,
}
public enum WorkSchedule
{
MondayToFriday = 1,
TuesdayToSaturday = 2,
WednesdayToSunday = 3,
ThursdayToMonday = 4,
FridayToTuesday = 5,
SaturdayToWednesday = 6,
SundayToThursday = 7,
MondayToThursday = 8,
TuesdayToFriday = 9,
WednesdayToSaturday = 10,
ThursdayToSunday = 11,
FridayToMonday = 12,
SaturdayToTuesday = 13,
SundayToWednesday = 14,
Monday = 15,
Tuesday = 16,
Wednesday = 17,
Thursday = 18,
Friday = 19,
Saturday = 20,
Sunday = 21
}
}

View File

@ -1,6 +1,7 @@
using HospitalManagementSystem.Appointments;
using HospitalManagementSystem.Departments;
using HospitalManagementSystem.Enums;
using HospitalManagementSystem.GlobalEnum;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
@ -21,8 +22,16 @@ namespace HospitalManagementSystem.Doctors
public virtual Department? Department { get; set; }
public string? Address { get; set; }
public string? Email { get; set; }
public string? DOB { get; set; }
public DateTime? DOB { get; set; }
public string? Education { get; set; }
public string? Specialization { get; set; }
public string? Degree { get; set; }
public DateTime? JoiningDate { get; set; }
public int? Experience { get; set; }
public decimal? ConsultationFee { get; set; }
public WorkSchedule? Availability { get; set; }
public decimal? Rating { get; set; }
public string? ClinicLocation { get; set; }
public virtual ICollection<Appointment> Appointments { get; set; } = new List<Appointment>();
public Doctor()
{
@ -31,7 +40,7 @@ namespace HospitalManagementSystem.Doctors
public Doctor(Guid id, string? firstName, string? lastName,
string? gender, string? mobile, string? password,
string? designation, Guid? departmentId, string? address,
string? email, string? dOB, string? education) : base(id)
string? email, DateTime? dOB, string? education) : base(id)
{
FirstName = firstName;
LastName = lastName;

View File

@ -0,0 +1,99 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace HospitalManagementSystem.Migrations
{
/// <inheritdoc />
public partial class modify_doctor : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "Availability",
table: "Doctors",
type: "int",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "ClinicLocation",
table: "Doctors",
type: "nvarchar(max)",
nullable: true);
migrationBuilder.AddColumn<decimal>(
name: "ConsultationFee",
table: "Doctors",
type: "decimal(18,2)",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "Degree",
table: "Doctors",
type: "nvarchar(max)",
nullable: true);
migrationBuilder.AddColumn<int>(
name: "Experience",
table: "Doctors",
type: "int",
nullable: true);
migrationBuilder.AddColumn<DateTime>(
name: "JoiningDate",
table: "Doctors",
type: "datetime2",
nullable: true);
migrationBuilder.AddColumn<decimal>(
name: "Rating",
table: "Doctors",
type: "decimal(18,2)",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "Specialization",
table: "Doctors",
type: "nvarchar(max)",
nullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Availability",
table: "Doctors");
migrationBuilder.DropColumn(
name: "ClinicLocation",
table: "Doctors");
migrationBuilder.DropColumn(
name: "ConsultationFee",
table: "Doctors");
migrationBuilder.DropColumn(
name: "Degree",
table: "Doctors");
migrationBuilder.DropColumn(
name: "Experience",
table: "Doctors");
migrationBuilder.DropColumn(
name: "JoiningDate",
table: "Doctors");
migrationBuilder.DropColumn(
name: "Rating",
table: "Doctors");
migrationBuilder.DropColumn(
name: "Specialization",
table: "Doctors");
}
}
}

View File

@ -0,0 +1,37 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace HospitalManagementSystem.Migrations
{
/// <inheritdoc />
public partial class modify_DOB_Doctor : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<DateTime>(
name: "DOB",
table: "Doctors",
type: "datetime2",
nullable: true,
oldClrType: typeof(string),
oldType: "nvarchar(max)",
oldNullable: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "DOB",
table: "Doctors",
type: "nvarchar(max)",
nullable: true,
oldClrType: typeof(DateTime),
oldType: "datetime2",
oldNullable: true);
}
}
}

View File

@ -180,6 +180,15 @@ namespace HospitalManagementSystem.Migrations
b.Property<string>("Address")
.HasColumnType("nvarchar(max)");
b.Property<int?>("Availability")
.HasColumnType("int");
b.Property<string>("ClinicLocation")
.HasColumnType("nvarchar(max)");
b.Property<decimal?>("ConsultationFee")
.HasColumnType("decimal(18,2)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2")
.HasColumnName("CreationTime");
@ -188,7 +197,10 @@ namespace HospitalManagementSystem.Migrations
.HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId");
b.Property<string>("DOB")
b.Property<DateTime?>("DOB")
.HasColumnType("datetime2");
b.Property<string>("Degree")
.HasColumnType("nvarchar(max)");
b.Property<Guid?>("DeleterId")
@ -211,6 +223,9 @@ namespace HospitalManagementSystem.Migrations
b.Property<string>("Email")
.HasColumnType("nvarchar(max)");
b.Property<int?>("Experience")
.HasColumnType("int");
b.Property<string>("FirstName")
.HasColumnType("nvarchar(max)");
@ -223,6 +238,9 @@ namespace HospitalManagementSystem.Migrations
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("JoiningDate")
.HasColumnType("datetime2");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2")
.HasColumnName("LastModificationTime");
@ -240,6 +258,12 @@ namespace HospitalManagementSystem.Migrations
b.Property<string>("Password")
.HasColumnType("nvarchar(max)");
b.Property<decimal?>("Rating")
.HasColumnType("decimal(18,2)");
b.Property<string>("Specialization")
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.HasIndex("DepartmentId");