Imports System.IO
Imports File = System.IO.File
Public Class myAppointment
Private Sub myStaff_Load(sender As Object, e As EventArgs) Handles MyBase.Load
fillGrid(dgv_appointment, fileLoc_Appointment)
' fills the grid when the user loadths form
' StartPosition = FormStartPosition.CenterScreen
' centering of screen occurs in design code
' sets the colours for the textbox using the values from my design
txt_appID.BackColor = gray
txt_staffID.BackColor = gray
txt_cusID.BackColor = gray
txt_cusName.BackColor = gray
txt_staffIDApp.BackColor = gray
txt_staffNameApp.BackColor = gray
DTP_Appointment.BackColor = gray
DTP_booking.BackColor = gray
txt_tOA.BackColor = gray
txt_treatmentID.BackColor = gray
txt_service1.BackColor = gray
txt_service2.BackColor = gray
txt_service3.BackColor = gray
txt_serviceName1.BackColor = gray
txt_serviceName2.BackColor = gray
txt_serviceName3.BackColor = gray
End Sub
Private Sub fillText(ByVal rowIndex As Integer)
txt_appID.Text = dgv_appointment.Rows(rowIndex).Cells(0).Value
txt_staffID.Text = dgv_appointment.Rows(rowIndex).Cells(1).Value
txt_cusID.Text = dgv_appointment.Rows(rowIndex).Cells(2).Value
' taking the value from current row
txt_cusName.Text = Decryption(FindField(fileLoc_Customer, txt_cusID.Text, 1)) + " " + Decryption(FindField(fileLoc_Customer, txt_cusID.Text, 2))
' combines the forename and surname from the customer file for the customer ID
txt_staffIDApp.Text = dgv_appointment.Rows(rowIndex).Cells(3).Value
' taking the value from current row
txt_staffNameApp.Text = Decryption(FindField(fileLoc_Staff, txt_staffIDApp.Text, 1)) + " " + Decryption(FindField(fileLoc_Staff, txt_staffIDApp.Text, 2))
' combines the forename and surname from the Staff file from the staff ID
' error handling for the MinValue if a date wasn't assigned, avoids crashes
If Not dgv_appointment.Rows(rowIndex).Cells(4).Value = Date.MinValue Then
DTP_booking.Value = dgv_appointment.Rows(rowIndex).Cells(4).Value
DTP_Appointment.Value = dgv_appointment.Rows(rowIndex).Cells(5).Value
' taking the value from current row
End If
txt_tOA.Text = dgv_appointment.Rows(rowIndex).Cells(6).Value
txt_treatmentID.Text = dgv_appointment.Rows(rowIndex).Cells(7).Value
' taking the value from current row
txt_treatmentName.Text = FindField(fileLoc_Appointment, txt_treatmentID.Text, 2)
' finds the name of the treatment from the file by taking the ID and searching, avoids memorising the names of the treatments
Dim ServiceUse As Integer = FindField(fileLoc_Appointment, txt_appID.Text, 8)
' Finds the service use from the appointment record, does it this way as it doesn't appear on the table
txt_service1.Text = FindField(FileLoc_ServiceUse, ServiceUse, 2)
txt_service2.Text = FindField(FileLoc_ServiceUse, ServiceUse, 3)
txt_service3.Text = FindField(FileLoc_ServiceUse, ServiceUse, 4)
' Searches the service use file with the found ID to find the appropriate service IDs
txt_serviceName1.Text = FindField(FileLoc_Service, txt_service1.Text, 2)
txt_serviceName2.Text = FindField(FileLoc_Service, txt_service2.Text, 2)
txt_serviceName3.Text = FindField(FileLoc_Service, txt_service3.Text, 2)
' Takes the name from the service file by using the ID found in the above code
End Sub
Private Sub clearText()
txt_appID.Text = ""
txt_staffID.Text = ""
txt_cusID.Text = ""
txt_cusName.Text = ""
txt_staffIDApp.Text = ""
txt_staffNameApp.Text = ""
DTP_booking.Text = ""
DTP_Appointment.Text = ""
txt_tOA.Text = ""
txt_treatmentID.Text = ""
txt_service1.Text = ""
txt_service2.Text = ""
txt_service3.Text = ""
txt_serviceName1.Text = ""
txt_serviceName2.Text = ""
txt_serviceName3.Text = ""
' Subroutine to clear all the text boxes on screen, can be called anywhere in the form
End Sub
'Navigation
Private dgvNavigator As New DataGridViewNavigator()
' Allows the form to have access to the subroutines in the class
Private Sub btn_first_Click(sender As Object, e As EventArgs) Handles btn_first.Click
dgvNavigator.SelectFirst(dgv_appointment)
fillText(dgvNavigator.CurrentIndex) ' Fills boxes with information from currently viewed record
End Sub
Private Sub btn_previous_Click(sender As Object, e As EventArgs) Handles btn_previous.Click
dgvNavigator.SelectPrevious(dgv_appointment)
fillText(dgvNavigator.CurrentIndex) ' Fills boxes with information from currently viewed record
End Sub
Private Sub btn_next_Click(sender As Object, e As EventArgs) Handles btn_next.Click
dgvNavigator.SelectNext(dgv_appointment)
fillText(dgvNavigator.CurrentIndex) ' Fills boxes with information from currently viewed record
End Sub
Private Sub btn_last_Click(sender As Object, e As EventArgs) Handles btn_last.Click
dgvNavigator.SelectLast(dgv_appointment)
fillText(dgvNavigator.CurrentIndex) ' Fills boxes with information from currently viewed record
End Sub
'----------------------------------------------------------------------------------------------'
Private Sub btn_add_Click(sender As Object, e As EventArgs) Handles btn_add.Click
clearText()
Dim newID As Integer = AddRecord(fileLoc_Appointment)
txt_appID.Text = newID
txt_staffID.Text = userID
End Sub
Private Sub btn_save_Click(sender As Object, e As EventArgs) Handles btn_save.Click
' Compiles the data to create a string that is passed onto the SaveRecord subroutine in the module
If Check() = False Then
' Runs check
Return
End If
Dim appointmentID As String = txt_appID.Text
' Services are optional additions to appointments, below creates the ServiceUse which is the way the program keeps referential integrity
Dim service1ID As String = txt_service1.Text
Dim service2ID As String = txt_service2.Text
Dim service3ID As String = txt_service3.Text
Dim serviceUserID As Integer = ServiceUseCreate(appointmentID, service1ID, service2ID, service3ID)
If UniqueCheck(appointmentID, fileLoc_Appointment) Then
' If the appointmentID is unique to the file, it will go ahead with adding the new appointment
Dim newAppointment As String = txt_appID.Text & "," & txt_staffID.Text & "," & txt_cusID.Text & "," & txt_staffIDApp.Text & "," & DTP_booking.Value.Date & "," & DTP_Appointment.Value.Date & "," & txt_tOA.Text & "," & txt_treatmentID.Text & "," & serviceUserID
' Compiles the data into a String
MsgBox(newAppointment)
' Displays the new record to the user in a MsgBox
SaveRecord(fileLoc_Appointment, newAppointment)
' Passes on new Record to SaveRecord subroutine in the module
fillGrid(dgv_appointment, fileLoc_Appointment)
' Refreshes dataGrid to show new record
Else
MsgBox("ID is not unique.")
End If
End Sub
Private Function ServiceUseCreate(ByVal AppointmentID As String, Optional Service1 As String = "-1", Optional Service2 As String = "-1", Optional Service3 As String = "-1")
Dim newID As String = AddRecord(FileLoc_ServiceUse)
'-1 representing a null answer.
Dim serviceValid As Boolean = True
serviceValid = ServiceCheck(serviceValid, Service1, Service2, Service3)
If serviceValid = True Then
' Service valid checks to see if a non null input was made into a service ID. if an attempt of adding a service was made, and it doesn't exist, it wont create the ServiceUse
Dim newServiceUse As String = newID & "," & AppointmentID & "," & Service1 & "," & Service2 & "," & Service3
SaveRecord(FileLoc_ServiceUse, newServiceUse)
Return newID
End If
Return True
End Function
Private Function ServiceCheck(ByRef ServiceValid As Boolean, Optional Service1 As String = "-1", Optional Service2 As String = "-1", Optional Service3 As String = "-1")
' Checks the validity of any Services
If Not (Service1 = "-1" Or Service1 = "") Then
If BinSearch(Service1, FileLoc_Service, 0) = False Then
serviceValid = False
End If
End If
If Not (Service2 = "-1" Or Service2 = "") Then
If BinSearch(Service2, FileLoc_Service, 0) = False Then
serviceValid = False
End If
End If
If Not (Service3 = "-1" Or Service3 = "") Then
If BinSearch(Service3, FileLoc_Service, 0) = False Then
serviceValid = False
End If
End If
Return ServiceValid
End Function
Private Function Check()
' Check is a function that changes on the form and checks each field in the forms given record
' If it can make it to the end of the function without returning a false, it is treated as valid data
If txt_appID.Text = "" Then
' Runs a presence check on the Appointment ID
MsgBox("please enter an appointment ID")
Return False
End If
If Not IntCheck(txt_appID.Text) Then
' Int checks the appointment ID
Return False
End If
Dim staffId As Integer = txt_staffID.Text
If BinSearch(staffId, fileLoc_Staff, 0) = False Then
' Checks that the staff ID exists in the text file
MsgBox("invalid Staff ID")
Return False
End If
Dim staffIdApp As Integer = txt_staffIDApp.Text
If BinSearch(staffIdApp, fileLoc_Staff, 0) = False Then
' Validates the existence of the staff ID appointed
MsgBox("invalid Appointed Staff ID")
Return False
End If
' Below looks to see if there exists a timetable on the date that the appointment is scheduled to be on
Dim index As Integer = 0
' An integer that will be incremented to go through the timetable ID's
Dim timetableTrue As Boolean = False
' Initially set as false, iterative algorithm below will have to prove that there does exist a Timetable to flip this
For Each line As String In fileLoc_timetable
Dim indString As String = CStr(index)
Dim timetableDate As Date = FindFieldButDate(fileLoc_timetable, indString, 1)
' Uses the FindFieldButDate function to return the date of the given timetable
If timetableDate = DTP_Appointment.Value.Date Then
' Compares the timetableDate to the date of the appointment, if they match, the boolean value is set to true
timetableTrue = True
Exit For
Else
index = index + 1
' Increments by 1
End If
Next
If timetableTrue = False Then
Return False
End If
Dim shift1 As Integer = FindField(fileLoc_timetable, index, 2)
Dim shift2 As Integer = FindField(fileLoc_timetable, index, 3)
Dim shift3 As Integer = FindField(fileLoc_timetable, index, 4)
Dim shift4 As Integer = FindField(fileLoc_timetable, index, 5)
Dim shift5 As Integer = FindField(fileLoc_timetable, index, 6)
Dim StaffShift As Integer = 0
' When it is established that there is a timetable on the date, the code below checks each of 5 shifts on the timetable to see if the staff is assigned to one of them
' If the staff member is, the integer staff shift will hold the shift ID that contains the start and finish time of the shift
If txt_staffIDApp.Text = FindField(fileLoc_Shift, shift1, 2) Then
StaffShift = shift1
End If
If txt_staffIDApp.Text = FindField(fileLoc_Shift, shift2, 2) Then
StaffShift = shift2
End If
If txt_staffIDApp.Text = FindField(fileLoc_Shift, shift3, 2) Then
StaffShift = shift3
End If
If txt_staffIDApp.Text = FindField(fileLoc_Shift, shift4, 2) Then
StaffShift = shift4
End If
If txt_staffIDApp.Text = FindField(fileLoc_Shift, shift5, 2) Then
StaffShift = shift5
End If
If StaffShift = 0 Then
' this will happen if the staff ID is not associated with any of the shifts
Return False
End If
'if this point is reached, there is a timetable that is on the day of the appointment, and the staff id appointed is on a shift during that time,
'below is checking that the time of the appointment is within the bounds of the shift
Dim part() As String = txt_tOA.Text.Split(":")
IntCheck(part(0))
IntCheck(part(1))
Dim hour As Integer = CInt(part(0))
Dim minute As Integer = CInt(part(1))
If hour < 0 Or hour > 24 Then
' Format Checking of the time
MsgBox("invalid Hour")
Return False
End If
If minute < 0 Or minute > 60 Then
' Format Checking of the time
MsgBox("invalid minute")
Return False
End If
Dim shiftStart As String = FindField(fileLoc_Shift, StaffShift, 3)
Dim shiftEnd As String = FindField(fileLoc_Shift, StaffShift, 4)
Dim partStart() As String = shiftStart.Split(":")
' Splits the time into two spots in an array, 0 being the hour and 1 being the minutes
Dim partEnd() As String = shiftEnd.Split(":")
If Not (part(0) > partStart(0) AndAlso part(0) < partEnd(0)) Then
' Not logic applied on top of a check if the time is within the bounds of the shift
MsgBox("Time of appointment is outside the shift bounds")
Return False
End If
If part(0) < partStart(0) OrElse (part(0) = partStart(0) AndAlso part(1) < partStart(1)) Then
' Checks to see if the appointment hour is before the start of the shift, or if it the same hour, but the minute is before the shift
Return False
End If
Dim CusId As Integer = txt_cusID.Text
If BinSearch(CusId, fileLoc_Customer, 0) = False Then
' Validates the existence of the customer id
MsgBox("invalid Customer ID")
Return False
End If
Dim treatmentID As Integer = txt_treatmentID.Text
If BinSearch(treatmentID, fileLoc_treatment, 0) = False Then
MsgBox("invalid Treatment ID")
Return False
End If
Dim booking As String = DTP_booking.Value.Date
Dim Appointment As String = DTP_Appointment.Value.Date
Dim BookingParts As String() = booking.Split("/")
Dim AppointmentParts As String() = Appointment.Split("/")
'part 0 is day, 1 is month, 2 is year
If CInt(BookingParts(2)) > CInt(AppointmentParts(2)) Then
MsgBox("Year of booking is later than year of appointment")
Return False
End If
If CInt(BookingParts(2)) < CInt(AppointmentParts(2)) Then
' If the year of the appointment is after the year of the booking, the month and day are irrelevant, hence making checking them unnecessary
GoTo postdate
End If
If CInt(BookingParts(1)) > CInt(AppointmentParts(1)) Then
MsgBox("Month of booking is later than month of appointment")
Return False
End If
If CInt(BookingParts(1)) < CInt(AppointmentParts(1)) Then
' If the month of the appointment is after the month of booking, then checking the day is irrelevant
GoTo postdate
End If
If CInt(BookingParts(0)) > CInt(AppointmentParts(0)) Then
MsgBox("Day of booking is later than day of appointment")
Return False
End If
If txt_tOA.Text.Length > 5 Then
MsgBox("Invalid time of appointment")
Return False
End If
postdate: ' Is reached if the year is greater or the month is greater
' The Idea is that if the year or month is greater, the date is irrelevent.
Return True
End Function
Private Sub btn_edit_Click(sender As Object, e As EventArgs) Handles btn_edit.Click
If Check() = False Then
' Checks the new information
Return
End If
Dim ID As Integer = txt_appID.Text
Dim ServiceUse As Integer = FindField(fileLoc_Appointment, txt_appID.Text, 8)
Dim newValues As String = txt_appID.Text & "," & txt_staffID.Text & "," & txt_cusID.Text & "," & txt_staffIDApp.Text & "," & DTP_booking.Value.Date & "," & DTP_Appointment.Value.Date & "," & txt_tOA.Text & "," & txt_treatmentID.Text & "," & ServiceUse
' Compiles the TextBox inputs as a string called newValues, that is passed onto the EditRecord along with the primary key ID that is used to find the record that is being edited
EditRecord(ID, newValues, fileLoc_Appointment)
fillGrid(dgv_appointment, fileLoc_Appointment)
' Grid is refreshed to show new changed
Dim service1 As String = txt_service1.Text
Dim service2 As String = txt_service2.Text
Dim service3 As String = txt_service3.Text
Dim IDString As String = CStr(ID)
' Converts the ID of the appoint to a string to be treated as a string in the editing of a record
Dim serviceValid As Boolean = True
serviceValid = ServiceCheck(serviceValid, service1, service2, service3)
' Checks the validity of any services added to the appointment
If serviceValid = True Then
' Edits the ServiceUse to reflect and additions and removals of services to the file
Dim newServiceUse As String = ServiceUse & "," & IDString & "," & service1 & "," & service2 & "," & service3
EditRecord(ServiceUse, newServiceUse, FileLoc_ServiceUse)
End If
End Sub
Private Sub btn_delete_Click(sender As Object, e As EventArgs) Handles btn_delete.Click
If txt_appID.Text = "" Then
' Avoids a crash if a blank ID is input
Return
End If
Dim appID As Integer = txt_appID.Text
' Gives an integer value for the record that the user is trying to delete
DeleteRecord(dgv_appointment, fileLoc_Appointment, appID)
fillGrid(dgv_appointment, fileLoc_Appointment)
' Refreshes grid
End Sub
Private Sub btn_menu_Click(sender As Object, e As EventArgs) Handles btn_menu.Click
' Takes user back to main menu
Me.Visible = False
myMenu.Visible = True
End Sub
'' Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'' Dim Customername As String = InputBox("please enter the customer name to search for appointments under that name")
'gets the name that is being searched
'' Dim customerIDs As List(Of String) = LikeSearch(Customername, fileLoc_Customer, 1)
'Searches for the name, if it matches (LIKE Logic) then it will store it in the string
''Dim AppointmentIDs As List(Of String) = LikeSearch2(customerIDs, fileLoc_Appointment, 2)
'' Console.WriteLine(AppointmentIDs)
'' Console.WriteLine(customerIDs)
'' ShowOnGrid(AppointmentIDs, dgv_appointment)
'' End Sub
''Public Function LikeSearch(Field As Object, fileloc As String, part As Int16)
'' Dim sr As New StreamReader(fileloc)
'sets up a variable to read the wanted file
'' Dim lines As String() = File.ReadAllLines(fileloc)
'stores all the lines in the file
'' Dim searchedIDs As New List(Of String)
'creates a new list the stores all the IDs
''For Each line As String In lines
'' Dim parts As String() = line.Split(","c)
'splits each record by the commas
''If Field Like parts(part) Then
'' searchedIDs.Add(parts(0))
'adds the ID to the list
' ' End If
' ' Next
'' sr.Close()
'' Return searchedIDs
'' End Function
'
'' Public Sub ShowOnGrid(Ids As Object, dgv As DataGridView)
' ' For Each row As DataGridViewRow In dgv.Rows
''If Not row.IsNewRow Then
''Dim ID As String = row.Cells(0).Value.ToString()
'splits each record by the commas
''If Ids.contains(ID) Then
'' row.Visible = True
'adds the ID to the list
''Else
' ' row.Visible = False
' 'End If
''End If
' 'Next
''End Sub
Private Sub Button6_Click(sender As Object, e As EventArgs)
'Brings up the help tab
myHelp.Visible = True
End Sub
Private Sub txt_cusID_TextChanged(sender As Object, e As EventArgs) Handles txt_cusID.TextChanged
' When an ID is put in the appointed customer, the name is automatically placed
txt_cusName.Text = Decryption(FindField(fileLoc_Customer, txt_cusID.Text, 1)) + " " + Decryption(FindField(fileLoc_Customer, txt_cusID.Text, 2))
End Sub
Private Sub txt_staffIDApp_TextChanged(sender As Object, e As EventArgs) Handles txt_staffIDApp.TextChanged
' When an ID is put in the appointed staff, the name is automatically placed
txt_staffNameApp.Text = Decryption(FindField(fileLoc_Staff, txt_staffIDApp.Text, 1)) + " " + Decryption(FindField(fileLoc_Staff, txt_staffIDApp.Text, 2))
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles btn_AppIDAsc.Click
' Sorts appointments by ID ascending
AscSort(fileLoc_Appointment, 0)
fillGrid(dgv_appointment, fileLoc_Appointment)
End Sub
Private Sub btn_appIDDesc_Click(sender As Object, e As EventArgs) Handles btn_appIDDesc.Click
' Sorts appointments by ID Descending
DescSort(fileLoc_Appointment, 0)
fillGrid(dgv_appointment, fileLoc_Appointment)
End Sub
End Class