100% found this document useful (1 vote)
215 views

COMP1551 - Application Development Coursework

The document titled "COMP1551 Coursework" is a detailed project report for the module COMP1551 at the University of Greenwich. It describes the development of a Desktop Information System designed to manage data for an educational institution, including administrative, teaching, and student information. Key highlights of the report include: Software Requirements Specification (SRS): This section outlines the system's purpose, scope, and features, such as administrator, teacher, and student data

Uploaded by

Ace
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
215 views

COMP1551 - Application Development Coursework

The document titled "COMP1551 Coursework" is a detailed project report for the module COMP1551 at the University of Greenwich. It describes the development of a Desktop Information System designed to manage data for an educational institution, including administrative, teaching, and student information. Key highlights of the report include: Software Requirements Specification (SRS): This section outlines the system's purpose, scope, and features, such as administrator, teacher, and student data

Uploaded by

Ace
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 83

001306081 COMP1551

University of Greenwich ID Number: 001306081

FPT Student ID Number: GCD220190

Module Code: COMP1551

Module Assessment Title: Coursework

Lecturer Name: Nguyen The Nghia

Submission Date: 19/08/2024

Number of words: 1732 (excluding table of contents, heading and code fields)

GCD220190
001306081 COMP1551

Table of Contents
1. Description of the System..................................................................................................2
2. Software Requirements Specification................................................................................ 2
2.1. Introduction..................................................................................................................... 2
2.1.1. Purpose................................................................................................................... 2
2.1.2. Project Scope...........................................................................................................2
2.2. Overall Description.......................................................................................................... 2
2.2.1. Product.................................................................................................................... 2
2.2.2. Users........................................................................................................................3
2.2.3. Operational Environment........................................................................................ 3
2.3. System Features...............................................................................................................3
2.3.1. Description.............................................................................................................. 3
2.3.2. Functional Requirements........................................................................................ 3
2.4. User Interface.................................................................................................................. 3
2.4.1. View All Users Interface...........................................................................................4
2.4.2. View Admin Interface.............................................................................................. 5
2.4.3. View Teacher Interface............................................................................................ 5
2.4.4. View Student Interface............................................................................................6
2.5. Platform........................................................................................................................... 6
2.6. Quality Attributes.............................................................................................................7
2.6.1. Performance............................................................................................................7
2.6.2. Security....................................................................................................................7
2.6.3. Safety.......................................................................................................................7
3. UML.................................................................................................................................. 7
3.1. Class Diagram...................................................................................................................7
3.2. Use Case Diagram............................................................................................................ 8
4. Object-Oriented Programming...........................................................................................9
4.1. Class................................................................................................................................. 9
4.1.1. Person......................................................................................................................9
4.1.2. Admin.................................................................................................................... 12
4.1.3. Teacher.................................................................................................................. 15
4.1.4. Student.................................................................................................................. 18
4.2. OOP Features................................................................................................................. 19

GCD220190

0
001306081 COMP1551

4.2.1. Inheritance............................................................................................................ 19
4.2.2. Encapsulation........................................................................................................ 19
4.2.3. Polymorphism....................................................................................................... 19
5. Testing.............................................................................................................................19
6. Future Improvements...................................................................................................... 21
7. Appendix.........................................................................................................................22
7.1. Classes............................................................................................................................22
7.1.1. Person.cs............................................................................................................... 22
7.1.2. Admin.cs................................................................................................................25
7.1.3. Teacher.cs.............................................................................................................. 27
7.1.4. Student.cs..............................................................................................................30
7.1.5. Role.cs................................................................................................................... 33
7.1.6. EmploymentType.cs.............................................................................................. 33
7.2. Form and User Controls................................................................................................. 34
7.2.1. MainForm.cs..........................................................................................................34
7.2.2. AllUsers.cs............................................................................................................. 37
7.2.3. AdminData.cs........................................................................................................ 40
7.2.4. TeacherData.cs...................................................................................................... 48
7.2.5. StudentData.cs...................................................................................................... 58
7.3. Testing Evidence.............................................................................................................69
7.3.1. Test Case 1.............................................................................................................69
7.3.2. Test Case 2.............................................................................................................69
7.3.3. Test Case 3.............................................................................................................70
7.3.4. Test Case 4.............................................................................................................71
7.3.5. Test Case 5.............................................................................................................72
7.3.6. Test Case 6.............................................................................................................73
7.3.7. Test Case 7.............................................................................................................74
7.3.8. Test Case 8.............................................................................................................75
7.3.9. Test Case 9.............................................................................................................76
7.3.10. Test Case 10.........................................................................................................77
7.3.11. Test Case 11.........................................................................................................78
7.3.12. Test Case 12.........................................................................................................79
7.3.13. Test Case 13.........................................................................................................80
7.3.14. Test Case 14.........................................................................................................81

GCD220190 1
001306081 COMP1551

1. Description of the System


The Desktop Information System is designed as a powerful tool to improve an
education centre’s efficiency. The system is aimed at the administrators to manage
student details and staff information.
The system stores information about the administrators, including their salaries,
employment type, and working hours. As for the teaching staff, who I called teachers,
have information about their salaries and the two subjects they are teaching. For the
students, the administrator can manage the information about the two subjects they
are learning and the subjects they have learnt.
The Desktop Information System will be deployed on Microsoft Windows, and it is
expected to run on modern computers with standard hardware configurations,
including at least 4 GB of RAM, a multi-core processor, and enough storage space for
managing the databases.

2. Software Requirements Specification


2.1. Introduction
2.1.1. Purpose
The Desktop Information System's main goal is to give the educational facility enough
tools to manage staff and student data. Its goal is to support administrators who
manage staff and student data by ensuring effective resource management and
streamlined procedures.
2.1.2. Project Scope
The Desktop Information System will be used to handle student, faculty, and
administrative data. This contains information about pay, job type, administrator
working hours, subjects taught by teachers, and subjects that pupils have learnt. The
system is anticipated to function on contemporary PCs with standard hardware and will
be installed on Microsoft Windows.
2.2. Overall Description
2.2.1. Product
A desktop-based software program called the Desktop Information System was created
to manage and save data pertaining to the academic and administrative operations of
educational institutions. It offers administrators an easy-to-use interface for swiftly
accessing, updating, and reporting on a variety of data points.

GCD220190 2
001306081 COMP1551

2.2.2. Users
The administrators of the education centre are the system's main users. These users will
deal with staff and student records on a daily basis through the system. The teachers
and students are the users that have information stored in the system, not directly the
ones that use the system.
2.2.3. Operational Environment
The Desktop Information System is designed to run on the Microsoft Windows OS,
requiring a minimum of 4 GB of RAM, a multi-core processor, and adequate storage
capacity for database management.
Database management system that I use for this project is SQL Server by Microsoft. and
the project is developed with C#.
2.3. System Features
2.3.1. Description
Several important modules will be included in the Desktop Information System,
including:
a. Administrator Management is in charge of handling data regarding wages, types
of employment, and working hours.
b. Teacher Management, which oversees the subjects each teacher teaches as well
as pay information.
c. Information on the disciplines that students are studying and finishing is kept in
Student Management.
2.3.2. Functional Requirements
Upon starting, all user data that is kept in the system database should be displayed. The
system administrator has the option to see the data according to role (student,
instructor, administrator). The system shall enable the administrator to view every
record for every role, add new records, change current records, and remove records for
the selected role in each role view.
2.4. User Interface
The system features a user-friendly graphical user interface, allowing the administrator
to navigate through different modules easily. The interface includes a clear menu and a
data entry form to help the administrators manage the records efficiently.
In addition, the system uses consistent graphical elements throughout the modules.

GCD220190 3
001306081 COMP1551

2.4.1. View All Users Interface

Figure 1. View All Users

In the “View All Users” interface, a table of all information of the users stored in
database is displayed. The columns represent the attributes of the users. The empty
values mean that the user does not have that attribute.
In this interface, you can only view but can not modify the information of the users.

GCD220190 4
001306081 COMP1551

2.4.2. View Admin Interface

Figure 2. View Admin

In the View Admin interface, there is a a table displaying the information of the
administrators. This interface is also where you can add, edit and delete an admin.
2.4.3. View Teacher Interface

GCD220190 5
001306081 COMP1551

Figure 3. View Teacher

Similar to the “View Admin” interface, this interface shows the information of the users
with the role “Teacher”, including their PersonID, TeacherID, basic information, and
role-specific information, such as salary and teaching subjects.
This interface is also where you can add, edit and delete users with “Teacher” role.
2.4.4. View Student Interface

Figure 4. View Student

In the “View Student” interface, the information of the students are displayed in the
table, including basic information and the subjects they are learning and completed.
In this interface, you can add new student, edit the information of the student, and
delete the students’ records. You can choose the subjects with the drop-down field,
which ensure the consistency in storing the information about the subjects.
2.5. Platform
The system is designed for deployment on the Microsoft Windows OS and requires a
minimum of 4 GB of RAM, a multi-core processor, and sufficient storage space for
handling databases.

GCD220190 6
001306081 COMP1551

2.6. Quality Attributes


2.6.1. Performance
The system is optimised to ensure quick response times during data entry, data
retrieval, data update, and data deletion.
2.6.2. Security
Since there are currently no user authentication procedures in place and the system is
only intended for usage by administrators, anyone with access to the administrator's
computer can alter any data in the system.
2.6.3. Safety
At the moment, the system only has confirmation prompts when deleting a record to
prevent accidental deletion.

3. UML
3.1. Class Diagram

Figure 5. Class Diagram

The Desktop Information System for an educational institution, which manages data
concerning three main user groups—Administration, Teaching Staff, and Students—is
depicted in the Class Diagram.

GCD220190 7
001306081 COMP1551

The Person class, which encapsulates common attributes like name, phone number,
email, and role in the education facility, is the main class, as illustrated in figure 5. The
particular user groups inherit from this superclass.
The Administration class is exclusive to the system administrator. It contains
characteristics pertaining to employment and pay in addition to system activities for
managing records.
The Teacher class adds unique properties pertinent to teaching professionals, like
compensation and subjects taught, while inheriting basic attributes from the "Pesron"
class.
Presenting the students of the education centre, the Student class focusses on their
academic records while capturing particular traits that are pertinent to the students.
A person's potential roles within the system are defined by the Role class.
The "Administration" class is linked to the EmploymentType class, which indicates
whether an administrator works full- or part-time.
3.2. Use Case Diagram

Figure 6. Use Case Diagram

The Use Case diagram above shows the functionalities and interactions within the
system. In the system, there are three primary user roles: Administrator, Teacher and
Student.

GCD220190 8
001306081 COMP1551

The core functions of the system are encapsulated in use cases such as “Add New Data”,
“Edit Existing Data”, Delete Existing Data”, and “View All Existing Data”. These functions
are fundamental to data management within the system.
The use case “View Existing Data of the Role” is included within the “Add New Data”
meaning that when you create a new user record of a certain role, you will see the
records of that role.

4. Object-Oriented Programming
4.1. Class
4.1.1. Person
public class Person
{
// Connect to the database
SqlConnection conn = new SqlConnection(@"Data
Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\ADMIN\Documents\comp1551
_coursework.mdf;Integrated Security=True;Connect Timeout=30;Encrypt=False");

// Data members
public int PersonID { get; internal set; } // internal set so that it can
only be set within the class
public string Name { get; set; }
public string Telephone { get; set; }
public string Email { get; set; }
public Role UserRole { get; set; }
public decimal? Salary { get; set; }
public string TeachingSubject1 { get; set; }
public string TeachingSubject2 { get; set; }
public string CurrentSubject1 { get; set; }
public string CurrentSubject2 { get; set; }
public string PreviousSubject1 { get; set; }
public string PreviousSubject2 { get; set; }

// Constructor and method


...
}

Above is the data members of the class Person, including PersonID, Name,
Telephone, Email, UserRole, Salary, TeachingSubject1, TeachingSubject2,
CurrentSubject1, CurrentSubject2, PreviousSubject1, and
PreviousSubject2. Not all the data members are for the Person object, but they are
there to help retrieve all people from the database later on by joining multiple tables.

GCD220190 9
001306081 COMP1551

// Default constructor
public Person() { }

// Constructor to create a Person object with the specified values


public Person(string name, string telephone, string email, Role userRole)
{
Name = name;
Telephone = telephone;
Email = email;
UserRole = userRole;
}

The class has a default constructor and a constructor that takes name, telephone,
email, and userRole parameters to create a Person object.
// Method to retrieve a list of all people from the database
public List<Person> UserList()
{
// Create an empty list to store the retrieved users
List<Person> users = new List<Person>();

if (conn.State != ConnectionState.Open)
{
try
{
conn.Open();
// SQL query to retrieve user data from multiple tables
string query = @"SELECT
p.PersonID, p.Name, p.Telephone, p.Email, p.Role,
COALESCE(a.Salary, t.Salary) AS Salary,
t.TeachingSubject1, t.TeachingSubject2,
s.CurrentSubject1, s.CurrentSubject2,
s.PreviousSubject1, s.PreviousSubject2
FROM Person p
LEFT JOIN Admin a ON p.PersonID = a.PersonID
LEFT JOIN Teacher t ON p.PersonID = t.PersonID
LEFT JOIN Student s ON p.PersonID = s.PersonID
";
using (SqlCommand cmd = new SqlCommand(query, conn))
{
// Execute the command and create a SqlDataReader to read the
results
SqlDataReader reader = cmd.ExecuteReader();
{

GCD220190 10
001306081 COMP1551

// Loop through each row in the result set retrieved from


the database
while (reader.Read())
{
Person user = new Person();
{
// Assign values from the reader to the user object
user.PersonID = Convert.ToInt32(reader["PersonID"]);
user.Name = reader["Name"].ToString();
user.Telephone = reader["Telephone"].ToString();
user.Email = reader["Email"].ToString();
user.UserRole = (Role)Enum.Parse(typeof(Role),
reader["Role"].ToString());
user.Salary = reader["Salary"] == DBNull.Value ?
(decimal?)null : Convert.ToDecimal(reader["Salary"]);
user.TeachingSubject1 =
reader["TeachingSubject1"].ToString();
user.TeachingSubject2 =
reader["TeachingSubject2"].ToString();
user.CurrentSubject1 =
reader["CurrentSubject1"].ToString();
user.CurrentSubject2 =
reader["CurrentSubject2"].ToString();
user.PreviousSubject1 =
reader["PreviousSubject1"].ToString();
user.PreviousSubject2 =
reader["PreviousSubject2"].ToString();
}
users.Add(user);
}
// Close the SqlDataReader to release resources
reader.Close();
}
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally

GCD220190 11
001306081 COMP1551

{
conn.Close();
}
}
return users;
}

The UserList() method retrieves a list of all people from the database using a SQL
query that joins Person, Admin, and Student tables to get all the relevant data of all
the user groups. The method then returns a List<Person> object.
The UserList() method handles any SqlException or Exception that may occur
during the database operation and displays the error message using
MessageBox.Show().
For the full code of the Person class, you can find it the Appendix 9.6
4.1.2. Admin
public class Admin : Person // Inherite from Person class
{
SqlConnection conn = new SqlConnection(@"Data
Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\ADMIN\Documents\comp1551
_coursework.mdf;Integrated Security=True;Connect Timeout=30;Encrypt=False");

// Data members
public string AdminID { get; set; }
public new decimal Salary { get; set; } // Overrides Person.Salary
public EmploymentType employmentType { get; set; }
public int WorkingHours { get; set; }

// Constructor and methods


}

The Admin class inherits from the Person class. The Sqlconnection conn is used to
connect to the SQL Server database for SQL query below.
The data members of the Admin class are AdminID, Salary, employmentType, and
WorkingHours. The Salary property in the Admin class overrides the
Person.Salary property.
// Default constructor
public Admin() { }

// Constructor to create an Admin object with the specified values

GCD220190 12
001306081 COMP1551

public Admin (int personID, string name, string telephone, string email, Role
userRole, string adminID, decimal salary, EmploymentType employmentType, int
workingHours)
: base(name, telephone, email, userRole)
{
this.PersonID = personID;
this.Name = name;
this.Telephone = telephone;
this.Email = email;
this.UserRole = userRole;
this.AdminID = adminID;
this.Salary = salary;
this.employmentType = employmentType;
this.WorkingHours = workingHours;
}

The class has a default constructor and a constructor that takes personID, name,
telephone, email, and userRole parameters inherited from the Person class
together with adminID, salary, employmentType, and workingHours parameters
to create an Admin object.
The this. prefix keyword is used to explicitly refer to the class member variables,
ensuring that they are assigned the values passed as parameters to the constructor.
This prefix helps ensuring that the class member variables are properly initialized.
// Method to retrieve a list of all Admin objects from the databas
public List<Admin> admins()
{
// Create an empty list to store retrieved Admin objects
List<Admin> adminList = new List<Admin>();

if (conn.State != ConnectionState.Open)
{
try
{
// Open the connection to the database
conn.Open();
// SQL query to retrieve Admin data with a join on the Person table
string query = @"SELECT
p.PersonID, a.AdminID, p.Name, p.Telephone, p.Email,
a.Salary, a.EmploymentType, a.WorkingHours
FROM Admin a
LEFT JOIN Person p ON a.PersonID = p.PersonID
WHERE p.Role = 'Admin'

GCD220190 13
001306081 COMP1551

ORDER BY a.AdminID";

using (SqlCommand cmd = new SqlCommand(query, conn)) // Create a


command object for the query
{
SqlDataReader reader = cmd.ExecuteReader(); // Execute the query
and create a SqlDataReader
while (reader.Read()) // Loop through each row returned by the
query
{
Admin admin = new Admin(); // Create a new Admin object
{
// Assign values from the data reader to the Admin
object properties
admin.PersonID = Convert.ToInt32(reader["PersonID"]);
admin.AdminID = reader["AdminID"].ToString();
admin.Name = reader["Name"].ToString();
admin.Telephone = reader["Telephone"].ToString();
admin.Email = reader["Email"].ToString();
admin.Salary = Convert.ToDecimal(reader["Salary"]);
admin.employmentType =
(EmploymentType)Enum.Parse(typeof(EmploymentType),
reader["EmploymentType"].ToString());
admin.WorkingHours =
Convert.ToInt32(reader["WorkingHours"]);
};
adminList.Add(admin); // Add the created Admin object to the
list
}
reader.Close();
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
conn.Close();
}

GCD220190 14
001306081 COMP1551

}
return adminList;
}

The admins() method retrieves a list of all Admin objects from the database using a
SQL query that joins the Admin and Person tables to get all the relevant data. This
method returns a List<Admin> object. The method also ensures that the database
connection is closed arter the operation is completed, regardless of whether an
exception occurred or not.
The method also handles any Exception may occur during the database operation
4.1.3. Teacher
public class Teacher : Person // Inherite from Person class
{
SqlConnection conn = new SqlConnection(@"Data
Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\ADMIN\Documents\comp1551
_coursework.mdf;Integrated Security=True;Connect Timeout=30;Encrypt=False");

// Data members
public string TeacherID { get; set; }
public new decimal Salary { get; set; } // Overrides Person.Salary
public new string TeachingSubject1 { get; set; } // Overrides
Person.TeachingSubject1
public new string TeachingSubject2 { get; set; } // Overrides
Person.TeachingSubject2

// Constructor and method


}

The Teacher class also inherited from the Person class, and has several data
members, including TeacherID, Salary that overrides the Person.Salary
property, TeachingSubject1 and TeachingSubject2, which also override the
properties of the Person class.
// Default constructor
public Teacher() { }

// Constructor to create a Teacher object with the specified values


public Teacher(int personID, string name, string telephone, string email, Role
userRole, string teacherID, decimal salary, string teachingSubject1, string
teachingSubject2)
: base(name, telephone, email, userRole)
{

GCD220190 15
001306081 COMP1551

this.PersonID = personID;
this.Name = name;
this.Telephone = telephone;
this.Email = email;
this.UserRole = userRole;
this.TeacherID = teacherID;
this.Salary = salary;
this.TeachingSubject1 = teachingSubject1;
this.TeachingSubject2 = teachingSubject2;
}

The class has a default constructor as well, and a constructor that takes parameters to
create a Teacher object.
// Method to retrieve a list of all Teacher objects from the database
public List<Teacher> teachers()
{
// Create an empty list to store retrieved Teacher objects
List<Teacher> teacherList = new List<Teacher>();

if(conn.State != ConnectionState.Open)
{
try
{
conn.Open(); // Open the connection to the database

// SQL query to retrieve Teacher data with a join on the Person


table
string query = @"SELECT
p.PersonID, t.TeacherID, p.Name, p.Telephone, p.Email, t.Salary,
t.TeachingSubject1, t.TeachingSubject2
FROM Teacher t
LEFT JOIN Person p ON t.PersonID = p.PersonID
WHERE p.Role = 'Teacher'
ORDER BY t.TeacherID";

using (SqlCommand cmd = new SqlCommand(query, conn)) // Create a


command object for the query
{
SqlDataReader reader = cmd.ExecuteReader(); // Execute the query
and create a SqlDataReader

while (reader.Read()) // Loop through each row returned by the


query

GCD220190 16
001306081 COMP1551

{
Teacher teacher = new Teacher(); // Create a new Teacher
object
{
// Assign values from the data reader to the Teacher
object properties
teacher.PersonID = Convert.ToInt32(reader["PersonID"]);
teacher.TeacherID = reader["TeacherID"].ToString();
teacher.Name = reader["Name"].ToString();
teacher.Telephone = reader["Telephone"].ToString();
teacher.Email = reader["Email"].ToString();
teacher.Salary = Convert.ToDecimal(reader["Salary"]);
teacher.TeachingSubject1 =
reader["TeachingSubject1"].ToString();
teacher.TeachingSubject2 =
reader["TeachingSubject2"].ToString();
};
teacherList.Add(teacher);
}
reader.Close();
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
conn.Close();
}
}
return teacherList;
}

The teachers() method retrieves a list of all Teacher objects from the database by
joining the Teacher and Person tables to get all the relevant data. The method
returns a List<Teacher> object.
The method handles any Exception that may occur and displays the error message
using MessageBox.Show()

GCD220190 17
001306081 COMP1551

4.1.4. Student
public class Student : Person // Inherite from Person class
{
SqlConnection conn = new SqlConnection(@"Data
Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\ADMIN\Documents\comp1551
_coursework.mdf;Integrated Security=True;Connect Timeout=30;Encrypt=False");

// Data members
public string StudentID { get; set; }
public new string CurrentSubject1 { get; set; } // Overrides
Person.CurrentSubject1
public new string CurrentSubject2 { get; set; } // Overrides
Person.CurrentSubject2
public new string PreviousSubject1 { get; set; } // Overrides
Person.PreviousSubject1
public new string PreviousSubject2 { get; set; } // Overrides
Person.PreviousSubject2

// Constructor and method


...
}

The Student class is another class that inherits from the Person class. Its data
members are also override some of the Person class properties.
// Default constructor
public Student() { }

// Constructor to create a Student object with the specified values


public Student(int personID, string name, string telephone, string email, Role
userRole, string studentID, string currentSubject1, string currentSubject2,
string previousSubject1, string previousSubject2)
: base(name, telephone, email, userRole)
{
this.PersonID = personID;
this.Name = name;
this.Telephone = telephone;
this.Email = email;
this.UserRole = userRole;
this.StudentID = studentID;
this.CurrentSubject1 = currentSubject1;
this.CurrentSubject2 = currentSubject2;
this.PreviousSubject1 = previousSubject1;
this.PreviousSubject2 = previousSubject2;

GCD220190 18
001306081 COMP1551

Similar to the Admin and Teacher classes, the Student class also has a default
constructor and a constructor that takes the parameters to create a Student object.
4.2. OOP Features
4.2.1. Inheritance
The Admin, Teacher, and Student classes all inherit from the Person class,
demonstrating the use of inheritance in OOP.
4.2.2. Encapsulation
Data encapsulation is demonstrated by the classes, which have private data members
and offer public properties for data access and modification.
4.2.3. Polymorphism
Method overriding, a type of polymorphism, is demonstrated by the Salary,
TeachingSubject1, TeachingSubject2, CurrentSubject1,
CurrentSubject2, PreviousSubject1, and PreviousSubject2 properties in the
derived classes overriding the corresponding properties in the parent Person class.

5. Testing
No. Test Scenario Expected Actual Evidence Pass/Fail
Result Result

1 View All Users View All View All Evidence


Users with Users with Pass
all attributes all attributes

2 View Admin View all View all Evidence


admin with admin with Pass
relevant relevant
values values

3 Add Admin Add new Add new Evidence


admin and admin and Pass
reload the reload the
data table data table

GCD220190 19
001306081 COMP1551

4 Edit Admin Reload the Reload the Evidence


data table data table Pass
with new with new
admin admin
information information

5 Delete Admin The admin The admin Evidence


record no record no Pass
longer longer
displays on displays on
the data the data
table table

6 View Teachers View all View all Evidence


teachers teachers Pass
with with
relevant relevant
values values

7 Add Teacher New record New record Evidence


of the of the Pass
teacher on teacher on
the data the data
table table

8 Edit Teacher New New Evidence


information information Pass
of the of the
teacher on teacher on
the data the data
table table

9 Delete Teacher The teacher The teacher Evidence


record no record no Pass
longer longer
displays on displays on
the data the data
table table

GCD220190 20
001306081 COMP1551

10 View Students View all View all Evidence


records of records of Pass
students students
with with
relevant relevant
attributes attributes

11 Add Student New student New student Evidence


record on record on Pass
the data the data
table table

12 Edit Student Updated Updated Evidence


student student Pass
record on record on
the data the data
table table

13 Delete Student No student No student Evidence


record on record on Pass
the data the data
table table

14 Check for duplicate Show error Show error Evidence


subject message if message if Pass
the subjects the subjects
are are
duplicated duplicated

6. Future Improvements
This is a simple application and still lacks some functionalities that can improve the
experience of using the system. In the future, there is a potential for further
improvements, such as adding authentication and allow the teachers and students to
use the system.

GCD220190 21
001306081 COMP1551

7. Appendix
7.1. Classes
7.1.1. Person.cs
using COMP1551_Coursework.Models.Enums;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;

namespace COMP1551_Coursework.Models
{
public class Person
{
// Connect to the database
SqlConnection conn = new SqlConnection(@"Data
Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\ADMIN\Documents\comp1551
_coursework.mdf;Integrated Security=True;Connect Timeout=30;Encrypt=False");

// Data members
public int PersonID { get; internal set; } // internal set so that it
can only be set within the class
public string Name { get; set; }
public string Telephone { get; set; }
public string Email { get; set; }
public Role UserRole { get; set; }
public decimal? Salary { get; set; }
public string TeachingSubject1 { get; set; }
public string TeachingSubject2 { get; set; }
public string CurrentSubject1 { get; set; }
public string CurrentSubject2 { get; set; }
public string PreviousSubject1 { get; set; }
public string PreviousSubject2 { get; set; }

// Default constructor
public Person() { }

// Constructor to create a Person object with the specified values

GCD220190 22
001306081 COMP1551

public Person(string name, string telephone, string email, Role


userRole)
{
Name = name;
Telephone = telephone;
Email = email;
UserRole = userRole;
}

// Method to retrieve a list of all people from the database


public List<Person> UserList()
{
// Create an empty list to store the retrieved users
List<Person> users = new List<Person>();

if (conn.State != ConnectionState.Open)
{
try
{
conn.Open();
// SQL query to retrieve user data from multiple tables
string query = @"SELECT
p.PersonID, p.Name, p.Telephone, p.Email,
p.Role,
COALESCE(a.Salary, t.Salary) AS Salary,
t.TeachingSubject1, t.TeachingSubject2,
s.CurrentSubject1, s.CurrentSubject2,
s.PreviousSubject1, s.PreviousSubject2
FROM Person p
LEFT JOIN Admin a ON p.PersonID = a.PersonID
LEFT JOIN Teacher t ON p.PersonID =
t.PersonID
LEFT JOIN Student s ON p.PersonID =
s.PersonID
";
using (SqlCommand cmd = new SqlCommand(query, conn))
{
// Execute the command and create a SqlDataReader to
read the results
SqlDataReader reader = cmd.ExecuteReader();
{
// Loop through each row in the result set retrieved
from the database

GCD220190 23
001306081 COMP1551

while (reader.Read())
{
Person user = new Person();
{
// Assign values from the reader to the user
object
user.PersonID =
Convert.ToInt32(reader["PersonID"]);
user.Name = reader["Name"].ToString();
user.Telephone =
reader["Telephone"].ToString();
user.Email = reader["Email"].ToString();
user.UserRole =
(Role)Enum.Parse(typeof(Role), reader["Role"].ToString());
user.Salary = reader["Salary"] ==
DBNull.Value ? (decimal?)null : Convert.ToDecimal(reader["Salary"]);
user.TeachingSubject1 =
reader["TeachingSubject1"].ToString();
user.TeachingSubject2 =
reader["TeachingSubject2"].ToString();
user.CurrentSubject1 =
reader["CurrentSubject1"].ToString();
user.CurrentSubject2 =
reader["CurrentSubject2"].ToString();
user.PreviousSubject1 =
reader["PreviousSubject1"].ToString();
user.PreviousSubject2 =
reader["PreviousSubject2"].ToString();
}
users.Add(user);
}
// Close the SqlDataReader to release resources
reader.Close();
}
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

GCD220190 24
001306081 COMP1551

}
return users;
}
}
}

7.1.2. Admin.cs
using COMP1551_Coursework.Models.Enums;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace COMP1551_Coursework.Models
{
public class Admin : Person // Inherite from Person class
{
SqlConnection conn = new SqlConnection(@"Data
Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\ADMIN\Documents\comp1551
_coursework.mdf;Integrated Security=True;Connect Timeout=30;Encrypt=False");

// Data members
public string AdminID { get; set; }
public new decimal Salary { get; set; } // Overrides Person.Salary
public EmploymentType employmentType { get; set; }
public int WorkingHours { get; set; }

// Default constructor
public Admin() { }

// Constructor to create an Admin object with the specified values


public Admin (int personID, string name, string telephone, string email,
Role userRole, string adminID, decimal salary, EmploymentType employmentType,
int workingHours)
: base(name, telephone, email, userRole)
{
this.PersonID = personID;
this.Name = name;
this.Telephone = telephone;
this.Email = email;

GCD220190 25
001306081 COMP1551

this.UserRole = userRole;
this.AdminID = adminID;
this.Salary = salary;
this.employmentType = employmentType;
this.WorkingHours = workingHours;
}

// Method to retrieve a list of all Admin objects from the databas


public List<Admin> admins()
{
// Create an empty list to store retrieved Admin objects
List<Admin> adminList = new List<Admin>();

if (conn.State != ConnectionState.Open)
{
try
{
// Open the connection to the database
conn.Open();
// SQL query to retrieve Admin data with a join on the
Person table
string query = @"SELECT
p.PersonID, a.AdminID, p.Name, p.Telephone,
p.Email,
a.Salary, a.EmploymentType, a.WorkingHours
FROM Admin a
LEFT JOIN Person p ON a.PersonID =
p.PersonID
WHERE p.Role = 'Admin'
ORDER BY a.AdminID";

using (SqlCommand cmd = new SqlCommand(query, conn)) //


Create a command object for the query
{
SqlDataReader reader = cmd.ExecuteReader(); // Execute
the query and create a SqlDataReader
while (reader.Read()) // Loop through each row returned
by the query
{
Admin admin = new Admin(); // Create a new Admin
object
{
// Assign values from the data reader to the
Admin object properties

GCD220190 26
001306081 COMP1551

admin.PersonID =
Convert.ToInt32(reader["PersonID"]);
admin.AdminID = reader["AdminID"].ToString();
admin.Name = reader["Name"].ToString();
admin.Telephone =
reader["Telephone"].ToString();
admin.Email = reader["Email"].ToString();
admin.Salary =
Convert.ToDecimal(reader["Salary"]);
admin.employmentType =
(EmploymentType)Enum.Parse(typeof(EmploymentType),
reader["EmploymentType"].ToString());
admin.WorkingHours =
Convert.ToInt32(reader["WorkingHours"]);
};
adminList.Add(admin); // Add the created Admin
object to the list
}
reader.Close();
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
conn.Close();
}
}
return adminList;
}
}
}

7.1.3. Teacher.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

GCD220190 27
001306081 COMP1551

using System.Windows.Forms;
using COMP1551_Coursework.Models.Enums;

namespace COMP1551_Coursework.Models
{
public class Teacher : Person // Inherite from Person class
{
SqlConnection conn = new SqlConnection(@"Data
Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\ADMIN\Documents\comp1551
_coursework.mdf;Integrated Security=True;Connect Timeout=30;Encrypt=False");

// Data members
public string TeacherID { get; set; }
public new decimal Salary { get; set; } // Overrides Person.Salary
public new string TeachingSubject1 { get; set; } // Overrides
Person.TeachingSubject1
public new string TeachingSubject2 { get; set; } // Overrides
Person.TeachingSubject2

// Default constructor
public Teacher() { }

// Constructor to create a Teacher object with the specified values


public Teacher(int personID, string name, string telephone, string
email, Role userRole, string teacherID, decimal salary, string teachingSubject1,
string teachingSubject2)
: base(name, telephone, email, userRole)
{
this.PersonID = personID;
this.Name = name;
this.Telephone = telephone;
this.Email = email;
this.UserRole = userRole;
this.TeacherID = teacherID;
this.Salary = salary;
this.TeachingSubject1 = teachingSubject1;
this.TeachingSubject2 = teachingSubject2;
}

// Method to retrieve a list of all Teacher objects from the database


public List<Teacher> teachers()
{
// Create an empty list to store retrieved Teacher objects
List<Teacher> teacherList = new List<Teacher>();

GCD220190 28
001306081 COMP1551

if(conn.State != ConnectionState.Open)
{
try
{
conn.Open(); // Open the connection to the database

// SQL query to retrieve Teacher data with a join on the


Person table
string query = @"SELECT
p.PersonID, t.TeacherID, p.Name, p.Telephone, p.Email,
t.Salary,
t.TeachingSubject1, t.TeachingSubject2
FROM Teacher t
LEFT JOIN Person p ON t.PersonID = p.PersonID
WHERE p.Role = 'Teacher'
ORDER BY t.TeacherID";

using (SqlCommand cmd = new SqlCommand(query, conn)) //


Create a command object for the query
{
SqlDataReader reader = cmd.ExecuteReader(); // Execute
the query and create a SqlDataReader

while (reader.Read()) // Loop through each row returned


by the query
{
Teacher teacher = new Teacher(); // Create a new
Teacher object
{
// Assign values from the data reader to the
Teacher object properties
teacher.PersonID =
Convert.ToInt32(reader["PersonID"]);
teacher.TeacherID =
reader["TeacherID"].ToString();
teacher.Name = reader["Name"].ToString();
teacher.Telephone =
reader["Telephone"].ToString();
teacher.Email = reader["Email"].ToString();
teacher.Salary =
Convert.ToDecimal(reader["Salary"]);
teacher.TeachingSubject1 =
reader["TeachingSubject1"].ToString();

GCD220190 29
001306081 COMP1551

teacher.TeachingSubject2 =
reader["TeachingSubject2"].ToString();
};
teacherList.Add(teacher);
}
reader.Close();
}
}
catch (Exception ex)
{
MessageBox.Show("Error connection Database: " + ex.Message);
}
finally
{
conn.Close();
}
}
return teacherList;
}
}
}

7.1.4. Student.cs
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using COMP1551_Coursework.Models.Enums;

namespace COMP1551_Coursework.Models
{
public class Student : Person // Inherite from Person class
{
SqlConnection conn = new SqlConnection(@"Data
Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\ADMIN\Documents\comp1551
_coursework.mdf;Integrated Security=True;Connect Timeout=30;Encrypt=False");

// Data members
public string StudentID { get; set; }

GCD220190 30
001306081 COMP1551

public new string CurrentSubject1 { get; set; } // Overrides


Person.CurrentSubject1
public new string CurrentSubject2 { get; set; } // Overrides
Person.CurrentSubject2
public new string PreviousSubject1 { get; set; } // Overrides
Person.PreviousSubject1
public new string PreviousSubject2 { get; set; } // Overrides
Person.PreviousSubject2

// Default constructor
public Student() { }

// Constructor to create a Student object with the specified values


public Student(int personID, string name, string telephone, string
email, Role userRole, string studentID, string currentSubject1, string
currentSubject2, string previousSubject1, string previousSubject2)
: base(name, telephone, email, userRole)
{
this.PersonID = personID;
this.Name = name;
this.Telephone = telephone;
this.Email = email;
this.UserRole = userRole;
this.StudentID = studentID;
this.CurrentSubject1 = currentSubject1;
this.CurrentSubject2 = currentSubject2;
this.PreviousSubject1 = previousSubject1;
this.PreviousSubject2 = previousSubject2;
}

// Method to retrieve a list of all Student objects from the database


public List<Student> students()
{
// Create an empty list to store retrieved Student objects
List<Student> studentList = new List<Student>();

if (conn.State != ConnectionState.Open)
{
try
{
conn.Open(); // Open the connection to the database

// SQL query to retrieve Student data with a join on the


Person table

GCD220190 31
001306081 COMP1551

string query = @"SELECT


p.PersonID, s.StudentID, p.Name,
p.Telephone, p.Email,
s.CurrentSubject1, s.CurrentSubject2,
s.PreviousSubject1, s.PreviousSubject2
FROM Student s
LEFT JOIN Person p ON s.PersonID =
p.PersonID
WHERE p.Role = 'Student'
ORDER BY s.StudentID";

using (SqlCommand cmd = new SqlCommand(query, conn)) //


Create a command object for the query
{
SqlDataReader reader = cmd.ExecuteReader(); // Execute
the query and create a SqlDataReader

while (reader.Read()) // Loop through each row returned


by the query
{
Student student = new Student(); // Create a new
Student object
{
// Assign values from the data reader to the
Student object properties
student.PersonID =
Convert.ToInt32(reader["PersonID"]);
student.StudentID =
reader["StudentID"].ToString();
student.Name = reader["Name"].ToString();
student.Telephone =
reader["Telephone"].ToString();
student.Email = reader["Email"].ToString();
student.CurrentSubject1 =
reader["CurrentSubject1"].ToString();
student.CurrentSubject2 =
reader["CurrentSubject2"].ToString();
student.PreviousSubject1 =
reader["PreviousSubject1"].ToString();
student.PreviousSubject2 =
reader["PreviousSubject2"].ToString();
};
studentList.Add(student);
}

GCD220190 32
001306081 COMP1551

reader.Close();
}
}
catch (Exception ex)
{
MessageBox.Show("Error connecting Database: " + ex.Message);
}
finally
{
conn.Close();
}
}
return studentList;
}
}
}

7.1.5. Role.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace COMP1551_Coursework.Models.Enums
{
public enum Role
{
Admin, // Represents an Admin role
Teacher, // Represents a Teacher role
Student // Represents a Student role
}
}

7.1.6. EmploymentType.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace COMP1551_Coursework.Models.Enums
{

GCD220190 33
001306081 COMP1551

public enum EmploymentType


{
FullTime, // Indicates a FullTime employment
PartTime // Indicates a PartTime employment
}
}

7.2. Form and User Controls


7.2.1. MainForm.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using COMP1551_Coursework.Forms.User_Control;

namespace COMP1551_Coursework
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();

// Subscribe to the PersonAdded event


adminData1.PersonAdded += AdminData1_PersonAdded;
studentData1.PersonAdded += StudentData1_PersonAdded;
teacherData1.PersonAdded += TeacherData1_PersonAdded;

// Subscribe to the PersonUpdate even


adminData1.PersonUpdated += AdminData1_PersonUpdated;
studentData1.PersonUpdated += StudentData1_PersonUpdated;
teacherData1.PersonUpdated += TeacherData1_PersonUpdated;

// Subscribe to the PersonDeleted event

GCD220190 34
001306081 COMP1551

adminData1.PersonDeleted += AdminData1_PersonDeleted;
studentData1.PersonDeleted += StudentData1_PersonDeleted;
teacherData1.PersonDeleted += TeacherData1_PersonDeleted;

// Initially hide all user controls


HideAllUserControls();
allUsers1.Visible = true; // Show the AllUsers user control by
default when running the application
}

private void btnViewAll_Click(object sender, EventArgs e)


{
// When click on the View All button, show the AllUsers user control
HideAllUserControls();
allUsers1.Visible = true;
}

private void btnViewAdmin_Click(object sender, EventArgs e)


{
// When click on the View Admin button, show the AdminData user
control
HideAllUserControls();
adminData1.Visible = true;
}

private void btnViewTeacher_Click(object sender, EventArgs e)


{
// When click on the View Teacher button, show the TeacherData user
control
HideAllUserControls();
teacherData1.Visible = true;
}

private void btnViewStudent_Click(object sender, EventArgs e)


{
// When click on the View Student button, show the StudentData user
control
HideAllUserControls();
studentData1.Visible = true;
}

private void HideAllUserControls()


{
// Hide all user controls

GCD220190 35
001306081 COMP1551

adminData1.Visible = false;
studentData1.Visible = false;
teacherData1.Visible = false;
allUsers1.Visible = false;
}

private void AdminData1_PersonAdded(object sender, EventArgs e)


{
// Refresh the AllUsers user control
allUsers1.RefreshData();
}

private void AdminData1_PersonUpdated(object sender, EventArgs e)


{
// Refresh the AllUsers user control
allUsers1.RefreshData();
}

private void AdminData1_PersonDeleted(object sender, EventArgs e)


{
// Refresh the AllUsers user control
allUsers1.RefreshData();
}

private void StudentData1_PersonAdded(object sender, EventArgs e)


{
// Refresh the AllUsers user control
allUsers1.RefreshData();
}

private void StudentData1_PersonUpdated(object sender, EventArgs e)


{
// Refresh the AllUsers user control
allUsers1.RefreshData();
}

private void StudentData1_PersonDeleted(object sender, EventArgs e)


{
// Refresh the AllUsers user control
allUsers1.RefreshData();
}

private void TeacherData1_PersonAdded(object sender, EventArgs e)


{

GCD220190 36
001306081 COMP1551

// Refresh the AllUsers user control


allUsers1.RefreshData();
}

private void TeacherData1_PersonUpdated(object sender, EventArgs e)


{
// Refresh the AllUsers user control
allUsers1.RefreshData();
}

private void TeacherData1_PersonDeleted(object sender, EventArgs e)


{
// Refresh the AllUsers user control
allUsers1.RefreshData();
}
}
}

7.2.2. AllUsers.cs

using COMP1551_Coursework.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace COMP1551_Coursework.Forms.User_Control
{
public partial class AllUsers : UserControl
{
private AdminData adminData;// Create a new AdminData object
private TeacherData teacherData;// Create a new TeacherData object
private StudentData studentData;// Create a new StudentData object

public AllUsers(AdminData adminData, TeacherData teacherData,


StudentData studentData)
{
InitializeComponent();

GCD220190 37
001306081 COMP1551

this.adminData = adminData;
this.teacherData = teacherData;
this.studentData = studentData;

userData(); // Call the userData method to display all users


}

public void userData()


{
Person user = new Person(); // Create a new Person object

// Configure the DataGridView to not automatically generate columns


dgvUsers.AutoGenerateColumns = false;
dgvUsers.Columns.Clear(); // Clear any existing columns

// Define columns manually


DataGridViewTextBoxColumn personIDColumn = new
DataGridViewTextBoxColumn(); // // Create a new DataGridViewTextBoxColumn to
display PersonID data
personIDColumn.DataPropertyName = "PersonID"; // // Bind the column
to the "PersonID" property of the data source
personIDColumn.HeaderText = "PersonID"; // Set the header text of
the column
dgvUsers.Columns.Add(personIDColumn); // Add the column to the
DataGridView

DataGridViewTextBoxColumn nameColumn = new


DataGridViewTextBoxColumn();
nameColumn.DataPropertyName = "Name";
nameColumn.HeaderText = "Name";
dgvUsers.Columns.Add(nameColumn);

DataGridViewTextBoxColumn telephoneColumn = new


DataGridViewTextBoxColumn();
telephoneColumn.DataPropertyName = "Telephone";
telephoneColumn.HeaderText = "Telephone";
dgvUsers.Columns.Add(telephoneColumn);

DataGridViewTextBoxColumn emailColumn = new


DataGridViewTextBoxColumn();
emailColumn.DataPropertyName = "Email";
emailColumn.HeaderText = "Email";
dgvUsers.Columns.Add(emailColumn);

GCD220190 38
001306081 COMP1551

DataGridViewTextBoxColumn roleColumn = new


DataGridViewTextBoxColumn();
roleColumn.DataPropertyName = "UserRole";
roleColumn.HeaderText = "Role";
dgvUsers.Columns.Add(roleColumn);

DataGridViewTextBoxColumn salaryColumn = new


DataGridViewTextBoxColumn();
salaryColumn.DataPropertyName = "Salary";
salaryColumn.HeaderText = "Salary";
dgvUsers.Columns.Add(salaryColumn);

DataGridViewTextBoxColumn teachingSubject1Column = new


DataGridViewTextBoxColumn();
teachingSubject1Column.DataPropertyName = "TeachingSubject1";
teachingSubject1Column.HeaderText = "Teaching Subject 1";
dgvUsers.Columns.Add(teachingSubject1Column);

DataGridViewTextBoxColumn teachingSubject2Column = new


DataGridViewTextBoxColumn();
teachingSubject2Column.DataPropertyName = "TeachingSubject2";
teachingSubject2Column.HeaderText = "Teaching Subject 2";
dgvUsers.Columns.Add(teachingSubject2Column);

DataGridViewTextBoxColumn currentSubject1Column = new


DataGridViewTextBoxColumn();
currentSubject1Column.DataPropertyName = "CurrentSubject1";
currentSubject1Column.HeaderText = "Current Subject 1";
dgvUsers.Columns.Add(currentSubject1Column);

DataGridViewTextBoxColumn currentSubject2Column = new


DataGridViewTextBoxColumn();
currentSubject2Column.DataPropertyName = "CurrentSubject2";
currentSubject2Column.HeaderText = "Current Subject 2";
dgvUsers.Columns.Add(currentSubject2Column);

DataGridViewTextBoxColumn previousSubject1Column = new


DataGridViewTextBoxColumn();
previousSubject1Column.DataPropertyName = "PreviousSubject1";
previousSubject1Column.HeaderText = "Previous Subject 1";
dgvUsers.Columns.Add(previousSubject1Column);

DataGridViewTextBoxColumn previousSubject2Column = new


DataGridViewTextBoxColumn();

GCD220190 39
001306081 COMP1551

previousSubject2Column.DataPropertyName = "PreviousSubject2";
previousSubject2Column.HeaderText = "Previous Subject 2";
dgvUsers.Columns.Add(previousSubject2Column);

// Set the data source of the DataGridView to the list of users


returned by the UserList method
dgvUsers.DataSource = user.UserList();
}

public void RefreshData()


{
userData(); // Call the userData method to refresh the data
}
}
}

7.2.3. AdminData.cs

using COMP1551_Coursework.Models;
using COMP1551_Coursework.Models.Enums;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace COMP1551_Coursework.Forms.User_Control
{
public partial class AdminData : UserControl
{
public event EventHandler PersonAdded; // Declare an event to notify
subscribers when a person is added
public event EventHandler PersonUpdated; // Declare an event to notify
subscribers when a person is updated
public event EventHandler PersonDeleted; // Declare an event to notify
subscribers when a person is deleted

SqlConnection conn = new SqlConnection(@"Data


Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\ADMIN\Documents\comp1551

GCD220190 40
001306081 COMP1551

_coursework.mdf;Integrated Security=True;Connect Timeout=30;Encrypt=False");

public AdminData()
{
InitializeComponent();
LoadEmploymentTypes(); // Call the LoadEmploymentTypes method to
load the employment types into the ComboBox
adminData(); // Call the adminData method to display all admins
}

public void adminData()


{
Admin admin = new Admin(); // Create a new Admin object

dgvAdmin.AutoGenerateColumns = false; // Configure the DataGridView


to not automatically generate columns
dgvAdmin.Columns.Clear(); // Clear any existing columns

// Define columns manually


DataGridViewTextBoxColumn personIDColumn = new
DataGridViewTextBoxColumn(); // Create a new DataGridViewTextBoxColumn to
display PersonID data
personIDColumn.DataPropertyName = "PersonID"; // Bind the column to
the "PersonID" property of the data source
personIDColumn.HeaderText = "PersonID"; // Set the header text of
the column
dgvAdmin.Columns.Add(personIDColumn); // Add the column to the
DataGridView

DataGridViewTextBoxColumn studentIDColumn = new


DataGridViewTextBoxColumn();
studentIDColumn.DataPropertyName = "AdminID";
studentIDColumn.HeaderText = "AdminID";
dgvAdmin.Columns.Add(studentIDColumn);

DataGridViewTextBoxColumn nameColumn = new


DataGridViewTextBoxColumn();
nameColumn.DataPropertyName = "Name";
nameColumn.HeaderText = "Name";
dgvAdmin.Columns.Add(nameColumn);

DataGridViewTextBoxColumn telephoneColumn = new


DataGridViewTextBoxColumn();
telephoneColumn.DataPropertyName = "Telephone";

GCD220190 41
001306081 COMP1551

telephoneColumn.HeaderText = "Telephone";
dgvAdmin.Columns.Add(telephoneColumn);

DataGridViewTextBoxColumn emailColumn = new


DataGridViewTextBoxColumn();
emailColumn.DataPropertyName = "Email";
emailColumn.HeaderText = "Email";
dgvAdmin.Columns.Add(emailColumn);

DataGridViewTextBoxColumn salaryColumn = new


DataGridViewTextBoxColumn();
salaryColumn.DataPropertyName = "Salary";
salaryColumn.HeaderText = "Salary";
dgvAdmin.Columns.Add(salaryColumn);

DataGridViewTextBoxColumn employmentTypeColumn = new


DataGridViewTextBoxColumn();
employmentTypeColumn.DataPropertyName = "EmploymentType";
employmentTypeColumn.HeaderText = "EmploymentType";
dgvAdmin.Columns.Add(employmentTypeColumn);

DataGridViewTextBoxColumn workingHoursColumn = new


DataGridViewTextBoxColumn();
workingHoursColumn.DataPropertyName = "WorkingHours";
workingHoursColumn.HeaderText = "WorkingHours";
dgvAdmin.Columns.Add(workingHoursColumn);

dgvAdmin.DataSource = admin.admins(); // Bind the DataGridView to


the list of admins
}

private void btnAddAdmin_Click(object sender, EventArgs e) // Handle


click event for the Add button
{
if (conn.State != ConnectionState.Open)
{
try
{
conn.Open();

string personQuery = "INSERT INTO Person (Name, Telephone,


Email, Role) OUTPUT INSERTED.PersonID VALUES (@Name, @Telephone, @Email,
@Role)"; // Define a query to insert a new person
int personID; // Declare a variable to store the ID of the

GCD220190 42
001306081 COMP1551

new person
using (SqlCommand personCmd = new SqlCommand(personQuery,
conn)) // Create a new SqlCommand object
{
// Add parameters to the query
personCmd.Parameters.AddWithValue("@Name",
txtName.Text.Trim());
personCmd.Parameters.AddWithValue("@Telephone",
txtPhone.Text.Trim());
personCmd.Parameters.AddWithValue("@Email",
txtEmail.Text.Trim());
personCmd.Parameters.AddWithValue("@Role",
Role.Admin.ToString());
personID = (int)personCmd.ExecuteScalar(); // Execute
the query and store the ID of the new person
}

string adminQuery = "INSERT INTO Admin (PersonID, Salary,


EmploymentType, WorkingHours) VALUES (@PersonID, @Salary, @EmploymentType,
@WorkingHours)"; // Define a query to insert a new admin
using (SqlCommand adminCmd = new SqlCommand(adminQuery,
conn)) // Create a new SqlCommand object
{
// Add parameters to the query
adminCmd.Parameters.AddWithValue("@PersonID", personID);
adminCmd.Parameters.AddWithValue("@Salary",
txtSalary.Text.Trim());
adminCmd.Parameters.AddWithValue("@EmploymentType",
cBoxEployment.SelectedItem.ToString());
adminCmd.Parameters.AddWithValue("@WorkingHours",
txtWorkingHours.Text.Trim());
adminCmd.ExecuteNonQuery(); // Execute the query
}
MessageBox.Show("Admin added successfully", "Success",
MessageBoxButtons.OK, MessageBoxIcon.Information);
adminData(); // Call the adminData method to refresh the
DataGridView

// Raise the event


PersonAdded?.Invoke(this, EventArgs.Empty);
}
catch (SqlException ex)
{
MessageBox.Show("SQL Error: " + ex.Message, "Message Error",

GCD220190 43
001306081 COMP1551

MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
conn.Close();
}
}
}

private void btnUpdateAdmin_Click(object sender, EventArgs e)


{
if (conn.State != ConnectionState.Open)
{
try
{
conn.Open();

int personID = GetSelectedPersonID(); // Get the ID of the


selected admin

// Update Person table


SqlCommand updatePersonCmd = new SqlCommand( // Create a new
SqlCommand object to update the Person table
"UPDATE Person SET Name = @Name, Telephone = @Telephone,
Email = @Email WHERE PersonID = @PersonID", conn);
// Add parameters to the query
updatePersonCmd.Parameters.AddWithValue("@Name",
txtName.Text.Trim());
updatePersonCmd.Parameters.AddWithValue("@Telephone",
txtPhone.Text.Trim());
updatePersonCmd.Parameters.AddWithValue("@Email",
txtEmail.Text.Trim());
updatePersonCmd.Parameters.AddWithValue("@PersonID",
personID);
updatePersonCmd.ExecuteNonQuery(); // Execute the query

// Update Admin table


SqlCommand updateAdminCmd = new SqlCommand( // Create a new
SqlCommand object to update the Admin table

GCD220190 44
001306081 COMP1551

"UPDATE Admin SET Salary = @Salary, EmploymentType =


@EmploymentType, WorkingHours = @WorkingHours WHERE PersonID = @PersonID",
conn);
// Add parameters to the query
updateAdminCmd.Parameters.AddWithValue("@Salary",
txtSalary.Text.Trim());
updateAdminCmd.Parameters.AddWithValue("@EmploymentType",
cBoxEployment.SelectedItem.ToString());
updateAdminCmd.Parameters.AddWithValue("@WorkingHours",
txtWorkingHours.Text.Trim());
updateAdminCmd.Parameters.AddWithValue("@PersonID",
personID);
updateAdminCmd.ExecuteNonQuery(); // Execute the query

MessageBox.Show("Admin updated successfully", "Success",


MessageBoxButtons.OK, MessageBoxIcon.Information);
adminData(); // Call the adminData method to refresh the
DataGridView

// Raise the event


PersonUpdated?.Invoke(this, EventArgs.Empty);
}
catch (SqlException ex)
{
MessageBox.Show("SQL Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
conn.Close();
}
}
}

private void btnDeleteAdmin_Click(object sender, EventArgs e) // Handle


click event for the Delete button
{
// Check if a row is selected
if (dgvAdmin.SelectedRows.Count == 0) // If no row is selected

GCD220190 45
001306081 COMP1551

{
MessageBox.Show("Please select an admin to delete", "Error
Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}

// Display confirmation box


DialogResult result = MessageBox.Show("Are you sure you want to
delete the selected admin?", "Confirm Deletion", MessageBoxButtons.YesNo,
MessageBoxIcon.Warning);
if (result == DialogResult.No)
{
return;
}
else if (conn.State != ConnectionState.Open)
{
try
{
conn.Open();

int personID = GetSelectedPersonID();

// Delete from Admin table


SqlCommand deleteAdminCmd = new SqlCommand("DELETE FROM
Admin WHERE PersonID = @PersonID", conn);
deleteAdminCmd.Parameters.AddWithValue("@PersonID",
personID);
deleteAdminCmd.ExecuteNonQuery();

// Delete from Person table


SqlCommand deletePersonCmd = new SqlCommand("DELETE FROM
Person WHERE PersonID = @PersonID", conn);
deletePersonCmd.Parameters.AddWithValue("@PersonID",
personID);
deletePersonCmd.ExecuteNonQuery();

MessageBox.Show("Admin deleted successfully", "Success",


MessageBoxButtons.OK, MessageBoxIcon.Information);
adminData();

// Raise the event


PersonDeleted?.Invoke(this, EventArgs.Empty);
}
catch (SqlException ex)

GCD220190 46
001306081 COMP1551

{
MessageBox.Show("SQL Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
conn.Close();
}
}
}

private int GetSelectedPersonID() // Method to get the ID of the


selected admin
{
if (dgvAdmin.SelectedRows.Count > 0) // If a row is selected
{
DataGridViewRow selectedRow = dgvAdmin.SelectedRows[0]; // Get
the selected row
return Convert.ToInt32(selectedRow.Cells[0].Value); // Return
the value of the PersonID cell in the selected row
}
else
{
throw new InvalidOperationException("No admin selected.");
}
}

private void LoadEmploymentTypes() // Method to load the employment


types into the ComboBox
{
// Create a list of strings and add an empty string as the first
item
List<string> employmentTypes = new List<string> { "" };

// Add the enum values to the list


employmentTypes.AddRange(Enum.GetNames(typeof(EmploymentType)));

// Bind the list to the ComboBox


cBoxEployment.DataSource = employmentTypes;

GCD220190 47
001306081 COMP1551

private void dgvAdmin_CellClick(object sender, DataGridViewCellEventArgs


e) // Handle click event for the DataGridView
{
if(e.RowIndex >= 0) // If a row is selected
{
// Get the selected row
DataGridViewRow row = dgvAdmin.Rows[e.RowIndex];
txtName.Text = row.Cells[2].Value.ToString();
txtPhone.Text = row.Cells[3].Value.ToString();
txtEmail.Text = row.Cells[4].Value.ToString();
txtSalary.Text = row.Cells[5].Value.ToString();
cBoxEployment.SelectedItem = row.Cells[6].Value.ToString();
txtWorkingHours.Text = row.Cells[7].Value.ToString();
}
}
}
}

7.2.4. TeacherData.cs

using COMP1551_Coursework.Models;
using COMP1551_Coursework.Models.Enums;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace COMP1551_Coursework.Forms.User_Control
{
public partial class TeacherData : UserControl
{
public event EventHandler PersonAdded; // Declare an event to notify
subscribers when a person is added
public event EventHandler PersonUpdated; // Declare an event to notify
subscribers when a person is updated
public event EventHandler PersonDeleted; // Declare an event to notify

GCD220190 48
001306081 COMP1551

subscribers when a person is deleted

SqlConnection conn = new SqlConnection(@"Data


Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\ADMIN\Documents\comp1551
_coursework.mdf;Integrated Security=True;Connect Timeout=30;Encrypt=False");
public TeacherData()
{
InitializeComponent();
LoadSubjects(); // Load available subjects for the comboboxes
teacherData(); // Populate the DataGridView control with teacher
data on initialization
}

public void teacherData()


{
Teacher teacher = new Teacher(); // Create a new Teacher object

dgvTeachers.AutoGenerateColumns = false; // Configure the


DataGridView to not automatically generate columns
dgvTeachers.Columns.Clear(); // Clear any existing columns

// Define columns manually


DataGridViewTextBoxColumn personIDColumn = new
DataGridViewTextBoxColumn(); // Create a new DataGridViewTextBoxColumn to
display PersonID data
personIDColumn.DataPropertyName = "PersonID"; // Bind the column to
the "PersonID" property of the data source
personIDColumn.HeaderText = "PersonID"; // Set the header text of
the column
dgvTeachers.Columns.Add(personIDColumn); // Add the column to the
DataGridView

DataGridViewTextBoxColumn studentIDColumn = new


DataGridViewTextBoxColumn();
studentIDColumn.DataPropertyName = "TeacherID";
studentIDColumn.HeaderText = "TeacherID";
dgvTeachers.Columns.Add(studentIDColumn);

DataGridViewTextBoxColumn nameColumn = new


DataGridViewTextBoxColumn();
nameColumn.DataPropertyName = "Name";
nameColumn.HeaderText = "Name";
dgvTeachers.Columns.Add(nameColumn);

GCD220190 49
001306081 COMP1551

DataGridViewTextBoxColumn telephoneColumn = new


DataGridViewTextBoxColumn();
telephoneColumn.DataPropertyName = "Telephone";
telephoneColumn.HeaderText = "Telephone";
dgvTeachers.Columns.Add(telephoneColumn);

DataGridViewTextBoxColumn emailColumn = new


DataGridViewTextBoxColumn();
emailColumn.DataPropertyName = "Email";
emailColumn.HeaderText = "Email";
dgvTeachers.Columns.Add(emailColumn);

DataGridViewTextBoxColumn salaryColumn = new


DataGridViewTextBoxColumn();
salaryColumn.DataPropertyName = "Salary";
salaryColumn.HeaderText = "Salary";
dgvTeachers.Columns.Add(salaryColumn);

DataGridViewTextBoxColumn teachingSubject1Column = new


DataGridViewTextBoxColumn();
teachingSubject1Column.DataPropertyName = "TeachingSubject1";
teachingSubject1Column.HeaderText = "Teaching Subject 1";
dgvTeachers.Columns.Add(teachingSubject1Column);

DataGridViewTextBoxColumn teachingSubject2Column = new


DataGridViewTextBoxColumn();
teachingSubject2Column.DataPropertyName = "TeachingSubject2";
teachingSubject2Column.HeaderText = "Teaching Subject 2";
dgvTeachers.Columns.Add(teachingSubject2Column);

// Bind the DataGridView control to the data source


dgvTeachers.DataSource = teacher.teachers();

private void btnAddTeacher_Click(object sender, EventArgs e) // Handle


the click event for the Add Teacher button
{
// Validate the input fields
if (txtName.Text == ""
|| txtPhone.Text == ""
|| txtEmail.Text == ""
|| txtSalary.Text == ""
|| cBoxTS1.Text == ""

GCD220190 50
001306081 COMP1551

|| cBoxTS2.Text == "")
{
MessageBox.Show("Please fill all fields.", "Error Message",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else if (cBoxTS1.Text == cBoxTS2.Text) // Check if the subjects are
the same (preventing duplicates)
{
MessageBox.Show("Error: Subjects cannot be the same.", "Error
Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
LoadSubjects(); // Reload the form to allow the user to correct
the input
}
else
{
if (conn.State != ConnectionState.Open)
{
try
{
conn.Open();

// Insert information to Person table


string personQuery = "INSERT INTO Person (Name,
Telephone, Email, Role) OUTPUT INSERTED.PersonID VALUES (@Name, @Telephone,
@Email, @Role)";
int personID;
using (SqlCommand personCmd = new
SqlCommand(personQuery, conn)) // Create a new SqlCommand object
{
// Add parameters to the query
personCmd.Parameters.AddWithValue("@Name",
txtName.Text.Trim());
personCmd.Parameters.AddWithValue("@Telephone",
txtPhone.Text.Trim());
personCmd.Parameters.AddWithValue("@Email",
txtEmail.Text.Trim());
personCmd.Parameters.AddWithValue("@Role",
Role.Teacher.ToString());

personID = (int)personCmd.ExecuteScalar(); //
Execute the query and get the PersonID of the newly inserted record
}

// Insert information to Teacher table

GCD220190 51
001306081 COMP1551

string teacherQuery = "INSERT INTO Teacher (PersonID,


Salary, TeachingSubject1, TeachingSubject2) VALUES (@PersonID, @Salary,
@TeachingSubject1, @TeachingSubject2)";
using (SqlCommand teacherCmd = new
SqlCommand(teacherQuery, conn)) // Creae a new SqlCommand object
{
// Add parameters to the query
teacherCmd.Parameters.AddWithValue("@PersonID",
personID);
teacherCmd.Parameters.AddWithValue("@Salary",
txtSalary.Text.ToString());

teacherCmd.Parameters.AddWithValue("@TeachingSubject1", cBoxTS1.Text);

teacherCmd.Parameters.AddWithValue("@TeachingSubject2", cBoxTS2.Text);

teacherCmd.ExecuteNonQuery(); // Execute the query

}
// Display a success message
MessageBox.Show("Teacher added successfully.",
"Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
teacherData(); // Reload the DataGridView control

// Raise the event


PersonAdded?.Invoke(this, EventArgs.Empty);
}
catch (SqlException ex)
{
MessageBox.Show("SQL Error: " + ex.Message, "Message
Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
conn.Close();
}
}
}
}

GCD220190 52
001306081 COMP1551

private void btnUpdateTeacher_Click(object sender, EventArgs e) //


Handle the click event for the Update button
{
if (cBoxTS1.Text == cBoxTS2.Text) // Check if the subjects are the
same (preventing duplicates)
{
MessageBox.Show("Error: Subjects cannot be the same", "Error
Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
// Reload the form to allow the user to correct the input
LoadSubjects();
}
else
{
if (conn.State != ConnectionState.Open)
{
try
{
conn.Open();

int personID = GetSelectedPersonID(); // Get the


PersonID of the selected teacher

// Update the Person table


SqlCommand updatePersonCmd = new SqlCommand(
"UPDATE Person SET Name = @Name, Telephone =
@Telephone, Email = @Email WHERE PersonID = @PersonID", conn); // Create a new
SqlCommand object
// Add parameters to the query
updatePersonCmd.Parameters.AddWithValue("@Name",
txtName.Text.Trim());
updatePersonCmd.Parameters.AddWithValue("@Telephone",
txtPhone.Text.Trim());
updatePersonCmd.Parameters.AddWithValue("@Email",
txtEmail.Text.Trim());
updatePersonCmd.Parameters.AddWithValue("@PersonID",
personID);
updatePersonCmd.ExecuteNonQuery();

// Update the Teacher table


SqlCommand updateTeacherCmd = new SqlCommand( // Create
a new SqlCommand object
"UPDATE Teacher SET Salary = @Salary,
TeachingSubject1 = @TeachingSubject1, TeachingSubject2 = @TeachingSubject2 WHERE

GCD220190 53
001306081 COMP1551

PersonID = @PersonID", conn);


// Add parameters to the query
updateTeacherCmd.Parameters.AddWithValue("@Salary",
txtSalary.Text.Trim());

updateTeacherCmd.Parameters.AddWithValue("@TeachingSubject1", cBoxTS1.Text);

updateTeacherCmd.Parameters.AddWithValue("@TeachingSubject2", cBoxTS2.Text);
updateTeacherCmd.Parameters.AddWithValue("@PersonID",
personID);
updateTeacherCmd.ExecuteNonQuery();

MessageBox.Show("Teacher updated successfully.",


"Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
teacherData(); // Reload the DataGridView control

// Raise the event


PersonUpdated?.Invoke(this, EventArgs.Empty);
}
catch (SqlException ex)
{
MessageBox.Show("SQL Error: " + ex.Message, "Message
Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
conn.Close();
}
}
}
}

private void btnDelete_Click(object sender, EventArgs e) // Handle the


click event for the Delete button
{
// Check if a teacher is selected
if (dgvTeachers.SelectedRows.Count == 0)
{
MessageBox.Show("Please select a student to delete", "Error

GCD220190 54
001306081 COMP1551

Message", MessageBoxButtons.OK, MessageBoxIcon.Error);


return;
}

// Display a confirmation dialog


DialogResult result = MessageBox.Show("Are you sure you want to
delete this teacher?", "Confirmation", MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (result == DialogResult.No)
{
return;
}
else if (conn.State != ConnectionState.Open)
{
try
{
conn.Open();

int personID = GetSelectedPersonID(); // Get the PersonID of


the selected teacher

// Delete the teacher from the Teacher table


SqlCommand deleteTeacherCmd = new SqlCommand("DELETE FROM
Teacher WHERE PersonID = @PersonID", conn); // Create a new SqlCommand object
deleteTeacherCmd.Parameters.AddWithValue("@PersonID",
personID); // Add parameters to the query
deleteTeacherCmd.ExecuteNonQuery(); // Execute the query

// Delete the teacher from the Person table


SqlCommand deletePersonCmd = new SqlCommand("DELETE FROM
Person WHERE PersonID = @PersonID", conn); // Create a new SqlCommand object
deletePersonCmd.Parameters.AddWithValue("@PersonID",
personID); // Add parameters to the query
deletePersonCmd.ExecuteNonQuery(); // Execute the query

MessageBox.Show("Teacher deleted successfully.", "Message",


MessageBoxButtons.OK, MessageBoxIcon.Information);
teacherData(); // Reload the DataGridView control

// Raise the event


PersonDeleted?.Invoke(this, EventArgs.Empty);

}
catch (SqlException ex)

GCD220190 55
001306081 COMP1551

{
MessageBox.Show("SQL Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
conn.Close();
}
}
}

private int GetSelectedPersonID() // Get the PersonID of the selected


teacher
{
// Check if a teacher is selected
if (dgvTeachers.SelectedRows.Count > 0)
{
DataGridViewRow selectedRow = dgvTeachers.SelectedRows[0]; //
Get the selected row
return Convert.ToInt32(selectedRow.Cells[0].Value); // Return
the PersonID of the selected teacher
}
else
{
throw new InvalidOperationException("No teacher selected."); //
Throw an exception if no teacher is selected
}
}

private void LoadSubjects() // Load available subjects for the


comboboxes
{
if (conn.State != ConnectionState.Open)
{
try
{
conn.Open();
string query = "SELECT SubjectName FROM Subject"; // Create
a new query to get all subjects

GCD220190 56
001306081 COMP1551

using (SqlCommand cmd = new SqlCommand(query, conn)) //


Create a new SqlCommand object
{
// Execute the query and get the subjects
SqlDataReader reader = cmd.ExecuteReader();
List<string> subjects = new List<string>() { "" }; //
Create a new list to store the subjects and add an empty string as the first
element
while (reader.Read()) // Loop through the results
{
subjects.Add(reader["SubjectName"].ToString()); //
Add the subject to the list
}
reader.Close();

// Bind the subjects to the ComboBox controls


cBoxTS1.DataSource = new List<string>(subjects);
cBoxTS2.DataSource = new List<string>(subjects);
}
}
catch (SqlException ex)
{
MessageBox.Show("SQL Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
conn.Close();
}
}
}

private void dgvTeachers_CellClick(object sender,


DataGridViewCellEventArgs e) // Handle the click event for the DataGridView
control
{
// Check if a row is selected
if(e.RowIndex >= 0)
{

GCD220190 57
001306081 COMP1551

DataGridViewRow row = dgvTeachers.Rows[e.RowIndex]; // Get the


selected row
txtName.Text = row.Cells[2].Value.ToString(); // Populate the
input fields with the data of the selected teacher
txtPhone.Text = row.Cells[3].Value.ToString(); // Populate the
input fields with the data of the selected teacher
txtEmail.Text = row.Cells[4].Value.ToString(); // Populate the
input fields with the data of the selected teacher
txtSalary.Text = row.Cells[5].Value.ToString(); // Populate the
input fields with the data of the selected teacher
cBoxTS1.Text = row.Cells[6].Value.ToString(); // Populate the
input fields with the data of the selected teacher
cBoxTS2.Text = row.Cells[7].Value.ToString(); // Populate the
input fields with the data of the selected teacher
}
}
}
}

7.2.5. StudentData.cs

using COMP1551_Coursework.Models;
using COMP1551_Coursework.Models.Enums;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace COMP1551_Coursework.Forms.User_Control
{
public partial class StudentData : UserControl
{
public event EventHandler PersonAdded; // Declare an event to notify
subscribers when a person is added
public event EventHandler PersonUpdated; // Declare an event to notify
subscribers when a person is updated
public event EventHandler PersonDeleted; // Declare an event to notify
subscribers when a person is deleted

GCD220190 58
001306081 COMP1551

SqlConnection conn = new SqlConnection(@"Data


Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\ADMIN\Documents\comp1551
_coursework.mdf;Integrated Security=True;Connect Timeout=30;Encrypt=False");

public StudentData()
{
InitializeComponent();
LoadSubjects(); // Load subjects into ComboBox controls
studentData(); // Display student data in the DataGridView
}

public void studentData()


{
Student student = new Student(); // Create a new Student object

dgvStudents.AutoGenerateColumns = false; // Configure the


DataGridView to not automatically generate columns
dgvStudents.Columns.Clear(); // Clear any existing columns

// Define columns manually


DataGridViewTextBoxColumn personIDColumn = new
DataGridViewTextBoxColumn(); // Create a new DataGridViewTextBoxColumn to
display PersonID data
personIDColumn.DataPropertyName = "PersonID"; // Bind the column to
the "PersonID" property of the data source
personIDColumn.HeaderText = "PersonID"; // Set the header text of
the column
dgvStudents.Columns.Add(personIDColumn); // Add the column to the
DataGridView

DataGridViewTextBoxColumn studentIDColumn = new


DataGridViewTextBoxColumn();
studentIDColumn.DataPropertyName = "StudentID";
studentIDColumn.HeaderText = "StudentID";
dgvStudents.Columns.Add(studentIDColumn);

DataGridViewTextBoxColumn nameColumn = new


DataGridViewTextBoxColumn();
nameColumn.DataPropertyName = "Name";
nameColumn.HeaderText = "Name";
dgvStudents.Columns.Add(nameColumn);

DataGridViewTextBoxColumn telephoneColumn = new

GCD220190 59
001306081 COMP1551

DataGridViewTextBoxColumn();
telephoneColumn.DataPropertyName = "Telephone";
telephoneColumn.HeaderText = "Telephone";
dgvStudents.Columns.Add(telephoneColumn);

DataGridViewTextBoxColumn emailColumn = new


DataGridViewTextBoxColumn();
emailColumn.DataPropertyName = "Email";
emailColumn.HeaderText = "Email";
dgvStudents.Columns.Add(emailColumn);

DataGridViewTextBoxColumn currentSubject1Column = new


DataGridViewTextBoxColumn();
currentSubject1Column.DataPropertyName = "CurrentSubject1";
currentSubject1Column.HeaderText = "Current Subject 1";
dgvStudents.Columns.Add(currentSubject1Column);

DataGridViewTextBoxColumn currentSubject2Column = new


DataGridViewTextBoxColumn();
currentSubject2Column.DataPropertyName = "CurrentSubject2";
currentSubject2Column.HeaderText = "Current Subject 2";
dgvStudents.Columns.Add(currentSubject2Column);

DataGridViewTextBoxColumn previousSubject1Column = new


DataGridViewTextBoxColumn();
previousSubject1Column.DataPropertyName = "PreviousSubject1";
previousSubject1Column.HeaderText = "Previous Subject 1";
dgvStudents.Columns.Add(previousSubject1Column);

DataGridViewTextBoxColumn previousSubject2Column = new


DataGridViewTextBoxColumn();
previousSubject2Column.DataPropertyName = "PreviousSubject2";
previousSubject2Column.HeaderText = "Previous Subject 2";
dgvStudents.Columns.Add(previousSubject2Column);

// Bind the DataGridView to the data source


dgvStudents.DataSource = student.students();

private void btnAddStudent_Click(object sender, EventArgs e) // Handle


click event for the Add Student button
{
// Validate input fields

GCD220190 60
001306081 COMP1551

if (txtName.Text == ""
|| txtPhone.Text == ""
|| txtEmail.Text == ""
|| cBoxCS1.Text == ""
|| cBoxCS2.Text == ""
|| cBoxPS1.Text == ""
|| cBoxPS2.Text == "")
{
MessageBox.Show("Please fill all fields", "Error Message",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
// Check if any of the subjects are the same (preventing duplicates)
else if (cBoxCS1.Text == cBoxCS2.Text || cBoxCS1.Text ==
cBoxPS1.Text || cBoxCS1.Text == cBoxPS2.Text
|| cBoxCS2.Text == cBoxPS1.Text || cBoxCS2.Text == cBoxPS2.Text
|| cBoxPS1.Text == cBoxPS2.Text)
{
MessageBox.Show("Error: Subjects cannot be the same", "Error
Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
LoadSubjects(); // Reload the form to allow the user to correct
the input
}
else
{
if (conn.State != ConnectionState.Open)
{
try
{
conn.Open();

// Insert into Person table


string personQuery = "INSERT INTO Person (Name,
Telephone, Email, Role) OUTPUT INSERTED.PersonID VALUES (@Name, @Telephone,
@Email, @Role)"; // Use OUTPUT INSERTED to get the PersonID of the newly
inserted row
int personID;
using (SqlCommand personCmd = new
SqlCommand(personQuery, conn)) // Use a SqlCommand object to execute the query
{
// Add parameters to the query
personCmd.Parameters.AddWithValue("@Name",
txtName.Text.Trim());
personCmd.Parameters.AddWithValue("@Telephone",
txtPhone.Text.Trim());

GCD220190 61
001306081 COMP1551

personCmd.Parameters.AddWithValue("@Email",
txtEmail.Text.Trim());
personCmd.Parameters.AddWithValue("@Role",
Role.Student.ToString());
personID = (int)personCmd.ExecuteScalar(); //
Execute the query and get the PersonID of the newly inserted row
}

// Insert into Student table


string studentQuery = "INSERT INTO Student (PersonID,
CurrentSubject1, CurrentSubject2, PreviousSubject1, PreviousSubject2) VALUES
(@PersonID, @CurrentSubject1, @CurrentSubject2, @PreviousSubject1,
@PreviousSubject2)"; // Define the query
// Use a new SqlCommand object to execute the query
using (SqlCommand studentCmd = new
SqlCommand(studentQuery, conn))
{
// Add parameters to the query
studentCmd.Parameters.AddWithValue("@PersonID",
personID);

studentCmd.Parameters.AddWithValue("@CurrentSubject1", cBoxCS1.Text.Trim());

studentCmd.Parameters.AddWithValue("@CurrentSubject2", cBoxCS2.Text.Trim());

studentCmd.Parameters.AddWithValue("@PreviousSubject1", cBoxPS1.Text.Trim());

studentCmd.Parameters.AddWithValue("@PreviousSubject2", cBoxPS2.Text.Trim());
studentCmd.ExecuteNonQuery(); // Execute the query
}

MessageBox.Show("Student added successfully", "Message",


MessageBoxButtons.OK, MessageBoxIcon.Information);
studentData(); // Refresh the DataGridView to display
the new student

// Raise the event


PersonAdded?.Invoke(this, EventArgs.Empty);
}
catch (SqlException ex)
{
MessageBox.Show("SQL Error: " + ex.Message, "Message
Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

GCD220190 62
001306081 COMP1551

catch (Exception ex)


{
MessageBox.Show("Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
conn.Close();
}
}
}
}

private void btnUpdateStudent_Click(object sender, EventArgs e) //


Handle click event for the Update Student button
{
// Validate input fields (preventing duplicated subjects)
if (cBoxCS1.Text == cBoxCS2.Text || cBoxCS1.Text == cBoxPS1.Text ||
cBoxCS1.Text == cBoxPS2.Text
|| cBoxCS2.Text == cBoxPS1.Text || cBoxCS2.Text == cBoxPS2.Text
|| cBoxPS1.Text == cBoxPS2.Text)
{
MessageBox.Show("Error: Subjects cannot be the same", "Error
Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
LoadSubjects(); // Reload the form to allow the user to correct
the input
}
else
{
if (conn.State != ConnectionState.Open)
{
try
{
conn.Open();

int personID = GetSelectedPersonID(); // Get the


PersonID of the selected student

// Update Person table


SqlCommand updatePersonCmd = new SqlCommand(
"UPDATE Person SET Name = @Name, Telephone =
@Telephone, Email = @Email WHERE PersonID = @PersonID", conn); // Define the
query

GCD220190 63
001306081 COMP1551

// Use a new SqlCommand object to execute the query


updatePersonCmd.Parameters.AddWithValue("@Name",
txtName.Text.Trim());
updatePersonCmd.Parameters.AddWithValue("@Telephone",
txtPhone.Text.Trim());
updatePersonCmd.Parameters.AddWithValue("@Email",
txtEmail.Text.Trim());
updatePersonCmd.Parameters.AddWithValue("@PersonID",
personID);
updatePersonCmd.ExecuteNonQuery(); // Execute the query

// Update Student table


SqlCommand updateStudentCmd = new SqlCommand( // Define
the query
"UPDATE Student SET CurrentSubject1 =
@CurrentSubject1, CurrentSubject2 = @CurrentSubject2, PreviousSubject1 =
@PreviousSubject1, PreviousSubject2 = @PreviousSubject2 WHERE PersonID =
@PersonID", conn);
// Use a new SqlCommand object to execute the query

updateStudentCmd.Parameters.AddWithValue("@CurrentSubject1",
cBoxCS1.Text.Trim());

updateStudentCmd.Parameters.AddWithValue("@CurrentSubject2",
cBoxCS2.Text.Trim());

updateStudentCmd.Parameters.AddWithValue("@PreviousSubject1",
cBoxPS1.Text.Trim());

updateStudentCmd.Parameters.AddWithValue("@PreviousSubject2",
cBoxPS2.Text.Trim());
updateStudentCmd.Parameters.AddWithValue("@PersonID",
personID);
updateStudentCmd.ExecuteNonQuery(); // Execute the query

MessageBox.Show("Student updated successfully",


"Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
studentData(); // Refresh the DataGridView to display
the updated student

// Raise the event


PersonUpdated?.Invoke(this, EventArgs.Empty);
}

GCD220190 64
001306081 COMP1551

catch (SqlException ex)


{
MessageBox.Show("SQL Error: " + ex.Message, "Message
Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
conn.Close();
}
}
}
}

private void btnDelete_Click(object sender, EventArgs e) // Handle click


event for the Delete button
{
if (dgvStudents.SelectedRows.Count == 0) // Check if a student is
selected
{
MessageBox.Show("Please select a student to delete", "Error
Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}

// Display confirmation box


DialogResult result = MessageBox.Show("Are you sure you want to
delete the selected student?", "Confirm Deletion", MessageBoxButtons.YesNo,
MessageBoxIcon.Warning);
if (result == DialogResult.No)
{
return;
}
else if (conn.State != ConnectionState.Open)
{
try
{
conn.Open();

// Get the selected student's PersonID

GCD220190 65
001306081 COMP1551

int personID = GetSelectedPersonID();

// Delete from Student table


SqlCommand deleteStudentCmd = new SqlCommand("DELETE FROM
Student WHERE PersonID = @PersonID", conn);
deleteStudentCmd.Parameters.AddWithValue("@PersonID",
personID);
deleteStudentCmd.ExecuteNonQuery();

// Delete from Person table


SqlCommand deletePersonCmd = new SqlCommand("DELETE FROM
Person WHERE PersonID = @PersonID", conn);
deletePersonCmd.Parameters.AddWithValue("@PersonID",
personID);
deletePersonCmd.ExecuteNonQuery();

MessageBox.Show("Student deleted successfully", "Message",


MessageBoxButtons.OK, MessageBoxIcon.Information);
studentData();

// Raise the event


PersonDeleted?.Invoke(this, EventArgs.Empty);
}
catch (SqlException ex)
{
MessageBox.Show("SQL Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
conn.Close();
}
}
}

private int GetSelectedPersonID() // Get the PersonID of the selected


student
{
// Check if a student is selected

GCD220190 66
001306081 COMP1551

if (dgvStudents.SelectedRows.Count > 0)
{
DataGridViewRow selectedRow = dgvStudents.SelectedRows[0]; //
Get the selected row
return Convert.ToInt32(selectedRow.Cells[0].Value); // Get the
PersonID of the selected student
}
else
{
throw new InvalidOperationException("No student selected.");
}
}

private void LoadSubjects() // Load subjects into ComboBox controls


{
if (conn.State != ConnectionState.Open)
{
try
{
conn.Open();
string query = "SELECT SubjectName FROM Subject"; // Define
the query
using (SqlCommand cmd = new SqlCommand(query, conn))
{
SqlDataReader reader = cmd.ExecuteReader();
List<string> subjects = new List<string>() { "" }; //
Create a new list to store subjects and add an empty string as the first element
while (reader.Read()) // Loop through the results
{
subjects.Add(reader["SubjectName"].ToString()); //
Add the subject to the list
}
reader.Close();

// Bind the subjects to the ComboBox controls


cBoxCS1.DataSource = new List<string>(subjects);
cBoxCS2.DataSource = new List<string>(subjects);
cBoxPS1.DataSource = new List<string>(subjects);
cBoxPS2.DataSource = new List<string>(subjects);
}
}
catch (SqlException ex)
{
MessageBox.Show("SQL Error: " + ex.Message, "Message Error",

GCD220190 67
001306081 COMP1551

MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message, "Message Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
conn.Close();
}
}
}

private void dgvStudents_CellClick(object sender,


DataGridViewCellEventArgs e) // Handle click event for the DataGridView
{
// Check if a student is selected
if(e.RowIndex >= 0)
{
DataGridViewRow row = dgvStudents.Rows[e.RowIndex]; // Get the
selected row
txtName.Text = row.Cells[2].Value.ToString(); // Display the
student's data in the input fields
txtPhone.Text = row.Cells[3].Value.ToString(); // Display the
student's data in the input fields
txtEmail.Text = row.Cells[4].Value.ToString(); // Display the
student's data in the input fields
cBoxCS1.Text = row.Cells[5].Value.ToString(); // Display the
student's data in the input fields
cBoxCS2.Text = row.Cells[6].Value.ToString(); // Display the
student's data in the input fields
cBoxPS1.Text = row.Cells[7].Value.ToString(); // Display the
student's data in the input fields
cBoxPS2.Text = row.Cells[8].Value.ToString(); // Display the
student's data in the input fields
}
}
}
}

GCD220190 68
001306081 COMP1551

7.3. Testing Evidence


7.3.1. Test Case 1

7.3.2. Test Case 2

GCD220190 69
001306081 COMP1551

7.3.3. Test Case 3

GCD220190 70
001306081 COMP1551

7.3.4. Test Case 4

GCD220190 71
001306081 COMP1551

7.3.5. Test Case 5

GCD220190 72
001306081 COMP1551

7.3.6. Test Case 6

GCD220190 73
001306081 COMP1551

7.3.7. Test Case 7

GCD220190 74
001306081 COMP1551

7.3.8. Test Case 8

GCD220190 75
001306081 COMP1551

7.3.9. Test Case 9

GCD220190 76
001306081 COMP1551

7.3.10. Test Case 10

GCD220190 77
001306081 COMP1551

7.3.11. Test Case 11

GCD220190 78
001306081 COMP1551

7.3.12. Test Case 12

GCD220190 79
001306081 COMP1551

7.3.13. Test Case 13

GCD220190 80
001306081 COMP1551

7.3.14. Test Case 14

GCD220190 81

You might also like