# # # build_calendar_html() # # include "templates.util.date_time.date_time"; include "templates.statistics.calendar.get_calendar_info"; subroutine(build_calendar_html( string profile_name, node report_job), ( node db_state = report_job . ".report_state.database"; string earliest_log_date = @db_state{"earliest_log_date"}; string latest_log_date = @db_state{"latest_log_date"}; int first_weekday = @report_job{"first_weekday"}; int marked_weekday = @report_job{"marked_weekday"}; # Fix older profiles where first_weekday or marked_weekday contains a 0 value. # The 0 value must be converted to 1 if (first_weekday == 0) then (first_weekday = 1); if (marked_weekday == 0) then (marked_weekday = 1); # # Note, weekdays are counted from 1-7! # 1 = Sunday # 2 = Monday # .. # 7 = Saturday # debug_message("\n\n#### build_calendar_html() START \n\n"); debug_message("#### earliest_log_date: " . earliest_log_date . "\n"); debug_message("#### latest_log_date: " . latest_log_date . "\n"); debug_message("#### first_weekday: " . first_weekday . "\n"); debug_message("#### marked_weekday: " . marked_weekday . "\n"); # # # Get calendar_info # # node calendar_info = get_calendar_info(profile_name, earliest_log_date, latest_log_date); int earliest_date_in_epoc = date_time_to_epoc(earliest_log_date . " 12:00:00"); int latest_date_in_epoc = date_time_to_epoc(latest_log_date . " 12:00:00"); volatile.temp_week_count = 0; # # # get_weekdays_info() # # # Returns a node where the node names present the ordered weekdays (as in calendar). # An "offset" subnode presents the offset/shift value of the first of the month which is used # to position the first day of the month. # # A "seconds_relative_to_start_day_in_week" subnode keeps the seconds relative to the start # day of a week. It is used to calculate the start day of a week. # # A "seconds_relative_to_end_day_in_week" subnode keeps the seconds relative to the end # day of a week. It is used to calculate the end day of a week. subroutine(get_weekdays_info(int first_weekday), ( delete_node("v.weekdays_info"); int weekday_count = first_weekday; int j = 6; for (int i = 0; i < 7; i++) ( "v.weekdays_info." . weekday_count . ".offset" = i; "v.weekdays_info." . weekday_count . ".seconds_relative_to_start_day_in_week" = 24 * 60 * 60 * i; "v.weekdays_info." . weekday_count . ".seconds_relative_to_end_day_in_week" = 24 * 60 * 60 * j; weekday_count++; j--; if (weekday_count > 7) then ( # start over with 1 weekday_count = 1; ); ); debug_message("\n\n" . node_as_string("v.weekdays_info") . "\n"); "v.weekdays_info"; )); subroutine(get_week_id( node weekdays_info, int earliest_date_in_epoc, int latest_date_in_epoc, string year, string month_number, string month_in_salang_format, int day), ( # debug_message("\n\n#### get_week_id() START \n"); # This subroutine calculates the start date and end date of a week. # The given day in the argument can be any day in the week. # Note that the first letter in week ID's is followed by a number. The number avoids duplicate id's # because the last week id in i.e. Jan could be the same id as the first week in Feb! # Get the week_count int week_count = volatile.temp_week_count; volatile.temp_week_count = week_count + 1; # Get the weekday int weekday = get_weekday(year, month_number, day); string day_in_salang_format = if (day > 9) then (day) else ("0" . day); string date_time = day_in_salang_format . "/" . month_in_salang_format . "/" . year . " 12:00:00"; int day_in_epoc = date_time_to_epoc(date_time); int start_day_in_epoc = day_in_epoc - @(weekdays_info . "." . weekday . ".seconds_relative_to_start_day_in_week"); int end_day_in_epoc = day_in_epoc + @(weekdays_info . "." . weekday . ".seconds_relative_to_end_day_in_week"); if (start_day_in_epoc < earliest_date_in_epoc) then ( start_day_in_epoc = earliest_date_in_epoc; ); if (end_day_in_epoc > latest_date_in_epoc) then ( end_day_in_epoc = latest_date_in_epoc; ); string start_day = epoc_to_date_time(start_day_in_epoc); string end_day = epoc_to_date_time(end_day_in_epoc); # debug_message("#### start_day: $start_day \n"); # debug_message("#### end_day: $end_day \n"); # Note, month in week_id is in javascript format (0-11) string week_id = "w" . week_count . ":" . get_year(start_day) . ":" . (get_month_as_number(start_day) - 1) . ":" . get_day(start_day) . ":"; week_id .= get_year(end_day) . ":" . (get_month_as_number(end_day) - 1) . ":" . get_day(end_day); # debug_message("#### weekday: $weekday \n"); # debug_message("#### week_id: $week_id \n"); week_id; )); subroutine(build_days_header_row( int first_weekday, int marked_weekday), ( int weekday_label_count = first_weekday; string weekday_label; string span_class_name; '\n'; for (int i = 1; i < 8; i++) ( weekday_label = @("lang_stats.weekdays_short." . weekday_label_count); span_class_name = "c-weekday-label"; if (weekday_label_count != marked_weekday) then ( ''; ) else ( ''; ); weekday_label; '\n'; weekday_label_count++; if (weekday_label_count > 7) then ( weekday_label_count = 1; ); ); ' \n'; '\n'; )); subroutine(build_day_rows( string year, int month_number, string month_in_Salang_format, node weekdays_info, int weekday_of_first_of_month, int days_in_month, node missing_log_data_days_node, int earliest_date_in_epoc, int latest_date_in_epoc), ( int weekday_offset = @(weekdays_info . "." . weekday_of_first_of_month . ".offset"); int day_count = 1 - weekday_offset; bool is_missing_log_data_day; bool row_contains_log_data_day; bool row_contains_day; string week_label = @("lang_stats.calendar.week_label"); string day_id; string week_id; int last_day_set_in_row; # Note, we always build six rows so that all months tables have the same height # # Add the six day rows # for (int i = 0; i < 6; i++) ( ''; row_contains_log_data_day = false; row_contains_day = false; # # Add the seven day cells per row # for (int j = 0; j < 7; j++) ( ''; if (day_count > 0 and day_count <= days_in_month) then ( is_missing_log_data_day = missing_log_data_days_node?{day_count}; if (!is_missing_log_data_day) then ( day_id = "d:" . year . ":" . (month_number - 1) . ":" . day_count; '' . day_count . ''; row_contains_log_data_day = true; last_day_set_in_row = day_count; # used to get the week range ) else ( '' . day_count . ''; row_contains_day = true; ); ) else ( # add empty cell ' '; ); '\n'; day_count++; ); # # Add the week cell # ''; if (row_contains_log_data_day) then ( week_id = get_week_id(weekdays_info, earliest_date_in_epoc, latest_date_in_epoc, year, month_number, month_in_Salang_format, last_day_set_in_row); '' . week_label . ''; ) else if (row_contains_day) then ( '' . week_label . ''; ) else ( ' '; ); '\n'; '\n'; ); )); node year_node; node month_node; string year; string year_id; int number_of_years = num_subnodes(calendar_info); string month_number; string month_in_Salang_format; string month_label; string month_id; bool month_has_log_data; string day; int days_in_month; int weekday_of_first_of_month; node missing_log_data_days_node; node weekdays_info = get_weekdays_info(first_weekday); '
'; foreach year_node calendar_info ( year = node_name(year_node); year_id = "y:" . year; # Note, we don't show the year link if there is only one year! if (number_of_years > 1) then ( '
' . year . '
\n'; ); foreach month_node year_node ( month_number = @month_node{"month"}; month_in_Salang_format = get_month_as_string(month_number); # i.e. Jan, Feb, ... days_in_month = @month_node{"days_in_month"}; weekday_of_first_of_month = @month_node{"weekday_of_first_of_month"}; missing_log_data_days_node = month_node{"missing_log_data_days"}; month_has_log_data = @month_node{"month_has_log_data"}; month_label = @("lang_stats.months." . month_number); month_id = "m:" . year . ":" . (month_number - 1); # month in javascript format (0-11) '\n'; '\n'; '\n'; '\n'; '\n'; '\n'; '\n'; '
\n'; '\n'; '\n'; if (month_has_log_data) then ( '\n'; ) else ( '\n'; ); '\n'; '\n'; '
' . month_label . '' . month_label . '' . year . '
\n'; '
\n'; '
\n'; '\n'; # Don't remove empty table cells! build_days_header_row(first_weekday, marked_weekday); build_day_rows( year, month_number, month_in_Salang_format, weekdays_info, weekday_of_first_of_month, days_in_month, missing_log_data_days_node, earliest_date_in_epoc, latest_date_in_epoc ); '
\n'; '
\n'; '
\n'; ); '
 
'; ); '
\n'; # calendar-body '\n'; # calendar ));