Merge branch 'AppointmentModule_Modified' of https://git.sentientgeeks.us/ranjit/Hospital_Management into AppointmentModule_Modified

This commit is contained in:
Sk Shaifat Murshed 2025-02-07 17:10:08 +05:30
commit d975c46a6f
18 changed files with 616 additions and 603 deletions

View File

@ -104,13 +104,14 @@
<ng-template pTemplate="header"> <ng-template pTemplate="header">
<tr class="table-dark"> <tr class="table-dark">
<th class="hidden" pSortableColumn="id">Patient ID <p-sortIcon field="id" /></th> <th class="hidden" pSortableColumn="id">Patient ID <p-sortIcon field="id" /></th>
<th pSortableColumn="patientCardId">Card ID <p-sortIcon field="patientCardId" /></th>
<th pSortableColumn="name">Full Name <p-sortIcon field="name" /></th> <th pSortableColumn="name">Full Name <p-sortIcon field="name" /></th>
<th pSortableColumn="gender">Gender <p-sortIcon field="gender" /></th> <th pSortableColumn="gender">Gender <p-sortIcon field="gender" /></th>
<th pSortableColumn="admissionDate">Date of Admission <p-sortIcon field="admissionDate" /></th>
<th pSortableColumn="bloodGroup">Blood Group <p-sortIcon field="bloodGroup" /></th> <th pSortableColumn="bloodGroup">Blood Group <p-sortIcon field="bloodGroup" /></th>
<th>Mobile</th> <th>Mobile</th>
<th>Age</th>
<th>Email</th> <th>Email</th>
<th pSortableColumn="status">Status <p-sortIcon field="status" /></th> <th pSortableColumn="insuranceProvider">Insurance <p-sortIcon field="insuranceProvider" /></th>
<th>Actions</th> <th>Actions</th>
</tr> </tr>
</ng-template> </ng-template>
@ -118,22 +119,18 @@
<ng-template pTemplate="body" let-patient> <ng-template pTemplate="body" let-patient>
<tr> <tr>
<td class="hidden">{{ patient.id }}</td> <td class="hidden">{{ patient.id }}</td>
<td>{{patient.patientCardId}}</td>
<td>{{ patient.name }}</td> <td>{{ patient.name }}</td>
<td> <td>
<span class="badge" [ngClass]="patient.gender === 1 ? 'bg-primary' : 'bg-pink'"> <span class="badge" [ngClass]="patient.gender === 1 ? 'bg-primary' : 'bg-pink'">
{{ gender[patient.gender] }} {{ gender[patient.gender] }}
</span> </span>
</td> </td>
<td>{{ patient.admissionDate | date }}</td>
<td>{{ patient.bloodGroup }}</td> <td>{{ patient.bloodGroup }}</td>
<td>{{ patient.mobile }}</td> <td>{{ patient.mobile }}</td>
<td>{{patient.age}}</td>
<td>{{ patient.email }}</td> <td>{{ patient.email }}</td>
<td> <td>{{patient.insuranceProvider}}</td>
<span class="badge"
[ngClass]="patient.status === 1 ? 'bg-success' : (patient.status === 2 ? 'bg-primary':'bg-danger')">
{{ status[patient.status] }}
</span>
</td>
<td class="d-flex gap-1"> <td class="d-flex gap-1">
<button *ngIf="createpermission" class="btn btn-success btn-sm" <button *ngIf="createpermission" class="btn btn-success btn-sm"
(click)="addnewrecord(patient.id)"> (click)="addnewrecord(patient.id)">
@ -170,9 +167,23 @@
placeholder="Enter full patient name" required #name="ngModel" /> placeholder="Enter full patient name" required #name="ngModel" />
<small *ngIf="name.invalid && name.touched" class="p-error">Full Name is required</small> <small *ngIf="name.invalid && name.touched" class="p-error">Full Name is required</small>
</div> </div>
</div>
<div class="col-6">
<div class="field">
<label for="age">Age</label>
<input id="age" name="age" type="number" pInputText [(ngModel)]="selectedPatient.age"
placeholder="Enter age" required min="1" max="120" #age="ngModel" />
<small *ngIf="age.invalid && age.touched" class="p-error">
Age is required and must be between 1 and 90
</small>
</div>
</div>
</div>
<div class="p-fluid grid">
<div class="col-6">
<div class="field"> <div class="field">
<label for="image"><i class="pi pi-image"></i> Profile Image</label> <label for="image"><i class="pi pi-image"></i> Profile Image</label>
<input type="file" id="image" name="image" accept=".jpg,.png" <input class="d-flex" type="file" id="image" name="image" accept=".jpg,.png"
(change)="profileimageupload($event)" /> (change)="profileimageupload($event)" />
</div> </div>
<small *ngIf="error !== ''" class="p-error">{{error}}</small> <small *ngIf="error !== ''" class="p-error">{{error}}</small>
@ -181,30 +192,16 @@
<progress [value]="uploadProgress" max="100"></progress> <progress [value]="uploadProgress" max="100"></progress>
</div> </div>
<small *ngIf="imgpath !== ''">{{imgpath}} <i class="pi pi-image"></i></small> <small *ngIf="imgpath !== ''">{{imgpath}} <i class="pi pi-image"></i></small>
</div> <!-- <div class="col-6">
<!-- Mobile & Address -->
<div class="col-6">
<div class="field"> <div class="field">
<label for="mobile"><i class="pi pi-phone"></i> Mobile</label> <label for="status">Status</label>
<input id="mobile" name="mobile" type="text" pInputText [(ngModel)]="selectedPatient.mobile" <p-dropdown name="status" id="status" [options]="statuslist" [(ngModel)]="selectedstatus"
placeholder="Enter mobile number" maxlength="10" required pattern="[0-9]{10}" optionLabel="label" optionValue="value" placeholder="Select status"
#mobile="ngModel" /> required></p-dropdown>
<small *ngIf="mobile.invalid && mobile.touched" class="p-error"> <small *ngIf="selectedstatus === 0" class="p-error">Status is required</small>
Mobile is required and must be 10 digits
</small>
</div> </div>
<div class="field"> </div> -->
<label for="address"><i class="pi pi-map-marker"></i> Address</label>
<input id="address" name="address" type="text" pInputText [(ngModel)]="selectedPatient.address"
placeholder="Enter address" required #address="ngModel" />
<small *ngIf="address.invalid && address.touched" class="p-error">Address is required</small>
</div> </div>
</div>
</div>
<div class="p-fluid grid">
<!-- Gender & Admission Date -->
<div class="col-6"> <div class="col-6">
<div class="field"> <div class="field">
<label for="gender"><i class="pi pi-users"></i> Gender</label> <label for="gender"><i class="pi pi-users"></i> Gender</label>
@ -223,7 +220,32 @@
<small *ngIf="!selectedgender" class="p-error">Gender is required</small> <small *ngIf="!selectedgender" class="p-error">Gender is required</small>
</div> </div>
</div> </div>
</div>
<div class="p-fluid grid">
<!-- Mobile & Address -->
<div class="col-6"> <div class="col-6">
<div class="field">
<label for="mobile"><i class="pi pi-phone"></i> Mobile</label>
<input id="mobile" name="mobile" type="text" pInputText [(ngModel)]="selectedPatient.mobile"
placeholder="Enter mobile number" maxlength="10" required pattern="[0-9]{10}"
#mobile="ngModel" />
<small *ngIf="mobile.invalid && mobile.touched" class="p-error">
Mobile is required and must be 10 digits
</small>
</div>
</div>
<div class="col-6">
<div class="field">
<label for="address"><i class="pi pi-map-marker"></i> Address</label>
<input id="address" name="address" type="text" pInputText [(ngModel)]="selectedPatient.address"
placeholder="Enter address" required #address="ngModel" />
<small *ngIf="address.invalid && address.touched" class="p-error">Address is
required</small>
</div>
</div>
</div>
<!-- <div class="p-fluid grid"> -->
<!-- <div class="col-6">
<div class="field"> <div class="field">
<label for="admissionDate"><i class="pi pi-calendar"></i> Admission Date</label> <label for="admissionDate"><i class="pi pi-calendar"></i> Admission Date</label>
<p-calendar appendTo="body" id="admissionDate" name="admissionDate" [(ngModel)]="selectadmissionDate" showIcon <p-calendar appendTo="body" id="admissionDate" name="admissionDate" [(ngModel)]="selectadmissionDate" showIcon
@ -232,11 +254,10 @@
Admission Date is required Admission Date is required
</small> </small>
</div> </div>
</div> </div> -->
</div> <!-- </div> -->
<div class="p-fluid grid"> <!-- <div class="p-fluid grid">
<!-- Doctor & Treatment -->
<div class="col-6"> <div class="col-6">
<div class="field"> <div class="field">
<label for="doctorAssigned"><i class="pi pi-user-md"></i> Doctor Assigned</label> <label for="doctorAssigned"><i class="pi pi-user-md"></i> Doctor Assigned</label>
@ -251,7 +272,7 @@
[(ngModel)]="selectedPatient.treatment" placeholder="Enter treatment" /> [(ngModel)]="selectedPatient.treatment" placeholder="Enter treatment" />
</div> </div>
</div> </div>
</div> </div> -->
<div class="p-fluid grid"> <div class="p-fluid grid">
<!-- Blood Group & Email --> <!-- Blood Group & Email -->
@ -275,21 +296,34 @@
</div> </div>
</div> </div>
</div> </div>
<!-- Insurance Provider -->
<div class="p-fluid grid"> <div class="p-fluid grid">
<div class="col-6"> <div class="col-6">
<div class="field"> <div class="field">
<label for="status">Status</label> <label for="insuranceProvider"><i class="pi pi-credit-card"></i> Insurance Provider</label>
<p-dropdown name="status" id="status" [options]="statuslist" [(ngModel)]="selectedstatus" <input id="insuranceProvider" name="insuranceProvider" type="text" pInputText
optionLabel="label" optionValue="value" placeholder="Select status" [(ngModel)]="selectedPatient.insuranceProvider" required
required></p-dropdown> placeholder="Enter insurance provider" #insurance="ngModel" />
<small *ngIf="selectedstatus === 0" class="p-error">Status is required</small> <small *ngIf="insurance.invalid && insurance.touched" class="p-error">
Insurance is required.
</small>
</div>
</div>
<div class="col-6">
<div class="field">
<label for="patientCardId"><i class="pi pi-credit-card"></i> Card ID</label>
<input id="patientCardId" name="patientCardId" type="text" pInputText
[(ngModel)]="selectedPatient.patientCardId" required
placeholder="Enter patient card Id" #patientCardId="ngModel" />
<small *ngIf="patientCardId.invalid && patientCardId.touched" class="p-error">
Card Id is required.
</small>
</div> </div>
</div> </div>
</div> </div>
<div class="text-right"> <div class="text-right">
<button type="submit" pButton class="btn btn-primary" <button type="submit" pButton class="btn btn-primary"
[disabled]="(patientrecord.invalid || selectedstatus === 0 || !selectedgender)"> [disabled]="(patientrecord.invalid || !selectedgender)">
<i class="pi pi-check"></i> Save <i class="pi pi-check"></i> Save
</button> </button>
<button pButton class="btn btn-secondary ml-1" (click)="closeDialog()"> <button pButton class="btn btn-secondary ml-1" (click)="closeDialog()">

View File

@ -5,7 +5,7 @@ import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms'; import { NgForm } from '@angular/forms';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { PagingSortResultDto } from '@proxy/dto'; import { PagingSortResultDto } from '@proxy/dto';
import { Gender, Status } from '@proxy/global-enum'; import { Gender } from '@proxy/global-enum';
import { PatientService } from '@proxy/patients'; import { PatientService } from '@proxy/patients';
import { PatientDto, CreateUpdatePatientDto } from '@proxy/patients/dto'; import { PatientDto, CreateUpdatePatientDto } from '@proxy/patients/dto';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
@ -26,17 +26,13 @@ export class AllPatientsComponent implements OnInit {
isEditMode: boolean = false; isEditMode: boolean = false;
patientDialogTitle: string = ''; patientDialogTitle: string = '';
params: PagingSortResultDto; params: PagingSortResultDto;
status: any;
gender: any; gender: any;
statuslist: any;
selectedstatus: any = 0;
selectedgender: any = 0; selectedgender: any = 0;
selectadmissionDate: Date = new Date(); selectadmissionDate: Date = new Date();
selectdischargeDate: Date = new Date(); selectdischargeDate: Date = new Date();
createpermission: boolean; createpermission: boolean;
editpermission: boolean; editpermission: boolean;
deletepermission: boolean; deletepermission: boolean;
error: string = '';
imgpath: string = ''; imgpath: string = '';
guid: string = '00000000-0000-0000-0000-000000000000'; guid: string = '00000000-0000-0000-0000-000000000000';
uploadProgress = 0; uploadProgress = 0;
@ -60,11 +56,7 @@ export class AllPatientsComponent implements OnInit {
this.deletepermission = this.permissionChecker.getGrantedPolicy( this.deletepermission = this.permissionChecker.getGrantedPolicy(
'HospitalManagementSystem.Patient.Delete' 'HospitalManagementSystem.Patient.Delete'
); );
this.status = Status;
this.gender = Gender; this.gender = Gender;
this.patientService.getStatusDropdown().subscribe(result => {
this.statuslist = result;
});
this.resetselectpatient(); this.resetselectpatient();
this.loadPatient({ this.loadPatient({
@ -82,17 +74,11 @@ export class AllPatientsComponent implements OnInit {
mobile: '', mobile: '',
email: '', email: '',
age: 0, age: 0,
treatment: '',
doctorAssigned: '',
address: '', address: '',
bloodGroup: '', bloodGroup: '',
admissionDate: '',
dischargeDate: '',
status: Status.InTreatment,
}; };
this.imgpath = ''; this.imgpath = '';
this.selectedgender = 0; this.selectedgender = 0;
this.selectedstatus = 0;
this.uploadProgress = 0; this.uploadProgress = 0;
} }
@ -144,7 +130,6 @@ export class AllPatientsComponent implements OnInit {
this.patientDialogTitle = 'New Patient'; this.patientDialogTitle = 'New Patient';
this.resetselectpatient(); this.resetselectpatient();
this.selectedgender = 0; this.selectedgender = 0;
this.selectedstatus = 0;
this.patientDialog = true; this.patientDialog = true;
this.isEditMode = false; this.isEditMode = false;
} }
@ -154,11 +139,6 @@ export class AllPatientsComponent implements OnInit {
} }
profileimageupload(event: Event) { profileimageupload(event: Event) {
if (this.selectedPatient.name == '') {
this.error = 'Please Type a Name';
return;
}
this.error = '';
const input = event.target as HTMLInputElement; const input = event.target as HTMLInputElement;
if (input.files.length > 0) { if (input.files.length > 0) {
const tag = 'Image'; const tag = 'Image';
@ -172,12 +152,9 @@ export class AllPatientsComponent implements OnInit {
} }
UploadFileData(tag: string, formdata: FormData) { UploadFileData(tag: string, formdata: FormData) {
// this.patientService.uploadFile(tag, formdata).subscribe(result => {
// this.selectedPatient.imageID = result;
// });
const req = new HttpRequest( const req = new HttpRequest(
'POST', 'POST',
environment.apis.default.url + '/api/app/patient/upload-file', environment.apis.default.url + '/api/app/shared/upload-file',
formdata, formdata,
{ {
reportProgress: true, reportProgress: true,
@ -189,14 +166,12 @@ export class AllPatientsComponent implements OnInit {
event => { event => {
if (event.type === HttpEventType.UploadProgress) { if (event.type === HttpEventType.UploadProgress) {
this.uploadProgress = Math.round((event.loaded / event.total!) * 100); this.uploadProgress = Math.round((event.loaded / event.total!) * 100);
console.log(event.type, this.uploadProgress);
} else if (event.type === HttpEventType.Response) { } else if (event.type === HttpEventType.Response) {
this.uploadProgress = 100; this.uploadProgress = 100;
this.selectedPatient.imageID = event.body.toString(); this.selectedPatient.imageID = event.body.toString();
} }
}, },
error => { error => {
console.error('Upload failed', error);
this.uploadProgress = 0; this.uploadProgress = 0;
} }
); );
@ -208,9 +183,7 @@ export class AllPatientsComponent implements OnInit {
this.patientService.getPatientById(Patient.id).subscribe(result => { this.patientService.getPatientById(Patient.id).subscribe(result => {
this.selectedPatient = result; this.selectedPatient = result;
this.imgpath = result.imagepath != null ? result.imagepath.split('\\')[3] : ''; this.imgpath = result.imagepath != null ? result.imagepath.split('\\')[3] : '';
this.selectadmissionDate = new Date(this.selectedPatient.admissionDate);
this.selectedgender = this.selectedPatient.gender; this.selectedgender = this.selectedPatient.gender;
this.selectedstatus = this.selectedPatient.status;
}); });
this.patientDialog = true; this.patientDialog = true;
this.isEditMode = true; this.isEditMode = true;
@ -234,19 +207,14 @@ export class AllPatientsComponent implements OnInit {
} }
savePatient(form: NgForm) { savePatient(form: NgForm) {
console.log(form.controls);
if (form.invalid) { if (form.invalid) {
Object.values(form.controls).forEach(control => control.markAsTouched()); Object.values(form.controls).forEach(control => control.markAsTouched());
return; return;
} }
this.selectedPatient.gender = this.selectedgender; this.selectedPatient.gender = this.selectedgender;
this.selectedPatient.status = this.selectedstatus;
this.selectedPatient.admissionDate = this.selectadmissionDate.toDateString();
this.selectedPatient.dischargeDate = this.selectdischargeDate.toDateString();
this.selectedPatient.imageID = this.selectedPatient.imageID this.selectedPatient.imageID = this.selectedPatient.imageID
? this.selectedPatient.imageID.replace('"', '').replace('"', '') ? this.selectedPatient.imageID.replace('"', '').replace('"', '')
: this.guid; : this.guid;
console.log(this.selectedPatient);
if (this.isEditMode) { if (this.isEditMode) {
this.patientService.updatePatient(this.selectedPatient.id, this.selectedPatient).subscribe( this.patientService.updatePatient(this.selectedPatient.id, this.selectedPatient).subscribe(
@ -262,7 +230,6 @@ export class AllPatientsComponent implements OnInit {
}); });
}, },
error => { error => {
console.log(error);
this.closeDialog(); this.closeDialog();
} }
); );
@ -280,7 +247,6 @@ export class AllPatientsComponent implements OnInit {
}); });
}, },
error => { error => {
console.log(error);
this.closeDialog(); this.closeDialog();
} }
); );

View File

@ -1,11 +1,9 @@
<div class="patient-container"> <div class="patient-container">
<div class="patient-card"> <div class="patient-card">
<!-- Patient Image -->
<div class="patient-image"> <div class="patient-image">
<img [src]="patientImageUrl || 'assets/default-profile.png'" alt="Patient Image"> <img [src]="patientImageUrl" alt="Patient Image">
</div> </div>
<!-- Patient Information -->
<div class="patient-info"> <div class="patient-info">
<h2 class="patient-name">{{ patientdto?.name }}</h2> <h2 class="patient-name">{{ patientdto?.name }}</h2>
<div class="patient-details"> <div class="patient-details">
@ -25,23 +23,9 @@
<strong>Blood Group:</strong> {{ patientdto?.bloodGroup }} <strong>Blood Group:</strong> {{ patientdto?.bloodGroup }}
</div> </div>
<div class="info-item"> <div class="info-item">
<strong>Doctor:</strong> {{ patientdto?.doctorAssigned || 'N/A' }} <strong>Card ID:</strong> {{ patientdto?.patientCardId }}
</div>
<div class="info-item">
<strong>Admission:</strong> {{ patientdto?.admissionDate | date }}
</div>
<div class="info-item">
<strong>Discharge:</strong> {{ patientdto?.dischargeDate | date }}
</div>
<div class="info-item">
<strong>Treatment:</strong> {{ patientdto?.treatment || 'N/A' }}
</div>
<div class="info-item">
<strong>Status:</strong>
<span class="status">
{{ status[patientdto?.status] }}
</span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@ -61,11 +45,10 @@
<div class="flex justify-content-between align-items-center"> <div class="flex justify-content-between align-items-center">
<h3>{{'::PatientHeader' | abpLocalization}}</h3> <h3>{{'::PatientHeader' | abpLocalization}}</h3>
<div class="flex gap-2"> <div class="flex gap-2">
<button *ngIf="createpermission" pButton class="p-button-rounded p-button-success" <button *ngIf="createpermission" pButton class="btn btn-success btn-sm" (click)="openNewPatientDialog()">
(click)="openNewPatientDialog()">
<i class="pi pi-plus-circle"></i> <i class="pi pi-plus-circle"></i>
</button> </button>
<button pButton class="p-button-rounded p-button-warning" (click)="exportPatient()"> <button pButton class="btn btn-warning btn-sm" (click)="exportPatient()">
<i class="pi pi-download"></i> <i class="pi pi-download"></i>
</button> </button>
<span class="p-input-icon-left"> <span class="p-input-icon-left">
@ -82,12 +65,15 @@
<th class="hidden" pSortableColumn="id">Patient ID <p-sortIcon field="id" /></th> <th class="hidden" pSortableColumn="id">Patient ID <p-sortIcon field="id" /></th>
<th>Full Name</th> <th>Full Name</th>
<th>Gender</th> <th>Gender</th>
<th>Doctor</th>
<th pSortableColumn="dateOfAdmission">Date of Admission <p-sortIcon field="dateOfAdmission" /></th> <th pSortableColumn="dateOfAdmission">Date of Admission <p-sortIcon field="dateOfAdmission" /></th>
<th pSortableColumn="dischargeDate">Discharge Date <p-sortIcon field="dischargeDate" /></th>
<th pSortableColumn="nextFollowUp">Next Follow-Up <p-sortIcon field="nextFollowUp" /></th>
<th pSortableColumn="diagnosis">Diagnosis <p-sortIcon field="diagnosis" /></th> <th pSortableColumn="diagnosis">Diagnosis <p-sortIcon field="diagnosis" /></th>
<th>Lab Reports</th> <th>Lab Reports</th>
<th>Medications</th> <th>Medications</th>
<th pSortableColumn="nextFollowUp">Next Follow-Up <p-sortIcon field="nextFollowUp" /></th>
<th>Status</th> <th pSortableColumn="status">Status <p-sortIcon field="status" /></th>
<th>Actions</th> <th>Actions</th>
</tr> </tr>
</ng-template> </ng-template>
@ -101,15 +87,19 @@
{{ gender[patientrecord.patients.gender] }} {{ gender[patientrecord.patients.gender] }}
</span> </span>
</td> </td>
<td><span *ngIf="patientrecord.doctorAssigned !== null">{{'Dr. ' + patientrecord.doctorAssigned?.firstName + ' '
+
patientrecord.doctorAssigned?.lastName}}</span></td>
<td>{{ patientrecord.dateOfAdmission | date }}</td> <td>{{ patientrecord.dateOfAdmission | date }}</td>
<td>{{ patientrecord.dischargeDate | date }}</td>
<td>{{ patientrecord.nextFollowUp | date }}</td>
<td>{{ patientrecord.diagnosis }}</td> <td>{{ patientrecord.diagnosis }}</td>
<td><i class="pi pi-file-pdf text-danger"></i></td> <td><i class="pi pi-file-pdf text-danger"></i></td>
<td><i class="pi pi-file-pdf text-primary"></i></td> <td><i class="pi pi-file-pdf text-primary"></i></td>
<td>{{ patientrecord.nextFollowUp | date }}</td>
<td> <td>
<span class="badge" <span class="badge"
[ngClass]="patientrecord.patients.status === 1 ? 'bg-success' : (patientrecord.patients.status === 2 ? 'bg-primary':'bg-danger')"> [ngClass]="patientrecord.status === 1 ? 'bg-success' : (patientrecord.status === 2 ? 'bg-primary':'bg-danger')">
{{ status[patientrecord.patients.status] }} {{ status[patientrecord.status] }}
</span> </span>
</td> </td>
<td class="flex gap-2"> <td class="flex gap-2">
@ -136,38 +126,82 @@
[closable]="true" [style]="{width: '70%', height: 'auto'}"> [closable]="true" [style]="{width: '70%', height: 'auto'}">
<form #patientrecord="ngForm" (ngSubmit)="savePatient(patientrecord)" novalidate> <form #patientrecord="ngForm" (ngSubmit)="savePatient(patientrecord)" novalidate>
<div class="p-fluid grid"> <div class="p-fluid grid">
<!-- Admission Date -->
<div class="col-6"> <div class="col-6">
<div class="field"> <div class="field">
<label for="admissionDate"><i class="pi pi-calendar"></i> Admission Date</label> <label for="admissionDate"><i class="pi pi-calendar"></i> Admission Date <span
<p-calendar appendTo="body" id="admissionDate" name="admissionDate" [(ngModel)]="selectdateOfAdmission" showIcon required class="text-danger">*</span></label>
#admissionDate="ngModel"></p-calendar> <p-calendar appendTo="body" id="admissionDate" name="admissionDate" [(ngModel)]="selectdateOfAdmission"
showIcon required #admissionDate="ngModel"></p-calendar>
<small *ngIf="admissionDate.invalid && admissionDate.touched" class="p-error"> <small *ngIf="admissionDate.invalid && admissionDate.touched" class="p-error">
Admission Date is required. Admission Date is required.
</small> </small>
</div> </div>
</div> </div>
<!-- Next Follow-Up Date -->
<div class="col-6"> <div class="col-6">
<div class="field"> <div class="field">
<label for="nextFollowUp"><i class="pi pi-calendar-plus"></i> Next Follow-Up Date</label> <label for="nextFollowUp"><i class="pi pi-calendar-plus"></i> Next Follow-Up Date</label>
<p-calendar appendTo="body" id="nextFollowUp" name="nextFollowUp" [(ngModel)]="selectnextFollowUp" showIcon required <p-calendar appendTo="body" id="nextFollowUp" name="nextFollowUp" [(ngModel)]="selectnextFollowUp"
#nextFollowUp="ngModel"></p-calendar> showIcon></p-calendar>
<small *ngIf="nextFollowUp.invalid && nextFollowUp.touched" class="p-error"> </div>
Next Follow-Up Date is required. </div>
</small> </div>
<div class="p-fluid grid">
<div class="col-6">
<div class="field">
<label for="dischargeDate"><i class="pi pi-calendar"></i> Discharge Date</label>
<p-calendar appendTo="body" id="dischargeDate" name="dischargeDate" [(ngModel)]="selectdischargeDate"
showIcon></p-calendar>
</div>
</div>
<div class="col-6">
<div class="field">
<label for="status">Status <span class="text-danger">*</span></label>
<p-dropdown name="status" id="status" [options]="statuslist" [(ngModel)]="selectedstatus"
optionLabel="label" optionValue="value" placeholder="Select status" required></p-dropdown>
<small *ngIf="selectedstatus === 0" class="p-error">Status is required</small>
</div>
</div>
</div>
<div class="p-fluid grid">
<div class="col-6">
<div class="field">
<label for="doctorAssignedID">Consulting Doctor <span class="text-danger">*</span></label>
<p-dropdown id="doctorAssignedID" name="doctorAssignedID"
[(ngModel)]="selectedPatientRecord.doctorAssignedID" [options]="doctorOptions" placeholder="Select Doctor"
optionLabel="label" optionValue="value" required></p-dropdown>
</div> </div>
</div> </div>
</div> </div>
<div class="p-fluid">
<div class="field">
<label for="diagnosis"><i class="pi pi-heartbeat"></i> Diagnosis</label>
<textarea style="width: 100%; background-color: #fff; color: black;" id="diagnosis" name="diagnosis"
pInputTextarea rows="5" cols="30" [(ngModel)]="selectedPatientRecord.diagnosis"></textarea>
</div>
</div>
<div class="p-fluid">
<div class="field">
<label for="treatmentPlan"><i class="pi pi-heartbeat"></i> Treatment Plan</label>
<textarea style="width: 100%; background-color: #fff; color: black;" id="treatmentPlan" name="treatmentPlan"
pInputTextarea rows="5" cols="30" [(ngModel)]="selectedPatientRecord.treatmentPlan"></textarea>
</div>
</div>
<div class="p-fluid">
<div class="field">
<label for="doctorNotes"><i class="pi pi-heartbeat"></i> Doctor Notes</label>
<textarea style="width: 100%; background-color: #fff; color: black;" id="doctorNotes" name="doctorNotes"
pInputTextarea rows="5" cols="30" [(ngModel)]="selectedPatientRecord.doctorNotes"></textarea>
</div>
</div>
<hr>
<h3 class="mb-4">Documents</h3>
<!-- File Uploads --> <!-- File Uploads -->
<div class="p-fluid grid"> <div class="p-fluid grid">
<div class="col-6"> <div class="col-6">
<div class="field"> <div class="field">
<label for="labReport"><i class="pi pi-file-pdf"></i> Lab Report</label> <label for="labReport"><i class="pi pi-file-pdf"></i> Lab Report</label>
<input type="file" id="labReport" name="labReport" accept=".pdf,.doc,.docx" <input class="d-flex" type="file" id="labReport" name="labReport" accept=".pdf,.doc,.docx"
(change)="handleUpload($event,'Lab-Report')" /> (change)="handleUpload($event,'Lab-Report')" />
<div *ngIf="uploadProgress1 > 0"> <div *ngIf="uploadProgress1 > 0">
<p>Uploading... {{ uploadProgress1 }}%</p> <p>Uploading... {{ uploadProgress1 }}%</p>
@ -180,7 +214,7 @@
<div class="col-6"> <div class="col-6">
<div class="field"> <div class="field">
<label for="medications"><i class="pi pi-file-pdf"></i> Medications</label> <label for="medications"><i class="pi pi-file-pdf"></i> Medications</label>
<input type="file" id="medications" name="medications" accept=".pdf,.doc,.docx" <input class="d-flex" type="file" id="medications" name="medications" accept=".pdf,.doc,.docx"
(change)="handleUpload($event,'Medication')" /> (change)="handleUpload($event,'Medication')" />
<div *ngIf="uploadProgress2 > 0"> <div *ngIf="uploadProgress2 > 0">
<p>Uploading... {{ uploadProgress2 }}%</p> <p>Uploading... {{ uploadProgress2 }}%</p>
@ -192,7 +226,7 @@
<div class="col-6"> <div class="col-6">
<div class="field"> <div class="field">
<label for="medicationHistory"><i class="pi pi-file-pdf"></i>Medication History</label> <label for="medicationHistory"><i class="pi pi-file-pdf"></i>Medication History</label>
<input type="file" id="medicationHistory" name="medicationHistory" accept=".pdf,.doc,.docx" <input class="d-flex" type="file" id="medicationHistory" name="medicationHistory" accept=".pdf,.doc,.docx"
(change)="handleUpload($event,'Medication-History')" /> (change)="handleUpload($event,'Medication-History')" />
<div *ngIf="uploadProgress3 > 0"> <div *ngIf="uploadProgress3 > 0">
<p>Uploading... {{ uploadProgress3 }}%</p> <p>Uploading... {{ uploadProgress3 }}%</p>
@ -203,33 +237,6 @@
</div> </div>
</div> </div>
</div> </div>
<!-- Diagnosis -->
<div class="p-fluid">
<div class="field">
<label for="diagnosis"><i class="pi pi-heartbeat"></i> Diagnosis</label>
<textarea style="width: 100%; background-color: #fff; color: black;" id="diagnosis" name="diagnosis"
pInputTextarea rows="5" cols="30" [(ngModel)]="selectedPatient.diagnosis" required
#diagnosis="ngModel"></textarea>
<small *ngIf="diagnosis.invalid && diagnosis.touched" class="p-error">
Diagnosis is required.
</small>
</div>
</div>
<!-- Insurance Provider -->
<div class="p-fluid">
<div class="field">
<label for="insuranceProvider"><i class="pi pi-credit-card"></i> Insurance Provider</label>
<input id="insuranceProvider" name="insuranceProvider" type="text" pInputText
[(ngModel)]="selectedPatient.insuranceProvider" required placeholder="Enter insurance provider"
#insurance="ngModel" />
<small *ngIf="insurance.invalid && insurance.touched" class="p-error">
Insurance is required.
</small>
</div>
</div>
<!-- Buttons --> <!-- Buttons -->
<div class="p-dialog-footer flex justify-content-end"> <div class="p-dialog-footer flex justify-content-end">
<button type="submit" pButton class="btn btn-primary" [disabled]="patientrecord.invalid"> <button type="submit" pButton class="btn btn-primary" [disabled]="patientrecord.invalid">

View File

@ -9,12 +9,19 @@ import { ActivatedRoute, Router } from '@angular/router';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
import { Confirmation, ConfirmationService, ToasterService } from '@abp/ng.theme.shared'; import { Confirmation, ConfirmationService, ToasterService } from '@abp/ng.theme.shared';
import { HttpClient, HttpEventType, HttpParams, HttpRequest } from '@angular/common/http'; import { HttpClient, HttpEventType, HttpParams, HttpRequest } from '@angular/common/http';
import { DoctorService } from '@proxy/doctors/doctor.service';
@Component({ @Component({
selector: 'app-patient-record', selector: 'app-patient-record',
templateUrl: './patient-record.component.html', templateUrl: './patient-record.component.html',
styleUrl: './patient-record.component.scss', styleUrl: './patient-record.component.scss',
providers: [PatientService, ConfirmationService, ToasterService, PermissionService], providers: [
PatientService,
ConfirmationService,
DoctorService,
ToasterService,
PermissionService,
],
}) })
export class PatientRecordComponent implements OnInit { export class PatientRecordComponent implements OnInit {
globalFilter: string = ''; globalFilter: string = '';
@ -22,7 +29,7 @@ export class PatientRecordComponent implements OnInit {
totalRecords: number = 0; totalRecords: number = 0;
loading: boolean = false; loading: boolean = false;
patientDialog: boolean = false; patientDialog: boolean = false;
selectedPatient: CreateUpdatePatientRecordDto; selectedPatientRecord: CreateUpdatePatientRecordDto;
patientdto: PatientDto; patientdto: PatientDto;
isEditMode: boolean = false; isEditMode: boolean = false;
patientDialogTitle: string = ''; patientDialogTitle: string = '';
@ -32,6 +39,8 @@ export class PatientRecordComponent implements OnInit {
statuslist: any; statuslist: any;
selectdateOfAdmission: Date = new Date(); selectdateOfAdmission: Date = new Date();
selectnextFollowUp: Date = new Date(); selectnextFollowUp: Date = new Date();
selectdischargeDate: Date = new Date();
selectedstatus = 0;
createpermission: boolean; createpermission: boolean;
editpermission: boolean; editpermission: boolean;
deletepermission: boolean; deletepermission: boolean;
@ -44,11 +53,15 @@ export class PatientRecordComponent implements OnInit {
uploadProgress1 = 0; uploadProgress1 = 0;
uploadProgress2 = 0; uploadProgress2 = 0;
uploadProgress3 = 0; uploadProgress3 = 0;
doctors = [];
doctorOptions = [];
doctorname = '';
constructor( constructor(
private patientService: PatientService, private patientService: PatientService,
private confirmation: ConfirmationService, private confirmation: ConfirmationService,
private permissionChecker: PermissionService, private permissionChecker: PermissionService,
private DoctorService: DoctorService,
private toaster: ToasterService, private toaster: ToasterService,
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
@ -57,7 +70,6 @@ export class PatientRecordComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.patientId = this.route.snapshot.paramMap.get('id'); this.patientId = this.route.snapshot.paramMap.get('id');
console.log(this.patientId);
this.createpermission = this.permissionChecker.getGrantedPolicy( this.createpermission = this.permissionChecker.getGrantedPolicy(
'HospitalManagementSystem.Patient.Create' 'HospitalManagementSystem.Patient.Create'
@ -75,10 +87,11 @@ export class PatientRecordComponent implements OnInit {
}); });
this.resetselectpatient(); this.resetselectpatient();
this.getdoctorlist();
} }
resetselectpatient() { resetselectpatient() {
this.selectedPatient = { this.selectedPatientRecord = {
patientId: this.patientId, patientId: this.patientId,
dateOfAdmission: '', dateOfAdmission: '',
// labReportUrl: '', // labReportUrl: '',
@ -88,7 +101,6 @@ export class PatientRecordComponent implements OnInit {
diagnosis: '', diagnosis: '',
treatmentPlan: '', treatmentPlan: '',
doctorNotes: '', doctorNotes: '',
insuranceProvider: '',
status: Status.InTreatment, status: Status.InTreatment,
}; };
this.labReportUrlpath = ''; this.labReportUrlpath = '';
@ -96,13 +108,15 @@ export class PatientRecordComponent implements OnInit {
this.medicationHistoryUrlpath = ''; this.medicationHistoryUrlpath = '';
this.selectdateOfAdmission = new Date(); this.selectdateOfAdmission = new Date();
this.selectnextFollowUp = new Date(); this.selectnextFollowUp = new Date();
this.selectdischargeDate = new Date();
this.selectedstatus = 0;
this.uploadProgress1 = 0; this.uploadProgress1 = 0;
this.uploadProgress2 = 0; this.uploadProgress2 = 0;
this.uploadProgress3 = 0; this.uploadProgress3 = 0;
} }
loadPatient(event: any, id: any) { loadPatient(event: any, id: any) {
this.selectedPatient.patientId = this.patientId; this.selectedPatientRecord.patientId = this.patientId;
this.loading = true; this.loading = true;
let order = event.sortOrder == 1 ? ' asc' : ' desc'; let order = event.sortOrder == 1 ? ' asc' : ' desc';
event.sortField = event.sortField == undefined ? 'id' : event.sortField; event.sortField = event.sortField == undefined ? 'id' : event.sortField;
@ -114,7 +128,9 @@ export class PatientRecordComponent implements OnInit {
}; };
this.patientService.getPatientById(this.patientId).subscribe(result => { this.patientService.getPatientById(this.patientId).subscribe(result => {
this.patientdto = result; this.patientdto = result;
this.patientImageUrl = environment.apis.default.url + result.imagepath; this.patientImageUrl =
environment.apis.default.url +
(result.imagepath !== null ? result.imagepath : '/images/default-profile.png');
}); });
this.patientService.getPatientRecordList(this.params, id).subscribe(data => { this.patientService.getPatientRecordList(this.params, id).subscribe(data => {
this.patientrecords = data.items; this.patientrecords = data.items;
@ -123,6 +139,16 @@ export class PatientRecordComponent implements OnInit {
}); });
} }
getdoctorlist() {
this.DoctorService.get().subscribe(result => {
this.doctors = result;
this.doctorOptions = this.doctors.map(doctor => ({
label: `Dr. ${doctor.firstName} ${doctor.lastName}`, // Combine first and last name
value: doctor.id, // Use the ID as the value
}));
});
}
backtopatient() { backtopatient() {
this.router.navigate(['/patients/all-patients']); this.router.navigate(['/patients/all-patients']);
} }
@ -164,16 +190,17 @@ export class PatientRecordComponent implements OnInit {
this.resetselectpatient(); this.resetselectpatient();
this.patientDialogTitle = 'Edit Patient'; this.patientDialogTitle = 'Edit Patient';
this.patientService.getPatientRecordById(Patient.id).subscribe(result => { this.patientService.getPatientRecordById(Patient.id).subscribe(result => {
this.selectedPatient = result; this.selectedPatientRecord = result;
this.selectedPatient.patientId = this.patientId; this.selectedPatientRecord.patientId = this.patientId;
this.selectdateOfAdmission = new Date(this.selectedPatient.dateOfAdmission); this.selectdateOfAdmission = new Date(this.selectedPatientRecord.dateOfAdmission);
this.selectnextFollowUp = new Date(this.selectedPatient.nextFollowUp); this.selectnextFollowUp = new Date(this.selectedPatientRecord.nextFollowUp);
this.selectdischargeDate = new Date(this.selectedPatientRecord.dischargeDate);
this.selectedstatus = this.selectedPatientRecord.status;
this.labReportUrlpath = result.labReportUrl != null ? result.labReportUrl.split('\\')[3] : ''; this.labReportUrlpath = result.labReportUrl != null ? result.labReportUrl.split('\\')[3] : '';
this.medicationUrlpath = this.medicationUrlpath =
result.medicationUrl != null ? result.medicationUrl.split('\\')[3] : ''; result.medicationUrl != null ? result.medicationUrl.split('\\')[3] : '';
this.medicationHistoryUrlpath = this.medicationHistoryUrlpath =
result.medicationHistoryUrl != null ? result.medicationHistoryUrl.split('\\')[3] : ''; result.medicationHistoryUrl != null ? result.medicationHistoryUrl.split('\\')[3] : '';
console.log(result);
}); });
this.patientDialog = true; this.patientDialog = true;
this.isEditMode = true; this.isEditMode = true;
@ -210,53 +237,10 @@ export class PatientRecordComponent implements OnInit {
} }
} }
// handleLabReportUpload(event: Event): void {
// const input = event.target as HTMLInputElement;
// if (input && input.files) {
// const tag = 'Lab-Report';
// const formdata = new FormData();
// formdata.append('file', input.files[0]);
// this.UploadFileData(tag, formdata);
// }
// }
// handleMedicationsUpload(event: any): void {
// const input = event.target as HTMLInputElement;
// if (input && input.files) {
// const tag = 'Medication';
// const formdata = new FormData();
// formdata.append('file', input.files[0]);
// this.UploadFileData(tag, formdata);
// }
// }
// handleMedicationHistoryUpload(event: any): void {
// const input = event.target as HTMLInputElement;
// if (input && input.files) {
// const tag = 'Medication-History';
// const formdata = new FormData();
// formdata.append('file', input.files[0]);
// this.UploadFileData(tag, formdata);
// }
// }
UploadFileData(tag: string, formdata: FormData) { UploadFileData(tag: string, formdata: FormData) {
// this.patientService.uploadFile(tag, formdata).subscribe(result => {
// switch (tag) {
// case 'Lab-Report':
// this.selectedPatient.labReportUrlID = result;
// break;
// case 'Medication':
// this.selectedPatient.medicationUrlID = result;
// break;
// case 'Medication-History':
// this.selectedPatient.medicationHistoryUrlID = result;
// break;
// }
// });
const req = new HttpRequest( const req = new HttpRequest(
'POST', 'POST',
environment.apis.default.url + '/api/app/patient/upload-file', environment.apis.default.url + '/api/app/shared/upload-file',
formdata, formdata,
{ {
reportProgress: true, reportProgress: true,
@ -267,7 +251,6 @@ export class PatientRecordComponent implements OnInit {
this.http.request(req).subscribe( this.http.request(req).subscribe(
event => { event => {
if (event.type === HttpEventType.UploadProgress) { if (event.type === HttpEventType.UploadProgress) {
// this.uploadProgress = Math.round((event.loaded / event.total!) * 100);
switch (tag) { switch (tag) {
case 'Lab-Report': case 'Lab-Report':
this.uploadProgress1 = Math.round((event.loaded / event.total!) * 100); this.uploadProgress1 = Math.round((event.loaded / event.total!) * 100);
@ -283,21 +266,20 @@ export class PatientRecordComponent implements OnInit {
switch (tag) { switch (tag) {
case 'Lab-Report': case 'Lab-Report':
this.uploadProgress1 = 100; this.uploadProgress1 = 100;
this.selectedPatient.labReportUrlID = event.body.toString(); this.selectedPatientRecord.labReportUrlID = event.body.toString();
break; break;
case 'Medication': case 'Medication':
this.uploadProgress2 = 100; this.uploadProgress2 = 100;
this.selectedPatient.medicationUrlID = event.body.toString(); this.selectedPatientRecord.medicationUrlID = event.body.toString();
break; break;
case 'Medication-History': case 'Medication-History':
this.uploadProgress3 = 100; this.uploadProgress3 = 100;
this.selectedPatient.medicationHistoryUrlID = event.body.toString(); this.selectedPatientRecord.medicationHistoryUrlID = event.body.toString();
break; break;
} }
} }
}, },
error => { error => {
console.error('Upload failed', error);
this.uploadProgress1 = 100; this.uploadProgress1 = 100;
this.uploadProgress2 = 100; this.uploadProgress2 = 100;
this.uploadProgress3 = 100; this.uploadProgress3 = 100;
@ -306,30 +288,30 @@ export class PatientRecordComponent implements OnInit {
} }
savePatient(form: NgForm) { savePatient(form: NgForm) {
// console.log(form); this.selectedPatientRecord.patientId = this.patientId;
this.selectedPatient.patientId = this.patientId; this.selectedPatientRecord.status = this.selectedPatientRecord.status;
this.selectedPatient.status = this.patientdto.status; this.selectedPatientRecord.dateOfAdmission = this.selectdateOfAdmission.toDateString();
this.selectedPatient.dateOfAdmission = this.selectdateOfAdmission.toDateString(); this.selectedPatientRecord.nextFollowUp = this.selectnextFollowUp.toDateString();
this.selectedPatient.nextFollowUp = this.selectnextFollowUp.toDateString(); this.selectedPatientRecord.dischargeDate = this.selectdischargeDate.toDateString();
this.selectedPatient.labReportUrlID = this.selectedPatient.labReportUrlID this.selectedPatientRecord.status = this.selectedstatus;
? this.selectedPatient.labReportUrlID.replace('"', '').replace('"', '') this.selectedPatientRecord.labReportUrlID = this.selectedPatientRecord.labReportUrlID
? this.selectedPatientRecord.labReportUrlID.replace('"', '').replace('"', '')
: this.guid; : this.guid;
this.selectedPatient.medicationUrlID = this.selectedPatient.medicationUrlID this.selectedPatientRecord.medicationUrlID = this.selectedPatientRecord.medicationUrlID
? this.selectedPatient.medicationUrlID.replace('"', '').replace('"', '') ? this.selectedPatientRecord.medicationUrlID.replace('"', '').replace('"', '')
: this.guid; : this.guid;
this.selectedPatient.medicationHistoryUrlID = this.selectedPatient.medicationHistoryUrlID this.selectedPatientRecord.medicationHistoryUrlID = this.selectedPatientRecord
? this.selectedPatient.medicationHistoryUrlID.replace('"', '').replace('"', '') .medicationHistoryUrlID
? this.selectedPatientRecord.medicationHistoryUrlID.replace('"', '').replace('"', '')
: this.guid; : this.guid;
console.log(this.selectedPatient);
if (this.isEditMode) { if (this.isEditMode) {
this.patientService this.patientService
.updatePatientRecord(this.selectedPatient.id, this.selectedPatient) .updatePatientRecord(this.selectedPatientRecord.id, this.selectedPatientRecord)
.subscribe( .subscribe(
result => { result => {
this.toaster.success('Patient updated successfully', 'Success'); this.toaster.success('Patient updated successfully', 'Success');
this.patientDialog = false; this.patientDialog = false;
console.log(result);
this.loadPatient( this.loadPatient(
{ {
@ -343,12 +325,11 @@ export class PatientRecordComponent implements OnInit {
); );
}, },
error => { error => {
console.log(error);
this.closeDialog(); this.closeDialog();
} }
); );
} else { } else {
this.patientService.createPatientRecord(this.selectedPatient).subscribe( this.patientService.createPatientRecord(this.selectedPatientRecord).subscribe(
() => { () => {
this.toaster.success('Patient created successfully', 'Success'); this.toaster.success('Patient created successfully', 'Success');
this.patientDialog = false; this.patientDialog = false;
@ -364,7 +345,6 @@ export class PatientRecordComponent implements OnInit {
); );
}, },
error => { error => {
console.log(error);
this.closeDialog(); this.closeDialog();
} }
); );

View File

@ -11,18 +11,15 @@ namespace HospitalManagementSystem.Patients.Dto
public class CreateUpdatePatientDto public class CreateUpdatePatientDto
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public string PatientCardId { get; set; }
public string Name { get; set; } public string Name { get; set; }
public Gender Gender { get; set; } public Gender Gender { get; set; }
public string Mobile { get; set; } public string Mobile { get; set; }
public string Email { get; set; } public string Email { get; set; }
public int Age { get; set; } public int Age { get; set; }
public string Treatment { get; set; }
public string DoctorAssigned { get; set; }
public string Address { get; set; } public string Address { get; set; }
public string BloodGroup { get; set; } public string BloodGroup { get; set; }
public DateTime AdmissionDate { get; set; } public string InsuranceProvider { get; set; }
public DateTime? DischargeDate { get; set; } public Guid? ImageID { get; set; }
public Status Status { get; set; }
public Guid ImageID { get; set; }
} }
} }

View File

@ -1,7 +1,9 @@
using HospitalManagementSystem.GlobalEnum; using HospitalManagementSystem.Doctors.Dto;
using HospitalManagementSystem.GlobalEnum;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -12,27 +14,18 @@ namespace HospitalManagementSystem.Patients.Dto
public class CreateUpdatePatientRecordDto public class CreateUpdatePatientRecordDto
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public Guid PatientId { get; set; } public Guid PatientId { get; set; }
[Required]
public DateTime DateOfAdmission { get; set; } public DateTime DateOfAdmission { get; set; }
public DateTime? DischargeDate { get; set; }
public Guid? LabReportUrlID { get; set; }
public Guid? MedicationUrlID { get; set; }
public Guid? MedicationHistoryUrlID { get; set; }
public DateTime? NextFollowUp { get; set; } public DateTime? NextFollowUp { get; set; }
public string? Diagnosis { get; set; }
public string Diagnosis { get; set; } public string? TreatmentPlan { get; set; }
public Guid? DoctorAssignedID { get; set; }
public string TreatmentPlan { get; set; } public string? DoctorNotes { get; set; }
public Guid? LabReportUrlID { get; set; }
public string DoctorNotes { get; set; } public Guid? MedicationUrlID { get; set; }
public Guid? MedicationHistoryUrlID { get; set; }
public string InsuranceProvider { get; set; }
public Status Status { get; set; } public Status Status { get; set; }
} }

View File

@ -1,6 +1,7 @@
using HospitalManagementSystem.GlobalEnum; using HospitalManagementSystem.GlobalEnum;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -10,18 +11,15 @@ namespace HospitalManagementSystem.Patients.Dto
public class PatientDto public class PatientDto
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public string PatientCardId { get; set; }
public string Name { get; set; } public string Name { get; set; }
public Gender Gender { get; set; } public Gender Gender { get; set; }
public string Mobile { get; set; } public string Mobile { get; set; }
public string Email { get; set; } public string Email { get; set; }
public int Age { get; set; } public int Age { get; set; }
public string Treatment { get; set; }
public string DoctorAssigned { get; set; }
public string Address { get; set; } public string Address { get; set; }
public string BloodGroup { get; set; } public string BloodGroup { get; set; }
public DateTime AdmissionDate { get; set; } public string InsuranceProvider { get; set; }
public DateTime? DischargeDate { get; set; }
public Status Status { get; set; }
public string? Imagepath { get; set; } public string? Imagepath { get; set; }
} }
} }

View File

@ -1,41 +1,26 @@
using HospitalManagementSystem.GlobalEnum; using HospitalManagementSystem.GlobalEnum;
using System; using System;
using System.Collections.Generic; using HospitalManagementSystem.Doctors.Dto;
using System.Linq; using System.ComponentModel.DataAnnotations;
using System.Text;
using System.Threading.Tasks;
using static HospitalManagementSystem.Permissions.HospitalManagementSystemPermissions;
using HospitalManagementSystem.Patients;
using System.ComponentModel.DataAnnotations.Schema;
namespace HospitalManagementSystem.Patients.Dto namespace HospitalManagementSystem.Patients.Dto
{ {
public class PatientRecordDto public class PatientRecordDto
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public Guid PatientId { get; set; } public Guid PatientId { get; set; }
public PatientDto Patients { get; set; } public PatientDto Patients { get; set; }
[Required]
public DateTime DateOfAdmission { get; set; } public DateTime DateOfAdmission { get; set; }
public DateTime? DischargeDate { get; set; }
public string Diagnosis { get; set; }
public string TreatmentPlan { get; set; }
public string DoctorNotes { get; set; }
public string LabReportUrl { get; set; }
public string MedicationUrl { get; set; }
public string MedicationHistoryUrl { get; set; }
public DateTime? NextFollowUp { get; set; } public DateTime? NextFollowUp { get; set; }
public string? Diagnosis { get; set; }
public string InsuranceProvider { get; set; } public string? TreatmentPlan { get; set; }
public DoctorDto? DoctorAssigned { get; set; }
public string? DoctorNotes { get; set; }
public string LabReportUrl { get; set; }
public string MedicationUrl { get; set; }
public string MedicationHistoryUrl { get; set; }
public Status Status { get; set; } public Status Status { get; set; }
} }

View File

@ -1,4 +1,5 @@
using HospitalManagementSystem.Departments; using HospitalManagementSystem.Departments;
using HospitalManagementSystem.Doctors.Dto;
using HospitalManagementSystem.Dtos; using HospitalManagementSystem.Dtos;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;

View File

@ -1,4 +1,5 @@
using HospitalManagementSystem.Dtos; using HospitalManagementSystem.Doctors.Dto;
using HospitalManagementSystem.Dtos;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;

View File

@ -1,24 +0,0 @@
using HospitalManagementSystem.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities.Auditing;
namespace HospitalManagementSystem.Dtos
{
public class DoctorDto : FullAuditedEntity<Guid>
{
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? Gender { get; set; }
public string? Mobile { get; set; }
public string? Designation { get; set; }
public Guid? DepartmentId { get; set; }
public string? Address { get; set; }
public string? Email { get; set; }
public string? DOB { get; set; }
public string? Education { get; set; }
}
}

View File

@ -1,7 +1,4 @@
using AutoMapper; using AutoMapper;
using HospitalManagementSystem.Departments;
using HospitalManagementSystem.Doctors;
using HospitalManagementSystem.Dtos;
namespace HospitalManagementSystem; namespace HospitalManagementSystem;
@ -12,7 +9,5 @@ public class HospitalManagementSystemApplicationAutoMapperProfile : Profile
/* You can configure your AutoMapper mapping configuration here. /* You can configure your AutoMapper mapping configuration here.
* Alternatively, you can split your mapping configurations * Alternatively, you can split your mapping configurations
* into multiple profile classes for a better organization. */ * into multiple profile classes for a better organization. */
CreateMap<Department, DepartmentDto>();
CreateMap<Doctor, DoctorDto>();
} }
} }

View File

@ -1,6 +1,9 @@
using AutoMapper; using AutoMapper;
using HospitalManagementSystem.Appoinments.Dto; using HospitalManagementSystem.Appoinments.Dto;
using HospitalManagementSystem.Appointments; using HospitalManagementSystem.Appointments;
using HospitalManagementSystem.Doctors.Dto;
using HospitalManagementSystem.Doctors;
using HospitalManagementSystem.Dtos;
using HospitalManagementSystem.Patients; using HospitalManagementSystem.Patients;
using HospitalManagementSystem.Patients.Dto; using HospitalManagementSystem.Patients.Dto;
using System; using System;
@ -8,6 +11,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using HospitalManagementSystem.Departments;
namespace HospitalManagementSystem namespace HospitalManagementSystem
{ {
@ -36,6 +40,15 @@ namespace HospitalManagementSystem
CreateMap<Appointment, CreateOrUpdateAppointmentDto>(); CreateMap<Appointment, CreateOrUpdateAppointmentDto>();
CreateMap<CreateOrUpdateAppointmentDto, Appointment>(); CreateMap<CreateOrUpdateAppointmentDto, Appointment>();
#endregion #endregion
#region Department
CreateMap<Department, DepartmentDto>();
#endregion
#region Doctor
CreateMap<Doctor, DoctorDto>();
CreateMap<DoctorDto, Doctor>();
#endregion
} }
} }
} }

View File

@ -1,9 +1,11 @@
using ClosedXML.Excel; using ClosedXML.Excel;
using HospitalManagementSystem.Doctors;
using HospitalManagementSystem.Documents; using HospitalManagementSystem.Documents;
using HospitalManagementSystem.Dto; using HospitalManagementSystem.Dto;
using HospitalManagementSystem.GlobalEnum; using HospitalManagementSystem.GlobalEnum;
using HospitalManagementSystem.Patients.Dto; using HospitalManagementSystem.Patients.Dto;
using HospitalManagementSystem.Permissions; using HospitalManagementSystem.Permissions;
using HospitalManagementSystem.Shared;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -29,16 +31,20 @@ namespace HospitalManagementSystem.Patients
private IRepository<Patient, Guid> _patientRepository; private IRepository<Patient, Guid> _patientRepository;
private IRepository<EntityDocument, Guid> _entityDocumentRepository; private IRepository<EntityDocument, Guid> _entityDocumentRepository;
private IRepository<PatientDocument, Guid> _patientDocumentRepository; private IRepository<PatientDocument, Guid> _patientDocumentRepository;
private IRepository<Doctor, Guid> _doctorrepository;
private readonly IWebHostEnvironment _env; private readonly IWebHostEnvironment _env;
private SharedAppService _sharedappService;
List<Guid> uniqueid = new List<Guid>(); 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) 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)
{ {
_patientrecordRepository = patientrecordRepository; _patientrecordRepository = patientrecordRepository;
_patientRepository = patientRepository; _patientRepository = patientRepository;
_env = env; _env = env;
_entityDocumentRepository = entityDocumentRepository; _entityDocumentRepository = entityDocumentRepository;
_patientDocumentRepository = patientDocumentRepository; _patientDocumentRepository = patientDocumentRepository;
_sharedappService = sharedappService;
_doctorrepository = doctorrepository;
} }
#region PatientRecord #region PatientRecord
@ -51,6 +57,7 @@ namespace HospitalManagementSystem.Patients
var filteredQuery = queryable var filteredQuery = queryable
.Include(x => x.Patients) .Include(x => x.Patients)
.Include(x => x.DoctorAssigned)
.Include(x => x.LabReportUrl) .Include(x => x.LabReportUrl)
.Include(x => x.MedicationUrl) .Include(x => x.MedicationUrl)
.Include(x => x.MedicationHistoryUrl) .Include(x => x.MedicationHistoryUrl)
@ -119,34 +126,43 @@ namespace HospitalManagementSystem.Patients
{ {
var worksheet = workbook.Worksheets.Add("Patients"); var worksheet = workbook.Worksheets.Add("Patients");
// Add headers
worksheet.Cell(1, 1).Value = "Full Name"; worksheet.Cell(1, 1).Value = "Full Name";
worksheet.Cell(1, 2).Value = "Gender"; worksheet.Cell(1, 2).Value = "Gender";
worksheet.Cell(1, 3).Value = "Date of Admission"; worksheet.Cell(1, 3).Value = "Date of Admission";
worksheet.Cell(1, 4).Value = "Diagnosis"; worksheet.Cell(1, 4).Value = "Discharge Date";
worksheet.Cell(1, 5).Value = "Next Follow-Up"; worksheet.Cell(1, 5).Value = "Diagnosis";
worksheet.Cell(1, 6).Value = "InsuranceProvider"; worksheet.Cell(1, 6).Value = "Treatment Plan";
worksheet.Cell(1, 7).Value = "InsuranceProvider"; worksheet.Cell(1, 7).Value = "Doctor Assigned";
worksheet.Cell(1, 8).Value = "InsuranceProvider"; worksheet.Cell(1, 8).Value = "Doctor Notes";
worksheet.Cell(1, 9).Value = "Status"; worksheet.Cell(1, 9).Value = "Next Follow-Up";
worksheet.Cell(1, 10).Value = "Lab Report URL";
worksheet.Cell(1, 11).Value = "Medication URL";
worksheet.Cell(1, 12).Value = "Medication History URL";
worksheet.Cell(1, 13).Value = "Status";
for (int i = 0; i < patientrecord.Count; i++) for (int i = 0; i < patientrecord.Count; i++)
{ {
worksheet.Cell(i + 2, 1).Value = patientrecord[i].Patients.Name; var patient = patientrecord[i];
worksheet.Cell(i + 2, 2).Value = patientrecord[i].Patients.Gender.ToString();
worksheet.Cell(i + 2, 3).Value = patientrecord[i].DateOfAdmission.ToShortDateString();
worksheet.Cell(i + 2, 4).Value = patientrecord[i].Diagnosis;
worksheet.Cell(i + 2, 5).Value = patientrecord[i].NextFollowUp?.ToShortDateString();
worksheet.Cell(i + 2, 6).Value = patientrecord[i].InsuranceProvider;
worksheet.Cell(i + 2, 7).Value = patientrecord[i].InsuranceProvider;
worksheet.Cell(i + 2, 8).Value = patientrecord[i].InsuranceProvider;
worksheet.Cell(i + 2, 9).Value = patientrecord[i].Status.ToString();
}
worksheet.Cell(i + 2, 1).Value = patient.Patients.Name;
worksheet.Cell(i + 2, 2).Value = patient.Patients.Gender.ToString();
worksheet.Cell(i + 2, 3).Value = patient.DateOfAdmission.ToShortDateString();
worksheet.Cell(i + 2, 4).Value = patient.DischargeDate?.ToShortDateString() ?? "N/A";
worksheet.Cell(i + 2, 5).Value = patient.Diagnosis;
worksheet.Cell(i + 2, 6).Value = patient.TreatmentPlan;
worksheet.Cell(i + 2, 7).Value = (patient.DoctorAssigned?.FirstName + patient.DoctorAssigned?.LastName) ?? "Not Assigned";
worksheet.Cell(i + 2, 8).Value = patient.DoctorNotes;
worksheet.Cell(i + 2, 9).Value = patient.NextFollowUp?.ToShortDateString() ?? "N/A";
worksheet.Cell(i + 2, 10).Value = patient.LabReportUrl?.FilePath ?? "No Report";
worksheet.Cell(i + 2, 11).Value = patient.MedicationUrl?.FilePath ?? "No Medication";
worksheet.Cell(i + 2, 12).Value = patient.MedicationHistoryUrl?.FilePath ?? "No History";
worksheet.Cell(i + 2, 13).Value = patient.Status.ToString();
}
worksheet.Columns().AdjustToContents(); worksheet.Columns().AdjustToContents();
workbook.SaveAs(filePath); workbook.SaveAs(filePath);
} }
byte[] fileBytes = await File.ReadAllBytesAsync(filePath); byte[] fileBytes = await File.ReadAllBytesAsync(filePath);
File.Delete(filePath); File.Delete(filePath);
@ -164,9 +180,12 @@ namespace HospitalManagementSystem.Patients
public async Task CreatePatientRecordAsync(CreateUpdatePatientRecordDto input) public async Task CreatePatientRecordAsync(CreateUpdatePatientRecordDto input)
{ {
var patientEntity = await _patientRepository.GetAsync(input.PatientId); // Get Patient from DB var patientEntity = await _patientRepository.GetAsync(input.PatientId); // Get Patient from DB
var doctorEntity = await _doctorrepository.GetAsync(input.DoctorAssignedID.Value);
var patientRecord = ObjectMapper.Map<CreateUpdatePatientRecordDto, PatientRecord>(input); var patientRecord = ObjectMapper.Map<CreateUpdatePatientRecordDto, PatientRecord>(input);
patientRecord.Patients = patientEntity; patientRecord.Patients = patientEntity;
patientRecord.DoctorAssigned = doctorEntity != null ? doctorEntity : null;
List<EntityDocument> entitydocument = new List<EntityDocument>(); List<EntityDocument> entitydocument = new List<EntityDocument>();
List<PatientDocument> patientDocuments = new List<PatientDocument>();
if (input.LabReportUrlID != Guid.Empty) if (input.LabReportUrlID != Guid.Empty)
uniqueid.Add(input.LabReportUrlID.Value); uniqueid.Add(input.LabReportUrlID.Value);
@ -176,7 +195,7 @@ namespace HospitalManagementSystem.Patients
uniqueid.Add(input.MedicationHistoryUrlID.Value); uniqueid.Add(input.MedicationHistoryUrlID.Value);
if (uniqueid.Count > 0) if (uniqueid.Count > 0)
{ {
entitydocument = await SaveFileToDocument(patientEntity, uniqueid); entitydocument = await _sharedappService.SaveFileToDocument(patientEntity, uniqueid);
foreach (var entity in entitydocument) foreach (var entity in entitydocument)
{ {
switch (entity.TagName) switch (entity.TagName)
@ -194,6 +213,39 @@ namespace HospitalManagementSystem.Patients
} }
} }
patientRecord = await _patientrecordRepository.InsertAsync(patientRecord); patientRecord = await _patientrecordRepository.InsertAsync(patientRecord);
// Fetch existing patient documents in one query
var existingPatientDocs = await _patientDocumentRepository.GetQueryableAsync()
.Result.Where(x => x.Patients.Id == input.PatientId)
.ToListAsync();
foreach (var document in entitydocument)
{
var existingDoc = existingPatientDocs.FirstOrDefault(x => x.TagName == document.TagName);
var patientDocument = new PatientDocument
{
Patients = patientEntity,
EntityDocuments = document,
TagName = document.TagName
};
if (existingDoc != null)
{
existingDoc.EntityDocuments = document; // Update reference
await _patientDocumentRepository.UpdateAsync(existingDoc);
}
else
{
patientDocuments.Add(patientDocument);
}
}
// Batch insert new patient documents
if (patientDocuments.Any())
{
await _patientDocumentRepository.InsertManyAsync(patientDocuments);
}
uniqueid.Clear();
} }
#endregion #endregion
@ -203,12 +255,12 @@ namespace HospitalManagementSystem.Patients
{ {
try try
{ {
var patientRecord = await _patientrecordRepository.GetQueryableAsync().Result.Include(x => x.Patients).Where(x => x.Id == id).FirstOrDefaultAsync(); var patientRecord = await _patientrecordRepository.GetQueryableAsync().Result.Include(x => x.Patients).Include(x => x.DoctorAssigned).Where(x => x.Id == id).FirstOrDefaultAsync();
List<EntityDocument> entitydocument = new List<EntityDocument>(); List<EntityDocument> entitydocument = new List<EntityDocument>();
if (patientRecord.Patients.Id != input.PatientId) // If PatientId is updated, fetch new Patient List<PatientDocument> patientDocuments = new List<PatientDocument>();
if (patientRecord.DoctorAssigned?.Id != input.DoctorAssignedID.Value)
{ {
var newPatient = await _patientRepository.GetAsync(input.PatientId); patientRecord.DoctorAssigned = await _doctorrepository.GetAsync(input.DoctorAssignedID.Value);
patientRecord.Patients = newPatient;
} }
ObjectMapper.Map(input, patientRecord); ObjectMapper.Map(input, patientRecord);
if (input.LabReportUrlID != Guid.Empty) if (input.LabReportUrlID != Guid.Empty)
@ -219,7 +271,7 @@ namespace HospitalManagementSystem.Patients
uniqueid.Add(input.MedicationHistoryUrlID.Value); uniqueid.Add(input.MedicationHistoryUrlID.Value);
if (uniqueid.Count > 0) if (uniqueid.Count > 0)
{ {
entitydocument = await SaveFileToDocument(patientRecord.Patients, uniqueid); entitydocument = await _sharedappService.SaveFileToDocument(patientRecord.Patients, uniqueid);
foreach (var entity in entitydocument) foreach (var entity in entitydocument)
{ {
switch (entity.TagName) switch (entity.TagName)
@ -236,6 +288,39 @@ namespace HospitalManagementSystem.Patients
} }
} }
} }
// Fetch existing patient documents in one query
var existingPatientDocs = await _patientDocumentRepository.GetQueryableAsync()
.Result.Where(x => x.Patients.Id == input.PatientId)
.ToListAsync();
foreach (var document in entitydocument)
{
var existingDoc = existingPatientDocs.FirstOrDefault(x => x.TagName == document.TagName);
var patientDocument = new PatientDocument
{
Patients = patientRecord.Patients,
EntityDocuments = document,
TagName = document.TagName
};
if (existingDoc != null)
{
existingDoc.EntityDocuments = document; // Update reference
await _patientDocumentRepository.UpdateAsync(existingDoc);
}
else
{
patientDocuments.Add(patientDocument);
}
}
// Batch insert new patient documents
if (patientDocuments.Any())
{
await _patientDocumentRepository.InsertManyAsync(patientDocuments);
}
uniqueid.Clear();
patientRecord = await _patientrecordRepository.UpdateAsync(patientRecord); patientRecord = await _patientrecordRepository.UpdateAsync(patientRecord);
} }
@ -319,35 +404,37 @@ namespace HospitalManagementSystem.Patients
{ {
var worksheet = workbook.Worksheets.Add("Patients"); var worksheet = workbook.Worksheets.Add("Patients");
// Add headers worksheet.Cell(1, 1).Value = "Patient Card ID";
worksheet.Cell(1, 1).Value = "Name"; worksheet.Cell(1, 2).Value = "Name";
worksheet.Cell(1, 2).Value = "Gender"; worksheet.Cell(1, 3).Value = "Gender";
worksheet.Cell(1, 3).Value = "Age"; worksheet.Cell(1, 4).Value = "Age";
worksheet.Cell(1, 4).Value = "BloodGroup"; worksheet.Cell(1, 5).Value = "Mobile";
worksheet.Cell(1, 5).Value = "Treatment"; worksheet.Cell(1, 6).Value = "Email";
worksheet.Cell(1, 6).Value = "Doctor Assigned"; worksheet.Cell(1, 7).Value = "Address";
worksheet.Cell(1, 7).Value = "Admission Date"; worksheet.Cell(1, 8).Value = "Blood Group";
worksheet.Cell(1, 8).Value = "Discharge Date"; worksheet.Cell(1, 9).Value = "Insurance Provider";
worksheet.Cell(1, 9).Value = "Status"; worksheet.Cell(1, 10).Value = "Patient Images";
// Add data rows
for (int i = 0; i < patients.Count; i++) for (int i = 0; i < patients.Count; i++)
{ {
worksheet.Cell(i + 2, 1).Value = patients[i].Name; worksheet.Cell(i + 2, 1).Value = patients[i].PatientCardId;
worksheet.Cell(i + 2, 2).Value = patients[i].Gender.ToString(); worksheet.Cell(i + 2, 2).Value = patients[i].Name;
worksheet.Cell(i + 2, 3).Value = patients[i].Age; worksheet.Cell(i + 2, 3).Value = patients[i].Gender.ToString();
worksheet.Cell(i + 2, 4).Value = patients[i].BloodGroup; worksheet.Cell(i + 2, 4).Value = patients[i].Age;
worksheet.Cell(i + 2, 5).Value = patients[i].Treatment; worksheet.Cell(i + 2, 5).Value = patients[i].Mobile;
worksheet.Cell(i + 2, 6).Value = patients[i].DoctorAssigned; worksheet.Cell(i + 2, 6).Value = patients[i].Email;
worksheet.Cell(i + 2, 7).Value = patients[i].AdmissionDate.ToShortDateString(); worksheet.Cell(i + 2, 7).Value = patients[i].Address;
worksheet.Cell(i + 2, 8).Value = patients[i].DischargeDate?.ToShortDateString(); worksheet.Cell(i + 2, 8).Value = patients[i].BloodGroup;
worksheet.Cell(i + 2, 9).Value = patients[i].Status.ToString(); worksheet.Cell(i + 2, 9).Value = patients[i].InsuranceProvider ?? "N/A";
worksheet.Cell(i + 2, 19).Value = patients[i].Images?.GeneratedFileName ?? "N/A";
} }
worksheet.Columns().AdjustToContents(); worksheet.Columns().AdjustToContents();
workbook.SaveAs(filePath); workbook.SaveAs(filePath);
} }
byte[] fileBytes = await File.ReadAllBytesAsync(filePath); byte[] fileBytes = await File.ReadAllBytesAsync(filePath);
File.Delete(filePath); File.Delete(filePath);
@ -363,13 +450,15 @@ namespace HospitalManagementSystem.Patients
[Authorize(HospitalManagementSystemPermissions.Patient.Create)] [Authorize(HospitalManagementSystemPermissions.Patient.Create)]
public async Task CreatePatientAsync(CreateUpdatePatientDto input) public async Task CreatePatientAsync(CreateUpdatePatientDto input)
{ {
List<PatientDocument> patientDocuments = new List<PatientDocument>();
List<EntityDocument> entitydocument = new List<EntityDocument>();
var patient = ObjectMapper.Map<CreateUpdatePatientDto, Patient>(input); var patient = ObjectMapper.Map<CreateUpdatePatientDto, Patient>(input);
patient = await _patientRepository.InsertAsync(patient); patient = await _patientRepository.InsertAsync(patient);
if (input.ImageID != Guid.Empty) if (input.ImageID != Guid.Empty)
{ {
uniqueid.Add(input.ImageID); uniqueid.Add(input.ImageID.Value);
var entitydocument = await SaveFileToDocument(patient, uniqueid, true); entitydocument = await _sharedappService.SaveFileToDocument(patient, uniqueid, true);
foreach (var entity in entitydocument) foreach (var entity in entitydocument)
{ {
if (entity.TagName == "Image") if (entity.TagName == "Image")
@ -378,6 +467,39 @@ namespace HospitalManagementSystem.Patients
} }
} }
} }
// Fetch existing patient documents in one query
var existingPatientDocs = await _patientDocumentRepository.GetQueryableAsync()
.Result.Where(x => x.Patients.Id == patient.Id)
.ToListAsync();
foreach (var document in entitydocument)
{
var existingDoc = existingPatientDocs.FirstOrDefault(x => x.TagName == document.TagName);
var patientDocument = new PatientDocument
{
Patients = patient,
EntityDocuments = document,
TagName = document.TagName
};
if (existingDoc != null)
{
existingDoc.EntityDocuments = document; // Update reference
await _patientDocumentRepository.UpdateAsync(existingDoc);
}
else
{
patientDocuments.Add(patientDocument);
}
}
// Batch insert new patient documents
if (patientDocuments.Any())
{
await _patientDocumentRepository.InsertManyAsync(patientDocuments);
}
uniqueid.Clear();
} }
#endregion #endregion
@ -387,11 +509,12 @@ namespace HospitalManagementSystem.Patients
{ {
var patient = await _patientRepository.GetQueryableAsync().Result.Include(x => x.Images).Where(x => x.Id == id).FirstOrDefaultAsync(); var patient = await _patientRepository.GetQueryableAsync().Result.Include(x => x.Images).Where(x => x.Id == id).FirstOrDefaultAsync();
List<EntityDocument> entitydocument = new List<EntityDocument>(); List<EntityDocument> entitydocument = new List<EntityDocument>();
List<PatientDocument> patientDocuments = new List<PatientDocument>();
ObjectMapper.Map(input, patient); ObjectMapper.Map(input, patient);
if (input.ImageID != Guid.Empty) if (input.ImageID != Guid.Empty)
{ {
uniqueid.Add(input.ImageID); uniqueid.Add(input.ImageID.Value);
entitydocument = await SaveFileToDocument(patient, uniqueid); entitydocument = await _sharedappService.SaveFileToDocument(patient, uniqueid);
foreach (var entity in entitydocument) foreach (var entity in entitydocument)
{ {
if (entity.TagName == "Image") if (entity.TagName == "Image")
@ -400,7 +523,39 @@ namespace HospitalManagementSystem.Patients
} }
} }
} }
// Fetch existing patient documents in one query
var existingPatientDocs = await _patientDocumentRepository.GetQueryableAsync()
.Result.Where(x => x.Patients.Id == patient.Id)
.ToListAsync();
foreach (var document in entitydocument)
{
var existingDoc = existingPatientDocs.FirstOrDefault(x => x.TagName == document.TagName);
var patientDocument = new PatientDocument
{
Patients = patient,
EntityDocuments = document,
TagName = document.TagName
};
if (existingDoc != null)
{
existingDoc.EntityDocuments = document; // Update reference
await _patientDocumentRepository.UpdateAsync(existingDoc);
}
else
{
patientDocuments.Add(patientDocument);
}
}
// Batch insert new patient documents
if (patientDocuments.Any())
{
await _patientDocumentRepository.InsertManyAsync(patientDocuments);
}
uniqueid.Clear();
patient = await _patientRepository.UpdateAsync(patient); patient = await _patientRepository.UpdateAsync(patient);
} }
#endregion #endregion
@ -439,219 +594,152 @@ namespace HospitalManagementSystem.Patients
} }
#endregion #endregion
#region UploadFile //#region UploadFile
public async Task<Guid> UploadFileAsync(string TagName, IRemoteStreamContent file) //public async Task<Guid> UploadFileAsync(string TagName, IRemoteStreamContent file)
{ //{
if (file == null) // if (file == null)
{ // {
throw new Exception("File cannot be null"); // throw new Exception("File cannot be null");
} // }
string patientFolder = Path.Combine(_env.WebRootPath, "temp"); // string patientFolder = Path.Combine(_env.WebRootPath, "temp");
Guid uniqueId = Guid.NewGuid(); // Guid uniqueId = Guid.NewGuid();
if (!Directory.Exists(patientFolder)) // if (!Directory.Exists(patientFolder))
{ // {
Directory.CreateDirectory(patientFolder); // Directory.CreateDirectory(patientFolder);
} // }
string fileExtension = Path.GetExtension(file.FileName); // string fileExtension = Path.GetExtension(file.FileName);
string fileName = $"{uniqueId}({TagName}){fileExtension}"; // string fileName = $"{uniqueId}({TagName}){fileExtension}";
string filePath = Path.Combine(patientFolder, fileName); // string filePath = Path.Combine(patientFolder, fileName);
using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) // using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{ // {
await file.GetStream().CopyToAsync(fileStream); // await file.GetStream().CopyToAsync(fileStream);
} // }
var metadata = new // var metadata = new
{ // {
OriginalFileName = file.FileName, // OriginalFileName = file.FileName,
FileName = fileName, // FileName = fileName,
FileSize = new FileInfo(filePath).Length.ToString(), // FileSize = new FileInfo(filePath).Length.ToString(),
FilePath = filePath, // FilePath = filePath,
UploadDate = DateTime.UtcNow, // UploadDate = DateTime.UtcNow,
FileType = fileExtension, // FileType = fileExtension,
TagName = TagName, // TagName = TagName,
}; // };
string jsonFileName = $"{uniqueId}({TagName}).json"; // string jsonFileName = $"{uniqueId}({TagName}).json";
string jsonFilePath = Path.Combine(patientFolder, jsonFileName); // string jsonFilePath = Path.Combine(patientFolder, jsonFileName);
await File.WriteAllTextAsync(jsonFilePath, JsonSerializer.Serialize(metadata, new JsonSerializerOptions { WriteIndented = true })); // await File.WriteAllTextAsync(jsonFilePath, JsonSerializer.Serialize(metadata, new JsonSerializerOptions { WriteIndented = true }));
return uniqueId; // return uniqueId;
} //}
#endregion //#endregion
#region SaveFileToDocument //#region SaveFileToDocument
//public async Task<List<EntityDocument>> SaveFileToDocument(Patient Patients, Guid ImageId, bool IsNew = false) //public async Task<List<EntityDocument>> SaveFileToDocument(Patient patient, List<Guid> uniqueIds, bool isNew = false)
//{ //{
// try // try
// { // {
// //string patientFolder = Path.Combine(_env.WebRootPath, "uploads", PatientId.ToString()); // string tempFolder = Path.Combine(_env.WebRootPath, "temp");
// string patientFolder = Path.Combine(_env.WebRootPath, "uploads", $"{Patients.Id}({Patients.Name})"); // string patientFolder = Path.Combine(_env.WebRootPath, "uploads", $"{patient.Id}({patient.Name})");
// string ImageFolder = Path.Combine(_env.WebRootPath, "uploads", $"{ImageId}({Patients.Name})");
// List<string>? jsonFiles;
// if (IsNew) // if (!Directory.Exists(patientFolder))
// { // {
// jsonFiles = Directory.EnumerateFiles(ImageFolder, "*.json").Where(x => Path.GetFileName(x).StartsWith(ImageId.ToString())).ToList(); // Directory.CreateDirectory(patientFolder);
// }
// else
// {
// jsonFiles = Directory.EnumerateFiles(patientFolder, "*.json").Where(x => Path.GetFileName(x).StartsWith(Patients.Id.ToString())).ToList();
// } // }
// List<EntityDocument> savedDocuments = new List<EntityDocument>(); // List<EntityDocument> savedDocuments = new List<EntityDocument>();
// // Iterate over all matching JSON files and save data to the database // foreach (var uniqueId in uniqueIds)
// foreach (var jsonFilePath in jsonFiles) // {
// // Fetch all matching JSON metadata files for the current uniqueId
// foreach (var jsonFilePath in Directory.EnumerateFiles(tempFolder, $"{uniqueId}(*).json"))
// { // {
// string jsonContent = await File.ReadAllTextAsync(jsonFilePath); // string jsonContent = await File.ReadAllTextAsync(jsonFilePath);
// var metadata = JsonSerializer.Deserialize<dynamic>(jsonContent); // var metadata = JsonSerializer.Deserialize<JsonElement>(jsonContent);
// string originalFileName = metadata.GetProperty("OriginalFileName").GetString();
// string generatedFileName = metadata.GetProperty("FileName").GetString();
// string fileSize = metadata.GetProperty("FileSize").GetString();
// string filePath = metadata.GetProperty("FilePath").GetString();
// string fileType = metadata.GetProperty("FileType").GetString();
// string tagName = metadata.GetProperty("TagName").GetString();
// DateTime uploadDate = metadata.GetProperty("UploadDate").GetDateTime();
// // Move the file from temp folder to patient folder
// string newFilePath = Path.Combine(patientFolder, generatedFileName);
// if (File.Exists(filePath))
// {
// File.Move(filePath, newFilePath, true);
// }
// newFilePath = newFilePath.Split("wwwroot")[1];
// var document = new EntityDocument // var document = new EntityDocument
// { // {
// OriginalFileName = metadata.GetProperty("OriginalFileName").GetString(), // OriginalFileName = originalFileName,
// GeneratedFileName = metadata.GetProperty("FileName").GetString(), // GeneratedFileName = generatedFileName,
// FileSize = metadata.GetProperty("FileSize").GetString(), // FileSize = fileSize,
// FilePath = metadata.GetProperty("FilePath").GetString(), // FilePath = newFilePath,
// FileType = metadata.GetProperty("FileType").GetString(), // FileType = fileType,
// TagName = metadata.GetProperty("TagName").GetString(), // TagName = tagName,
// UploadDate = metadata.GetProperty("UploadDate").GetDateTime() // Use GetDateTime() // UploadDate = uploadDate
// }; // };
// // Save document record to the database
// await _entityDocumentRepository.InsertAsync(document);
// savedDocuments.Add(document); // savedDocuments.Add(document);
// var patientidexist = await _patientDocumentRepository.GetQueryableAsync().Result.Include(x => x.Patients).Include(x => x.EntityDocuments)
// .Where(x => x.Patients.Id == Patients.Id && x.TagName == document.TagName).FirstOrDefaultAsync(); // // Delete JSON file after processing
// var patientDocument = new PatientDocument
// {
// Patients = Patients,
// EntityDocuments = document,
// TagName = metadata.GetProperty("TagName").GetString()
// };
// if (patientidexist != null)
// {
// await _patientDocumentRepository.UpdateAsync(patientDocument);
// }
// else
// {
// await _patientDocumentRepository.InsertAsync(patientDocument);
// }
// File.Delete(jsonFilePath); // File.Delete(jsonFilePath);
// } // }
// }
// // Batch insert entity documents
// if (savedDocuments.Any())
// {
// await _entityDocumentRepository.InsertManyAsync(savedDocuments);
// }
// //// Fetch existing patient documents in one query
// //var existingPatientDocs = await _patientDocumentRepository.GetQueryableAsync()
// // .Result.Where(x => x.Patients.Id == patient.Id)
// // .ToListAsync();
// //List<PatientDocument> patientDocuments = new List<PatientDocument>();
// //foreach (var document in savedDocuments)
// //{
// // var existingDoc = existingPatientDocs.FirstOrDefault(x => x.TagName == document.TagName);
// // var patientDocument = new PatientDocument
// // {
// // Patients = patient,
// // EntityDocuments = document,
// // TagName = document.TagName
// // };
// // if (existingDoc != null)
// // {
// // existingDoc.EntityDocuments = document; // Update reference
// // await _patientDocumentRepository.UpdateAsync(existingDoc);
// // }
// // else
// // {
// // patientDocuments.Add(patientDocument);
// // }
// //}
// //// Batch insert new patient documents
// //if (patientDocuments.Any())
// //{
// // await _patientDocumentRepository.InsertManyAsync(patientDocuments);
// //}
// uniqueid.Clear();
// return savedDocuments; // return savedDocuments;
// } // }
// catch (Exception ex) // catch (Exception ex)
// { // {
// throw new Exception(ex.Message); // uniqueid.Clear();
// throw new Exception($"Error saving files for patient {patient.Id}: {ex.Message}", ex);
// } // }
//} //}
public async Task<List<EntityDocument>> SaveFileToDocument(Patient patient, List<Guid> uniqueIds, bool isNew = false) //#endregion
{
try
{
string tempFolder = Path.Combine(_env.WebRootPath, "temp");
string patientFolder = Path.Combine(_env.WebRootPath, "uploads", $"{patient.Id}({patient.Name})");
if (!Directory.Exists(patientFolder))
{
Directory.CreateDirectory(patientFolder);
}
List<EntityDocument> savedDocuments = new List<EntityDocument>();
foreach (var uniqueId in uniqueIds)
{
// Fetch all matching JSON metadata files for the current uniqueId
foreach (var jsonFilePath in Directory.EnumerateFiles(tempFolder, $"{uniqueId}(*).json"))
{
string jsonContent = await File.ReadAllTextAsync(jsonFilePath);
var metadata = JsonSerializer.Deserialize<JsonElement>(jsonContent);
string originalFileName = metadata.GetProperty("OriginalFileName").GetString();
string generatedFileName = metadata.GetProperty("FileName").GetString();
string fileSize = metadata.GetProperty("FileSize").GetString();
string filePath = metadata.GetProperty("FilePath").GetString();
string fileType = metadata.GetProperty("FileType").GetString();
string tagName = metadata.GetProperty("TagName").GetString();
DateTime uploadDate = metadata.GetProperty("UploadDate").GetDateTime();
// Move the file from temp folder to patient folder
string newFilePath = Path.Combine(patientFolder, generatedFileName);
if (File.Exists(filePath))
{
File.Move(filePath, newFilePath, true);
}
newFilePath = newFilePath.Split("wwwroot")[1];
var document = new EntityDocument
{
OriginalFileName = originalFileName,
GeneratedFileName = generatedFileName,
FileSize = fileSize,
FilePath = newFilePath,
FileType = fileType,
TagName = tagName,
UploadDate = uploadDate
};
savedDocuments.Add(document);
// Delete JSON file after processing
File.Delete(jsonFilePath);
}
}
// Batch insert entity documents
if (savedDocuments.Any())
{
await _entityDocumentRepository.InsertManyAsync(savedDocuments);
}
// Fetch existing patient documents in one query
var existingPatientDocs = await _patientDocumentRepository.GetQueryableAsync()
.Result.Where(x => x.Patients.Id == patient.Id)
.ToListAsync();
List<PatientDocument> patientDocuments = new List<PatientDocument>();
foreach (var document in savedDocuments)
{
var existingDoc = existingPatientDocs.FirstOrDefault(x => x.TagName == document.TagName);
var patientDocument = new PatientDocument
{
Patients = patient,
EntityDocuments = document,
TagName = document.TagName
};
if (existingDoc != null)
{
existingDoc.EntityDocuments = document; // Update reference
await _patientDocumentRepository.UpdateAsync(existingDoc);
}
else
{
patientDocuments.Add(patientDocument);
}
}
// Batch insert new patient documents
if (patientDocuments.Any())
{
await _patientDocumentRepository.InsertManyAsync(patientDocuments);
}
uniqueid.Clear();
return savedDocuments;
}
catch (Exception ex)
{
uniqueid.Clear();
throw new Exception($"Error saving files for patient {patient.Id}: {ex.Message}", ex);
}
}
#endregion
} }
} }

View File

@ -12,6 +12,8 @@ namespace HospitalManagementSystem.Patients
{ {
public class Patient : AuditedAggregateRoot<Guid> public class Patient : AuditedAggregateRoot<Guid>
{ {
[Required]
public string PatientCardId { get; set; }
[Required] [Required]
public string Name { get; set; } public string Name { get; set; }
[Required] [Required]
@ -22,16 +24,11 @@ namespace HospitalManagementSystem.Patients
public string Email { get; set; } public string Email { get; set; }
[Required] [Required]
public int Age { get; set; } public int Age { get; set; }
public string Treatment { get; set; }
public string DoctorAssigned { get; set; }
[Required] [Required]
public string Address { get; set; } public string Address { get; set; }
[Required] [Required]
public string BloodGroup { get; set; } public string BloodGroup { get; set; }
public DateTime AdmissionDate { get; set; } public string InsuranceProvider { get; set; }
public DateTime? DischargeDate { get; set; }
[Required]
public Status Status { get; set; }
public EntityDocument? Images { get; set; } public EntityDocument? Images { get; set; }
} }
} }

View File

@ -8,40 +8,24 @@ using System.ComponentModel.DataAnnotations;
using HospitalManagementSystem.GlobalEnum; using HospitalManagementSystem.GlobalEnum;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using HospitalManagementSystem.Documents; using HospitalManagementSystem.Documents;
using HospitalManagementSystem.Doctors;
namespace HospitalManagementSystem.Patients namespace HospitalManagementSystem.Patients
{ {
public class PatientRecord : AuditedAggregateRoot<Guid> public class PatientRecord : AuditedAggregateRoot<Guid>
{ {
//[Required]
//public string FullName { get; set; }
//[Required]
//public string Mobile { get; set; }
//[Required]
//public Gender Gender { get; set; }
public virtual Patient Patients { get; set; } public virtual Patient Patients { get; set; }
[Required] [Required]
public DateTime DateOfAdmission { get; set; } public DateTime DateOfAdmission { get; set; }
public DateTime? DischargeDate { get; set; }
public string Diagnosis { get; set; }
public string TreatmentPlan { get; set; }
public string DoctorNotes { get; set; }
public virtual EntityDocument? LabReportUrl { get; set; }
public virtual EntityDocument? MedicationUrl { get; set; }
public virtual EntityDocument? MedicationHistoryUrl { get; set; }
public DateTime? NextFollowUp { get; set; } public DateTime? NextFollowUp { get; set; }
public string? Diagnosis { get; set; }
public string InsuranceProvider { get; set; } public string? TreatmentPlan { get; set; }
public Doctor? DoctorAssigned { get; set; }
public string? DoctorNotes { get; set; }
public virtual EntityDocument? LabReportUrl { get; set; }
public virtual EntityDocument? MedicationUrl { get; set; }
public virtual EntityDocument? MedicationHistoryUrl { get; set; }
[Required] [Required]
public Status Status { get; set; } public Status Status { get; set; }
} }

View File

@ -373,9 +373,6 @@ namespace HospitalManagementSystem.Migrations
.IsRequired() .IsRequired()
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.Property<DateTime>("AdmissionDate")
.HasColumnType("datetime2");
b.Property<int>("Age") b.Property<int>("Age")
.HasColumnType("int"); .HasColumnType("int");
@ -398,13 +395,6 @@ namespace HospitalManagementSystem.Migrations
.HasColumnType("uniqueidentifier") .HasColumnType("uniqueidentifier")
.HasColumnName("CreatorId"); .HasColumnName("CreatorId");
b.Property<DateTime?>("DischargeDate")
.HasColumnType("datetime2");
b.Property<string>("DoctorAssigned")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Email") b.Property<string>("Email")
.IsRequired() .IsRequired()
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
@ -420,6 +410,10 @@ namespace HospitalManagementSystem.Migrations
b.Property<Guid?>("ImagesId") b.Property<Guid?>("ImagesId")
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
b.Property<string>("InsuranceProvider")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime?>("LastModificationTime") b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime2") .HasColumnType("datetime2")
.HasColumnName("LastModificationTime"); .HasColumnName("LastModificationTime");
@ -436,10 +430,7 @@ namespace HospitalManagementSystem.Migrations
.IsRequired() .IsRequired()
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.Property<int>("Status") b.Property<string>("PatientCardId")
.HasColumnType("int");
b.Property<string>("Treatment")
.IsRequired() .IsRequired()
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
@ -474,11 +465,15 @@ namespace HospitalManagementSystem.Migrations
.HasColumnType("datetime2"); .HasColumnType("datetime2");
b.Property<string>("Diagnosis") b.Property<string>("Diagnosis")
.IsRequired()
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.Property<DateTime?>("DischargeDate")
.HasColumnType("datetime2");
b.Property<Guid?>("DoctorAssignedId")
.HasColumnType("uniqueidentifier");
b.Property<string>("DoctorNotes") b.Property<string>("DoctorNotes")
.IsRequired()
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.Property<string>("ExtraProperties") b.Property<string>("ExtraProperties")
@ -486,10 +481,6 @@ namespace HospitalManagementSystem.Migrations
.HasColumnType("nvarchar(max)") .HasColumnType("nvarchar(max)")
.HasColumnName("ExtraProperties"); .HasColumnName("ExtraProperties");
b.Property<string>("InsuranceProvider")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<Guid?>("LabReportUrlId") b.Property<Guid?>("LabReportUrlId")
.HasColumnType("uniqueidentifier"); .HasColumnType("uniqueidentifier");
@ -517,11 +508,12 @@ namespace HospitalManagementSystem.Migrations
.HasColumnType("int"); .HasColumnType("int");
b.Property<string>("TreatmentPlan") b.Property<string>("TreatmentPlan")
.IsRequired()
.HasColumnType("nvarchar(max)"); .HasColumnType("nvarchar(max)");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("DoctorAssignedId");
b.HasIndex("LabReportUrlId"); b.HasIndex("LabReportUrlId");
b.HasIndex("MedicationHistoryUrlId"); b.HasIndex("MedicationHistoryUrlId");
@ -2321,6 +2313,10 @@ namespace HospitalManagementSystem.Migrations
modelBuilder.Entity("HospitalManagementSystem.Patients.PatientRecord", b => modelBuilder.Entity("HospitalManagementSystem.Patients.PatientRecord", b =>
{ {
b.HasOne("HospitalManagementSystem.Doctors.Doctor", "DoctorAssigned")
.WithMany()
.HasForeignKey("DoctorAssignedId");
b.HasOne("HospitalManagementSystem.Documents.EntityDocument", "LabReportUrl") b.HasOne("HospitalManagementSystem.Documents.EntityDocument", "LabReportUrl")
.WithMany() .WithMany()
.HasForeignKey("LabReportUrlId"); .HasForeignKey("LabReportUrlId");
@ -2339,6 +2335,8 @@ namespace HospitalManagementSystem.Migrations
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.Navigation("DoctorAssigned");
b.Navigation("LabReportUrl"); b.Navigation("LabReportUrl");
b.Navigation("MedicationHistoryUrl"); b.Navigation("MedicationHistoryUrl");

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB