/** * Show calendar day * * @param void * @return null */ function day() { if ($this->request->get('year') && $this->request->get('month') && $this->request->get('day')) { $day = new DateValue($this->request->get('year') . '-' . $this->request->get('month') . '-' . $this->request->get('day')); } else { $day = DateValue::now(); } // if $this->wireframe->addBreadCrumb($day->getYear() . ' / ' . $day->getMonth(), Calendar::getDashboardMonthUrl($day->getYear(), $day->getMonth())); $objects = ProjectObjects::groupByProject(Calendar::getActiveProjectsDayData($this->logged_user, $day)); $this->smarty->assign(array('day' => $day, 'groupped_objects' => $objects)); }
/** * Show events for a given day * * @param void * @return null */ function day() { if ($this->request->get('year') && $this->request->get('month') && $this->request->get('day')) { $day = new DateValue($this->request->get('year') . '-' . $this->request->get('month') . '-' . $this->request->get('day')); } else { $day = DateValue::now(); } // if $this->wireframe->addBreadCrumb($day->getYear() . ' / ' . $day->getMonth(), Calendar::getProjectMonthUrl($this->active_project, $day->getYear(), $day->getMonth())); $objects = Calendar::getProjectDayData($this->logged_user, $this->active_project, $day); $this->smarty->assign(array('day' => $day, 'objects' => $objects)); }
/** * Reschedule selected milestone * * @param void * @return null */ function reschedule() { if ($this->active_milestone->isNew()) { $this->httpError(HTTP_ERR_NOT_FOUND); } // if if (!$this->active_milestone->canEdit($this->logged_user)) { $this->httpError($this->logged_user); } // if $milestone_data = $this->request->post('milestone'); if (!is_array($milestone_data)) { $milestone_data = array('start_on' => $this->active_milestone->getStartOn(), 'due_on' => $this->active_milestone->getDueOn(), 'reschedule_milstone_objects' => false); } // if $this->smarty->assign('milestone_data', $milestone_data); if ($this->request->isSubmitted()) { db_begin_work(); $old_due_on = new DateValue($this->active_milestone->getDueOn()); $new_start_on = new DateValue(array_var($milestone_data, 'start_on')); $new_due_on = new DateValue(array_var($milestone_data, 'due_on')); $reschedule_tasks = (bool) array_var($milestone_data, 'reschedule_milstone_objects'); $successive_milestones = Milestones::findSuccessiveByMilestone($this->active_milestone, STATE_VISIBLE, $this->logged_user->getVisibility()); // before we update timestamp $reschedule = $this->active_milestone->reschedule($new_start_on, $new_due_on, $reschedule_tasks); if ($reschedule && !is_error($reschedule)) { //if (instance_of($new_due_on, 'DateValue')){ if ($new_due_on->getTimestamp() != $old_due_on->getTimestamp()) { $with_successive = array_var($milestone_data, 'with_sucessive'); $to_move = null; switch (array_var($with_successive, 'action')) { case 'move_all': $to_move = $successive_milestones; break; case 'move_selected': $selected_milestones = array_var($with_successive, 'milestones'); if (is_foreachable($selected_milestones)) { $to_move = Milestones::findByIds($selected_milestones, STATE_VISIBLE, $this->logged_user->getVisibility()); } // if break; } // switch if (is_foreachable($to_move)) { $diff = $new_due_on->getTimestamp() - $old_due_on->getTimestamp(); foreach ($to_move as $to_move_milestone) { $milestone_start_on = $to_move_milestone->getStartOn(); $milestone_due_on = $to_move_milestone->getDueOn(); $new_milestone_start_on = $milestone_start_on->advance($diff, false); $new_milestone_due_on = $milestone_due_on->advance($diff, false); $to_move_milestone->reschedule($new_milestone_start_on, $new_milestone_due_on, $reschedule_tasks); } // foreach } // if } // if db_commit(); if ($this->request->getFormat() == FORMAT_HTML) { //flash_success('Milestone ":name" has been updated', array('name' => $this->active_milestone->getName()), false, true); flash_success('Project ":name" has been updated', array('name' => $this->active_milestone->getName()), false, true); $this->redirectToUrl($this->active_milestone->getViewUrl()); } else { $this->serveData($this->active_milestone); } // if //} } else { db_rollback(); if ($this->request->getFormat() == FORMAT_HTML) { $this->smarty->assign('errors', $reschedule); } else { $this->serveData($save); } // if } // if } // if }
/** * Check if this invoice is overdue * * @param void * @return null */ function isOverdue() { $today = new DateValue(time() + get_user_gmt_offset()); $due_on = $this->getDueOn(); return (bool) ($this->isIssued() && !$this->isBilled() && !$this->isCanceled() && (instance_of($due_on, 'DateValue') && $due_on->getTimestamp() < $today->getTimestamp())); }
function index() { parent::index(); $milestones_t = Milestones::findAllByProject($this->active_project); $tasks_t = Tasks::findByProject($this->active_project, $this->logged_user); $milestones = array(); $tasks = array(); // voglio il task non categorizzato che inizia prima di tutti, quindi setto questo nel futuro $first_task_time = new DateValue(time() + time()); $trovato = false; if (is_foreachable($tasks_t)) { foreach ($tasks_t as $task) { $res = array(); $res['id'] = $task->getTaskId(); $res['name'] = $task->getName(); $task->complete()->describe($this->logged_user, true, true, $completion_description); $task_description = $task->describe($this->logged_user, true, true); $res['is_completed'] = $completion_description['is_completed']; $res['completed_on'] = $completion_description['completed_on']; $res['due_on'] = $completion_description['due_on']; // non è sempre settato $res['milestone_id'] = $task_description['milestone_id'] ? $task_description['milestone_id'] : 0; $res['created_on_d'] = $task->getCreatedOn()->getDay(); $res['created_on_m'] = $task->getCreatedOn()->getMonth() - 1; $res['created_on_y'] = $task->getCreatedOn()->getYear(); // La data di inizio non è sempre presente. Quindi se non c'è, prendo la data di creazione del task. // Inoltre questo campo dipende dal modulo TaskPlus if (AngieApplication::isModuleLoaded('tasks_plus') && TaskPlus::getStartOn($task)) { $start_on = TaskPlus::getStartOn($task); } else { $start_on = $task->getCreatedOn(); } $res['start_on_d'] = $start_on->getDay(); $res['start_on_m'] = $start_on->getMonth() - 1; //javascript merda parte da Gennaio = 0 $res['start_on_y'] = $start_on->getYear(); // giorni in più $days = 60 * 60 * 24 * 15; //15 giorni in più if ($completion_description['is_completed']) { $completion_date = $completion_description['completed_on']; } else { if ($completion_description['due_on']) { // non è completata ma ha data di fine settata $completion_date = $completion_description['due_on']; } else { if (!$completion_description['due_on']) { // non è completata e non ha data di fine settata $completion_date = $start_on->advance($days, false); // (data_inizio || data_creazione) + 15 giorni } } } $res['finish_on_d'] = $completion_date->getDay(); $res['finish_on_m'] = $completion_date->getMonth() - 1; //javascript merda parte da Gennaio = 0 $res['finish_on_y'] = $completion_date->getYear(); $res['durata'] = $start_on->daysBetween($completion_date) * 8; //giorni_differenza * ore_lavorative if ($res['is_completed']) { $res['percent_completion'] = 100; } else { list($total_subtasks, $open_subtasks) = ProjectProgress::getObjectProgress($task); $completed_subtasks = $total_subtasks - $open_subtasks; if ($open_subtasks) { $res['percent_completion'] = ceil($completed_subtasks / $total_subtasks * 100); } else { $res['percent_completion'] = 0; } } $tasks[] = $res; if ($res['milestone_id'] == 0 && $first_task_time->getTimestamp() > $start_on->getTimestamp()) { $first_task_time = $start_on; $trovato = false; } } } if ($trovato) { //Aggiungo la milestone per tasks non categorizzati $milestones[0]['id'] = 0; $milestones[0]['name'] = lang("Uncategorized"); $milestones[0]['start_on_d'] = $first_task_time->getDay(); $milestones[0]['start_on_m'] = $first_task_time->getMonth() - 1; $milestones[0]['start_on_y'] = $first_task_time->getYear(); $milestones[0]['durata'] = 1; } if (is_foreachable($milestones_t)) { foreach ($milestones_t as $milestone) { $res = array(); $res['id'] = $milestone->getId(); $res['name'] = $milestone->getName(); $res['start_on_d'] = $milestone->getStartOn()->getDay(); $res['start_on_m'] = $milestone->getStartOn()->getMonth() - 1; //javascript merda parte da Gennaio = 0 $res['start_on_y'] = $milestone->getStartOn()->getYear(); $res['durata'] = ($milestone->getDueOn()->getTimestamp() - $milestone->getStartOn()->getTimestamp()) / (60 * 60 * 24) * 8; //giorni * ore lavorative $milestones[] = $res; } } $this->smarty->assign(array('milestones' => $milestones, 'tasks' => $tasks)); }
/** * Render single day * * @param DateValue $day * @param integer $weekday * @return string */ function renderDay($day, $weekday) { $this->smarty->assign(array('day' => $day, 'day_url' => Calendar::getProfileDayUrl($this->user, $day->getYear(), $day->getMonth(), $day->getDay()), 'day_data' => array_var($this->data, $this->year . '-' . $this->month . '-' . $day->getDay()))); return $this->smarty->fetch(get_template_path('cell', null, 'calendar')); }
/** * Prepare conditions based on filter settings * * @param User $user * @return string */ function prepareConditions($user) { $project_objects_table = TABLE_PREFIX . 'project_objects'; $assignments_table = TABLE_PREFIX . 'assignments'; $completable_types = get_completable_project_object_types(); $conditions = array(); // Selected projects filter if ($this->getProjectFilter() == PROJECT_FILTER_SELECTED) { $project_ids = $this->getProjectFilterData(); if ($project_ids) { $conditions[] = db_prepare_string("({$project_objects_table}.project_id IN (?))", array($project_ids)); $types_filter = ProjectUsers::getVisibleTypesFilter($user, null, $completable_types); if ($types_filter) { $conditions[] = $types_filter; } else { return false; // No access to any of the projects? } // if } // if } // if // All projects if (count($conditions) == 0) { $types_filter = ProjectUsers::getVisibleTypesFilter($user, array(PROJECT_STATUS_ACTIVE), $completable_types); if ($types_filter) { $conditions[] = $types_filter; } else { return false; // No access to any of the projects? } // if } // if // User filter switch ($this->getUserFilter()) { // Not assigned to anyone case USER_FILTER_NOT_ASSIGNED: $user_id = $user->getId(); $conditions[] = "({$assignments_table}.user_id IS NULL)"; break; // Logged user // Logged user case USER_FILTER_LOGGED_USER: $user_id = $user->getId(); $conditions[] = "({$assignments_table}.user_id = {$user_id})"; break; // Logged user is responsible // Logged user is responsible case USER_FILTER_LOGGED_USER_RESPONSIBLE: $user_id = $user->getId(); $conditions[] = "({$assignments_table}.user_id = {$user_id}) AND ({$assignments_table}.is_owner = 1)"; break; // All members of a specific company // All members of a specific company case USER_FILTER_COMPANY: $visible_user_ids = $user->visibleUserIds(); if (!is_foreachable($visible_user_ids)) { return false; } // if $company_id = $this->getUserFilterData(); if ($company_id) { $company = Companies::findById($company_id); if (instance_of($company, 'Company')) { $user_ids = Users::findUserIdsByCompany($company); if (is_foreachable($user_ids)) { foreach ($user_ids as $k => $v) { if (!in_array($v, $visible_user_ids)) { unset($user_ids[$k]); } // if } // if if (count($user_ids) > 0) { $imploded = implode(', ', $user_ids); $conditions[] = "({$assignments_table}.user_id IN ({$imploded}))"; } else { return false; } // if } // if } // if } // if break; // Selected users // Selected users case USER_FILTER_SELECTED: $visible_user_ids = $user->visibleUserIds(); if (!is_foreachable($visible_user_ids)) { return false; } // if $user_ids = $this->getUserFilterData(); if (is_foreachable($user_ids)) { foreach ($user_ids as $k => $v) { if (!in_array($v, $visible_user_ids)) { unset($user_ids[$k]); } // if } // foreach if (count($user_ids) > 0) { $imploded = implode(', ', $user_ids); $conditions[] = "({$assignments_table}.user_id IN ({$imploded}))"; } else { return false; } // if } // if break; } // switch $today = new DateValue(time() + get_user_gmt_offset($user)); // Calculate user timezone when determining today switch ($this->getDateFilter()) { // List late assignments case DATE_FILTER_LATE: $today_str = db_escape($today->toMySQL()); $conditions[] = "({$project_objects_table}.due_on < {$today_str})"; break; // List today assignments // List today assignments case DATE_FILTER_TODAY: $today_str = db_escape($today->toMySQL()); $conditions[] = "({$project_objects_table}.due_on = {$today_str})"; break; // List tomorrow assignments // List tomorrow assignments case DATE_FILTER_TOMORROW: $tomorrow = $today->advance(86400, false); $tomorrow_str = db_escape($tomorrow->toMySQL()); $conditions[] = "({$project_objects_table}.due_on = {$tomorrow_str})"; break; // List this week assignments // List this week assignments case DATE_FILTER_THIS_WEEK: $first_day_sunday = UserConfigOptions::getValue('time_first_week_day', $user) == 0; $week_start = $today->beginningOfWeek($first_day_sunday); $week_end = $today->endOfWeek($first_day_sunday); $week_start_str = db_escape($week_start->toMySQL()); $week_end_str = db_escape($week_end->toMySQL()); $conditions[] = "({$project_objects_table}.due_on >= {$week_start_str} AND {$project_objects_table}.due_on <= {$week_end_str})"; break; // List next week assignments // List next week assignments case DATE_FILTER_NEXT_WEEK: $first_day_sunday = UserConfigOptions::getValue('time_first_week_day', $user) == 0; $next_week = $today->advance(604800, false); $week_start = $next_week->beginningOfWeek($first_day_sunday); $week_end = $next_week->endOfWeek($first_day_sunday); $week_start_str = db_escape($week_start->toMySQL()); $week_end_str = db_escape($week_end->toMySQL()); $conditions[] = "({$project_objects_table}.due_on >= {$week_start_str} AND {$project_objects_table}.due_on <= {$week_end_str})"; break; // List this month assignments // List this month assignments case DATE_FILTER_THIS_MONTH: $month_start = DateTimeValue::beginningOfMonth($today->getMonth(), $today->getYear()); $month_end = DateTimeValue::endOfMonth($today->getMonth(), $today->getYear()); $month_start_str = db_escape($month_start->toMySQL()); $month_end_str = db_escape($month_end->toMySQL()); $conditions[] = "({$project_objects_table}.due_on >= {$month_start_str} AND {$project_objects_table}.due_on <= {$month_end_str})"; break; // List next month assignments // List next month assignments case DATE_FILTER_NEXT_MONTH: $month = $today->getMonth() + 1; $year = $today->getYear(); if ($month == 13) { $month = 1; $year += 1; } // if $month_start = DateTimeValue::beginningOfMonth($month, $year); $month_end = DateTimeValue::endOfMonth($month, $year); $month_start_str = db_escape($month_start->toMySQL()); $month_end_str = db_escape($month_end->toMySQL()); $conditions[] = "({$project_objects_table}.due_on >= {$month_start_str} AND {$project_objects_table}.due_on <= {$month_end_str})"; break; // Specific date // Specific date case DATE_FILTER_SELECTED_DATE: $date_from = $this->getDateFrom(); if (instance_of($date_from, 'DateTimeValue')) { $date_from_str = db_escape($date_from->toMySql()); $conditions[] = "({$project_objects_table}.due_on = {$date_from_str})"; } // if break; // Specific range // Specific range case DATE_FILTER_SELECTED_RANGE: $date_from = $this->getDateFrom(); $date_to = $this->getDateTo(); if (instance_of($date_from, 'DateValue') && instance_of($date_to, 'DateValue')) { $date_from_str = db_escape($date_from->toMySQL()); $date_to_str = db_escape($date_to->toMySQL()); $conditions[] = "({$project_objects_table}.due_on >= {$date_from_str} AND {$project_objects_table}.due_on <= {$date_to_str})"; } // if break; } // switch // Status filter switch ($this->getStatusFilter()) { case STATUS_FILTER_ACTIVE: $conditions[] = "({$project_objects_table}.completed_on IS NULL)"; break; case STATUS_FILTER_COMPLETED: $conditions[] = "({$project_objects_table}.completed_on IS NOT NULL)"; break; } // if // Additional filters $state = STATE_VISIBLE; $visibility = $user->getVisibility(); $conditions[] = "({$project_objects_table}.state >= {$state} AND {$project_objects_table}.visibility >= {$visibility})"; return implode(' AND ', $conditions); }
/** * Render specific day * * $weekday is numeric representation of day in a week. 0 is Sunday -> 6 is * Saturday * * @param DateValue $day * @param integer $weekday * @return null */ function renderDay($day, $weekday) { $class = $weekday == 0 || $weekday == 6 ? 'weekend' : 'weekday'; return '<td class="' . $class . '">' . $day->getDay() . '</td>'; }
/** * Prepare conditions based on report settings * * @param User $user * @param Project $project * @return string */ function prepareConditions($user, $project = null) { $project_objects_table = TABLE_PREFIX . 'project_objects'; $conditions = array(); // Project and type if (instance_of($project, 'Project')) { $conditions[] = db_prepare_string('project_id = ? AND type = ?', array($project->getId(), 'timerecord')); } else { $conditions[] = db_prepare_string('type = ?', array('timerecord')); } // if // User filter switch ($this->getUserFilter()) { // Anyone - This filter used to filter only time tracked from all // visible users, but that did not include deleted accounts. Fixed now // //case USER_FILTER_ANYBODY: // $visible_user_ids = $user->visibleUserIds(); // if(is_foreachable($visible_user_ids)) { // $conditions[] = "($project_objects_table.integer_field_1 IN (" . db_escape($visible_user_ids) . '))'; // } else { // return false; // not visible users // } // if // break; // Logged user case USER_FILTER_LOGGED_USER: $user_id = $user->getId(); $conditions[] = "({$project_objects_table}.integer_field_1 = {$user_id})"; break; // All members of a specific company // All members of a specific company case USER_FILTER_COMPANY: $visible_user_ids = $user->visibleUserIds(); if (!is_foreachable($visible_user_ids)) { return false; } // if $company_id = $this->getUserFilterData(); if ($company_id) { $company = Companies::findById($company_id); if (instance_of($company, 'Company')) { $user_ids = Users::findUserIdsByCompany($company); if (is_foreachable($user_ids)) { foreach ($user_ids as $k => $v) { if (!in_array($v, $visible_user_ids)) { unset($user_ids[$k]); } // if } // if if (count($user_ids) > 0) { $imploded = implode(', ', $user_ids); $conditions[] = "({$project_objects_table}.integer_field_1 IN ({$imploded}))"; } else { return false; } // if } // if } // if } // if break; // Selected users // Selected users case USER_FILTER_SELECTED: $visible_user_ids = $user->visibleUserIds(); if (!is_foreachable($visible_user_ids)) { return false; } // if $user_ids = $this->getUserFilterData(); if (is_foreachable($user_ids)) { foreach ($user_ids as $k => $v) { if (!in_array($v, $visible_user_ids)) { unset($user_ids[$k]); } // if } // foreach if (count($user_ids) > 0) { $imploded = implode(', ', $user_ids); $conditions[] = "({$project_objects_table}.integer_field_1 IN ({$imploded}))"; } else { return false; } // if } // if break; } // switch $today = new DateValue(time() + get_user_gmt_offset($user)); // Calculate user timezone when determining today switch ($this->getDateFilter()) { // List time records posted for today case DATE_FILTER_TODAY: $today_str = db_escape($today->toMySQL()); $conditions[] = "({$project_objects_table}.date_field_1 = {$today_str})"; break; // List next week records // List next week records case DATE_FILTER_LAST_WEEK: $first_day_sunday = UserConfigOptions::getValue('time_first_week_day', $user) == 0; $last_week = $today->advance(-604800, false); $week_start = $last_week->beginningOfWeek($first_day_sunday); $week_end = $last_week->endOfWeek($first_day_sunday); $week_start_str = db_escape($week_start->toMySQL()); $week_end_str = db_escape($week_end->toMySQL()); $conditions[] = "({$project_objects_table}.date_field_1 >= {$week_start_str} AND {$project_objects_table}.date_field_1 <= {$week_end_str})"; break; // List this week records // List this week records case DATE_FILTER_THIS_WEEK: $first_day_sunday = UserConfigOptions::getValue('time_first_week_day', $user) == 0; $week_start = $today->beginningOfWeek($first_day_sunday); $week_end = $today->endOfWeek($first_day_sunday); $week_start_str = db_escape($week_start->toMySQL()); $week_end_str = db_escape($week_end->toMySQL()); $conditions[] = "({$project_objects_table}.date_field_1 >= {$week_start_str} AND {$project_objects_table}.date_field_1 <= {$week_end_str})"; break; // List this month time records // List this month time records case DATE_FILTER_LAST_MONTH: $month = $today->getMonth() - 1; $year = $today->getYear(); if ($month == 0) { $month = 12; $year -= 1; } // if $month_start = DateTimeValue::beginningOfMonth($month, $year); $month_end = DateTimeValue::endOfMonth($month, $year); $month_start_str = db_escape($month_start->toMySQL()); $month_end_str = db_escape($month_end->toMySQL()); $conditions[] = "({$project_objects_table}.date_field_1 >= {$month_start_str} AND {$project_objects_table}.date_field_1 <= {$month_end_str})"; break; // Last month // Last month case DATE_FILTER_THIS_MONTH: $month_start = DateTimeValue::beginningOfMonth($today->getMonth(), $today->getYear()); $month_end = DateTimeValue::endOfMonth($today->getMonth(), $today->getYear()); $month_start_str = db_escape($month_start->toMySQL()); $month_end_str = db_escape($month_end->toMySQL()); $conditions[] = "({$project_objects_table}.date_field_1 >= {$month_start_str} AND {$project_objects_table}.date_field_1 <= {$month_end_str})"; break; // Specific date // Specific date case DATE_FILTER_SELECTED_DATE: $date_from = $this->getDateFrom(); if (instance_of($date_from, 'DateValue')) { $date_from_str = db_escape($date_from->toMySql()); $conditions[] = "({$project_objects_table}.date_field_1 = {$date_from_str})"; } // if break; // Specific range // Specific range case DATE_FILTER_SELECTED_RANGE: $date_from = $this->getDateFrom(); $date_to = $this->getDateTo(); if (instance_of($date_from, 'DateValue') && instance_of($date_to, 'DateValue')) { $date_from_str = db_escape($date_from->toMySQL()); $date_to_str = db_escape($date_to->toMySQL()); $conditions[] = "({$project_objects_table}.date_field_1 >= {$date_from_str} AND {$project_objects_table}.date_field_1 <= {$date_to_str})"; } // if break; } // switch // Billable filter switch ($this->getBillableFilter()) { case BILLABLE_FILTER_BILLABLE: $conditions[] = "({$project_objects_table}.integer_field_2 = '" . BILLABLE_STATUS_BILLABLE . "')"; break; case BILLABLE_FILTER_NOT_BILLABLE: $conditions[] = "({$project_objects_table}.integer_field_2 = '" . BILLABLE_STATUS_NOT_BILLABLE . "' OR {$project_objects_table}.integer_field_2 IS NULL)"; break; case BILLABLE_FILTER_BILLABLE_BILLED: $conditions[] = "({$project_objects_table}.integer_field_2 >= '" . BILLABLE_STATUS_BILLED . "')"; break; case BILLABLE_FILTER_PENDING_PAYMENT: $conditions[] = "({$project_objects_table}.integer_field_2 = '" . BILLABLE_STATUS_PENDING_PAYMENT . "')"; break; case BILLABLE_FILTER_BILLABLE_NOT_BILLED: $conditions[] = "({$project_objects_table}.integer_field_2 IN ('" . BILLABLE_STATUS_BILLABLE . "', '" . BILLABLE_STATUS_PENDING_PAYMENT . "'))"; break; } // switch // Additional filters $state = STATE_VISIBLE; $visibility = $user->getVisibility(); $conditions[] = "({$project_objects_table}.state >= {$state} AND {$project_objects_table}.visibility >= {$visibility})"; return implode(' AND ', $conditions); }
/** * Return view day records (statically availables) * * @param Project $project * @param DateValue $day * @param integer $page * @return string * @static */ function getViewDayUrl($project, $day, $page = null) { $params = array('project_id' => $project->getId(), 'day' => $day->getYear() . '-' . $day->getMonth() . '-' . $day->getDay()); if ($page !== null) { $params['page'] = $page; } // if return assemble_url('project_time_day', $params); }
/** * Check if $date is in range between $from and $to * * @param DateValue $date * @param DateValue $from * @param DateValue $to * @return boolean */ function date_in_range($date, $from, $to) { return $date->getTimestamp() >= $from->getTimestamp() && $date->getTimestamp() <= $to->getTimestamp(); }