@@ -4,6 +4,8 @@ const generateId = require('../utils/id-generator');
44const { faker } = require ( '@faker-js/faker' ) ;
55const weighted = require ( 'weighted' ) ;
66const dayjs = require ( 'dayjs' ) ;
7+ const config = require ( '../../config' ) ;
8+
79
810const NOT_SCREENED_REASONS = [
911 "Recent mammogram at different facility" ,
@@ -14,7 +16,57 @@ const NOT_SCREENED_REASONS = [
1416 "Recent breast surgery"
1517] ;
1618
19+ const determineEventStatus = ( slotDateTime , currentDateTime , attendanceWeights ) => {
20+ slotDateTime = dayjs ( slotDateTime ) ;
21+
22+ const simulatedTime = dayjs ( currentDateTime ) ;
23+ const slotDate = slotDateTime . startOf ( 'day' ) ;
24+ const currentDate = simulatedTime . startOf ( 'day' ) ;
25+
26+ // For future dates or future slots today, always return scheduled
27+ if ( slotDateTime . isAfter ( simulatedTime ) ) {
28+ return 'scheduled' ;
29+ }
30+
31+ if ( slotDate . isBefore ( currentDate ) ) {
32+ const finalStatuses = [ 'attended' , 'did_not_attend' , 'attended_not_screened' ] ;
33+ return weighted . select ( finalStatuses , attendanceWeights ) ;
34+ }
35+
36+ // For past slots, generate a status based on how long ago the slot was
37+ const minutesPassed = simulatedTime . diff ( slotDateTime , 'minute' ) ;
38+
39+ // Define probability weights for different statuses based on time passed
40+ if ( minutesPassed <= 60 ) {
41+ // Within 30 mins of appointment
42+ return weighted . select ( {
43+ 'checked_in' : 0.6 ,
44+ 'attended' : 0.1 ,
45+ 'attended_not_screened' : 0.1 ,
46+ 'scheduled' : 0.2 ,
47+ } ) ;
48+ } else {
49+ // More than 30 mins after appointment
50+ return weighted . select ( {
51+ 'attended' : 0.6 ,
52+ 'attended_not_screened' : 0.1 ,
53+ 'scheduled' : 0.2 ,
54+ } ) ;
55+ }
56+ } ;
57+
1758const generateEvent = ( { slot, participant, clinic, outcomeWeights } ) => {
59+
60+ // Get simulated current time
61+ const [ hours , minutes ] = config . clinics . simulatedTime . split ( ':' ) ;
62+ const currentDateTime = dayjs ( ) . hour ( parseInt ( hours ) ) . minute ( parseInt ( minutes ) ) ;
63+
64+ // Check if the event is from yesterday or before
65+ const eventDate = dayjs ( slot . dateTime ) . startOf ( 'day' ) ;
66+ const today = dayjs ( currentDateTime ) . startOf ( 'day' ) ;
67+ const isPast = dayjs ( slot . dateTime ) . isBefore ( currentDateTime ) ;
68+ const isTodayBeforeCurrentTime = eventDate . isBefore ( currentDateTime )
69+
1870 // If it's an assessment clinic, override the outcome weights to reflect higher probability of findings
1971 const eventWeights = clinic . serviceType === 'assessment' ?
2072 {
@@ -28,11 +80,6 @@ const generateEvent = ({ slot, participant, clinic, outcomeWeights }) => {
2880 [ 0.9 , 0.08 , 0.02 ] : // [attended, dna, attended_not_screened]
2981 [ 0.65 , 0.25 , 0.1 ] ; // Original weights for screening
3082
31- // Check if the event is from yesterday or before
32- const eventDate = dayjs ( slot . dateTime ) . startOf ( 'day' ) ;
33- const today = dayjs ( ) . startOf ( 'day' ) ;
34- const isPast = eventDate . isBefore ( today ) ;
35-
3683 // All future events and today's events start as scheduled
3784 if ( ! isPast ) {
3885 return {
@@ -55,11 +102,10 @@ const generateEvent = ({ slot, participant, clinic, outcomeWeights }) => {
55102 } ;
56103 }
57104
58- // For past events, generate final status with clinic-appropriate weights
59- const finalStatuses = [ 'attended' , 'did_not_attend' , 'attended_not_screened' ] ;
60- const status = weighted . select ( finalStatuses , attendanceWeights ) ;
105+ // For past events, generate final status with clinic-appropriate weights
106+ const status = determineEventStatus ( slot . dateTime , currentDateTime , attendanceWeights ) ;
61107
62- const event = {
108+ const event = {
63109 id : generateId ( ) ,
64110 participantId : participant . id ,
65111 clinicId : clinic . id ,
@@ -75,7 +121,7 @@ const generateEvent = ({ slot, participant, clinic, outcomeWeights }) => {
75121 faker . helpers . arrayElement ( NOT_SCREENED_REASONS ) : null
76122 } ,
77123 statusHistory : generateStatusHistory ( status , slot . dateTime )
78- } ;
124+ } ;
79125
80126 // Add outcome for completed events where participant attended
81127 if ( status === 'attended' ) {
@@ -108,13 +154,13 @@ const generateStatusHistory = (finalStatus, dateTime) => {
108154 if ( finalStatus === 'attended' ) {
109155 history . push (
110156 {
111- status : 'pre_screening ' ,
157+ status : 'checked_in ' ,
112158 timestamp : new Date ( baseDate . getTime ( ) - ( 10 * 60 * 1000 ) ) . toISOString ( ) // 10 mins before
113159 } ,
114- {
115- status : 'in_progress' ,
116- timestamp : new Date ( baseDate ) . toISOString ( )
117- } ,
160+ // {
161+ // status: 'in_progress',
162+ // timestamp: new Date(baseDate).toISOString()
163+ // },
118164 {
119165 status : finalStatus ,
120166 timestamp : new Date ( baseDate . getTime ( ) + ( 15 * 60 * 1000 ) ) . toISOString ( ) // 15 mins after
0 commit comments