diff --git a/src/GenerateSampleData.jl b/src/GenerateSampleData.jl new file mode 100644 index 0000000..be6d417 --- /dev/null +++ b/src/GenerateSampleData.jl @@ -0,0 +1,85 @@ +using XLSX +using DataFrames +using Random + + +function generateTreatmentplan(row::DataFrameRow,bestord::Date,columns) + treatmentplan = [] + for col in columns + if !ismissing(row[col[1]]) + + if row[col[1]] == 1 + push!(treatmentplan,Hospitalplanning.UnplannedVisit("test",bestord,col[2])) + elseif rand() < row[col[1]] + push!(treatmentplan,Hospitalplanning.UnplannedVisit("test",bestord,col[2])) + end + end + end + treatmentplan +end + +function readPatientTable(path,sheet,columns,mastercalendar) + patientOverview = DataFrame(XLSX.readtable(path,sheet)...) + patients = [] + for row in eachrow(patientOverview) + if row.Kategori === missing + continue + end + for i = 1:40:Int(row.Antal) #TODO:remove 40 + bestord = rand(mastercalendar) + treatmentplan = generateTreatmentplan(row,bestord,columns) + push!(patients,Patient(string(row.Kategori, "_" , i),0,row.Diagnoser1,treatmentplan )) + end + end + patients +end + +function readWorkPattern(path::String,sheet::String,resources=[]) + columns = Dict{String,Int}("Monday"=>1,"Tuesday"=> 2, "Wednesday" => 3, "Thursday" => 4, "Friday"=> 5) + wp_df = DataFrame(XLSX.readtable(path,sheet)...) + for resource_df in groupby(wp_df,:Resource,skipmissing = true) + cur_resourceid = string(resource_df[1,:Type],"_",resource_df[1,:Resource]) + cur_resourcelocation = findfirst(x -> x.id == cur_resourceid, resources) + if isnothing(cur_resourcelocation) + push!(resources,Resource(resource_df[1,:Type],resource_df[1,:Resource])) + cur_resourcelocation = length(resources) + end + evencalendar = Calendar() + oddcalendar = Calendar() + for day in columns + evenday = Workday(day[2],Even) + oddday = Workday(day[2],Odd) + if ismissing(resource_df[1,Symbol(string(day[1],"_start"))]) continue end; + for row in eachrow(resource_df) + if ismissing(row[Symbol(string(day[1],"_start"))]) ||row[Symbol(string(day[1],"_start"))]=="PAUSE" + continue + end + addTimeslot(evenday,row[Symbol(string(day[1],"_start"))],row[Symbol(string(day[1],"_end"))]) + if row.Weeks in ("All","Even") + end + if row.Weeks in ("All","Odd") + addTimeslot(oddday,row[Symbol(string(day[1],"_start"))],row[Symbol(string(day[1],"_end"))]) + end + end + addWorkday(evencalendar,evenday) + addWorkday(oddcalendar,oddday) + end + addWorkPattern(resources[cur_resourcelocation],oddcalendar,evencalendar) + + + end + resources +end + +function generateCalendarFromPattern(resources::Array{Resource},masterCalendar::MasterCalendar) + for cur_resource in resources + for day in masterCalendar + if + filter(x ->x ,cur_resource.workpattern) +end +end +end + +function generateRandomCalendar(masterCalendar::MasterCalendar) + +end diff --git a/src/Misc.jl b/src/Misc.jl new file mode 100644 index 0000000..d4b93ee --- /dev/null +++ b/src/Misc.jl @@ -0,0 +1,66 @@ +using Dates + +struct MasterCalendar + workdays::Array{Date} + + MasterCalendar(startDate::Date,enddate::Date) = filter(date -> dayofweek(date)<=5, startDate:Day(1):enddate) +end + + +struct Timeslot + startTime::Time + endTime::Time + + Timeslot(startTime::DateTime,endTime::DateTime)= new(Time(startTime),Time(startTime)) + Timeslot(startTime::Time,endTime::Time)= new(startTime,endTime) + +end +@enum WEEK Odd = 1 Even = 2 +struct Workday + date::DateTime + timeslots::Array{Timeslot} + + weekday::Int + weektype::WEEK + + Workday() = new(Date(0),[]) + Workday(weekday::Int,weektype::WEEK) = new(Date(0),[],weekday,weektype) + Workday(date::DateTime,timeslots::Array{Timeslot},weekday::WEEK,weektype::Int) = new(date,timeslots,weekday,weektype) +end +function addTimeslot(workday::Workday,startTime::Time,endTime::Time) + push!(workday.timeslots,Timeslot(startTime,endTime)) +end + + +function addTimeslot(workday::Workday,startTime::String,endTime::String) + push!(workday.timeslots,Timeslot(Dates.Time(startTime),Dates.Time(endTime))) +end + + +abstract type AbstractCalendar end + + +struct Calendar <: AbstractCalendar + workdays::Array{Workday} + + Calendar() = new([]) +end +function Base.:(+)(cal1::AbstractCalendar, cal2::AbstractCalendar) + newcal = vcat(cal1.workdays,cal2,workdays) + sort!(newcal, by ) + return +end + + +function addWorkday(calendar::Calendar,workday::Workday) + push!(calendar.workdays,workday) + sort!(calendar.workdays,by = x ->(x.date,x.weekday)) +end + +struct WorkPattern + oddcalendar::Calendar + evencalendar::Calendar + + WorkPattern() = new([],[]) + WorkPattern(oddcalendar::Calendar,evencalendar::Calendar) = new(oddcalendar,evencalendar) +end diff --git a/src/Patient.jl b/src/Patient.jl new file mode 100644 index 0000000..d63d8b6 --- /dev/null +++ b/src/Patient.jl @@ -0,0 +1,15 @@ +struct Patient + id::String + age::Int + diagnosis::String + treatmentplan::Array{Any} + + Patient(id::String,age::Int,diagnosis::String,treatmentplan::Array{Any}) = new(id,age,diagnosis,treatmentplan) + Patient(id::String,age::Int,diagnosis::String) = new(id,age,diagnosis,[]) + Patient(id::Int) = patient(string(id),100,"") + Patient(id::String) = Patient(id,100,"") +end + +function Base.:(==)(p1::Patient, p2::Patient) + return p1.id == p2.id +end diff --git a/src/Resource.jl b/src/Resource.jl new file mode 100644 index 0000000..9a81b2f --- /dev/null +++ b/src/Resource.jl @@ -0,0 +1,42 @@ +using Dates + +abstract type AbstractResource end + + +function Base.:(==)(r1::AbstractResource, r2::AbstractResource) + return r1.id == r2.id +end + +function Base.:(==)(r1::AbstractResource, r2::String) + return r1.id == r2 +end + +function Base.:(==)(r1::String, r2::AbstractResource) + return r1 == r2.id +end + +struct Offperiod + id::String + starttime::DateTime + endtime::DateTime + + Offperiod(id,starttime,endtime) = new(id,starttime,endtime) +end + +mutable struct Resource <: AbstractResource + id::String + type::String + name::String + + workpattern::Calendar + + calendar::Calendar + offperiods::Array{Offperiod} + + Resource(type::String,name::String) = new(string(type, "_" , name),type,name) +end + +function addWorkPattern(resource::Resource,oddcalendar::Calendar,evencalendar::Calendar) + resource.workpattern = WorkPattern(oddcalendar,evencalendar) + +end diff --git a/src/Visit.jl b/src/Visit.jl new file mode 100644 index 0000000..93c315f --- /dev/null +++ b/src/Visit.jl @@ -0,0 +1,10 @@ +abstract type AbstractVisit end + +mutable struct UnplannedVisit <: AbstractVisit + id::String + bestord::Date + requiredresources::String + patient::String + + UnplannedVisit(id::String,bestord::Date,requiredresources::String) = new(id,bestord,requiredresources) +end diff --git a/test/current.jl b/test/current.jl new file mode 100644 index 0000000..006b56e --- /dev/null +++ b/test/current.jl @@ -0,0 +1,37 @@ +using Revise +using Dates +using Hospitalplanning +using Debugg +HP = Hospitalplanning + + + +path = "C:/Users/hebb/OneDrive - Danmarks Tekniske Universitet/Project/RH/Data/Sample data/PatientOverview.xlsx" +sheet = "Sheet1" +startdate = Date("2019-01-01") +enddate = Date("2019-12-31") +mastercalendar = HP.MasterCalendar(startdate,enddate) +columns = [(:Visits,"Consultation"),(:Telefon,"Telephone"),(:TTE,"TTE"),(:AEKG,"EKG"),(:MR,"MR"),(:Holter,"Holter")] +HP.readPatientTable(path,sheet,columns,mastercalendar) + +path_resourceOverview = "C:/Users/hebb/OneDrive - Danmarks Tekniske Universitet/Project/RH/Data/Sample data/GUCHamb_Timeslots.xlsx" +sheet_resourceOverview = "GUCH AMB" + +HP.readWorkPattern(path_resourceOverview,sheet_resourceOverview) +using PkgTemplates +t = Template( + user="HBreddam", + license="MIT", + authors=["Henrik Bøgedal Breddam"], + julia_version=v"1.1", + plugins=[ + TravisCI(), + Codecov(), + Coveralls(), + AppVeyor(), + GitHubPages(), + CirrusCI(), + ] + ) + +generate("Hospitalplanning",t) diff --git a/test/runtest.jl b/test/runtest.jl new file mode 100644 index 0000000..e69de29