application_id = $application_id; } /** * Set application data */ public function set_application() { $this->application = get_post($this->application_id); } /** * Set client data */ public function set_client() { $client_id = get_post_meta($this->application_id, '_aam_application_client', true); if ($client_id) { $this->client = get_user_by('id', $client_id); } $this->_set_bo_days(); } /** * Set blackout days from client and consultant BO days */ private function _set_bo_days() { $client_bo_days = get_user_meta($this->client->ID, 'aam_bo_days', true); $consultant_bo_days = get_user_meta(get_current_user_id(), 'aam_bo_days', true); if (!$client_bo_days) $client_bo_days = array(); if (!$consultant_bo_days) $consultant_bo_days = array(); $this->bo_days = array_merge($client_bo_days, $consultant_bo_days); } public function set_combination_data() { $this->combination_data = get_post_meta($this->application_id, '_aam_application_combination', true); } public function set_combination() { if ($this->combination_data) { $this->combination = get_post($this->combination_data['combination']); } } /** * Set deadline for selected round */ public function set_deadline() { if ($this->combination) { $deadlines = get_post_meta($this->combination->ID, '_aam_combination_deadlines', true); $this->deadline = $deadlines[$this->combination_data['round'] - 1]; } } /** * Get steps from database */ public function set_steps() { global $wpdb; $app_table = $wpdb->prefix . 'aam_applications'; $this->steps = $wpdb->get_results( $wpdb->prepare("SELECT * FROM $app_table WHERE application_id = %d", $this->application_id) ); } /** * Set documents */ public function set_documents() { $documents = get_post_meta($this->combination->ID, '_aam_combination_documents', true); $this->documents = array(); $sum = 0; foreach ($documents as $dk => $document) { $documentSteps = get_post_meta($document['type'], '_aam_type_steps', true); $this->documents[$dk] = array( 'data' => $document, 'doc' => get_post($document['type']), 'steps' => array() ); $sum += $document['weight']; foreach ($documentSteps as $sk => $step) { $this->documents[$dk]['steps'][$sk] = $step; } } $this->sum = $sum; } /** * Set application data * @param bool $only_active */ public function set_application_data($only_active = true) { global $wpdb; $table_name = $wpdb->prefix . $this->table_name; if ($only_active) { $this->application_data = $wpdb->get_results( $wpdb->prepare("SELECT * FROM $table_name WHERE application_id = %d AND active = 1", $this->application_id), ARRAY_A ); } else { $this->application_data = $wpdb->get_results( $wpdb->prepare("SELECT * FROM $table_name WHERE application_id = %d", $this->application_id), ARRAY_A ); } } /** * Calculate deadlines for application * @param bool $save */ public function calc_deadlines($save = false) { $this->set_application(); $this->set_application_data(); $this->set_combination_data(); $this->set_combination(); $this->set_deadline(); $this->set_steps(); $this->set_documents(); $createdDate = new Carbon($this->application->post_date); $deadlineDate = new Carbon($this->deadline['date']); //calc diff between start and deadline dates $diff = $deadlineDate->diffInDays($createdDate); //sum all step days $days = 0; foreach ($this->application_data as $step) { $days += $step['step_days']; } //calculate off days $free_days = $this->calc_free_days($createdDate, $deadlineDate); //calc working days $working_days = $diff - $free_days; //var_dump($days); var_dump($working_days); die; if ($days > $working_days) { $this->recursive_decrease($days - $working_days); } else if ($days < $working_days) { $this->recursive_increase($working_days - $days); } //fb($this->documents); $this->set_deadlines($createdDate); //echo '
'; var_dump($this->application_data); die;
//fb($this->documents);
if ($save) {
$this->save_deadlines();
}
}
/**
* Calculate number of free days according to consultant free days and blackout days
*
* @param Carbon $createdDate
* @param Carbon $deadlineDate
*
* @return int
*/
public function calc_free_days(Carbon $createdDate, Carbon $deadlineDate)
{
$diff = $deadlineDate->diffInDays($createdDate);
$free_days_option = get_user_meta(get_current_user_id(), 'aam_off_days', true);
$free_days = $free_days_option ? array_keys($free_days_option) : array();
$free_days_total = 0;
$newDate = clone $createdDate;
if (!empty($free_days) || !empty($this->bo_days)) {
for ($i = 1; $i <= $diff; $i++) {
$newDate = clone $newDate;
$newDate->addDay();
if ($this->check_bo_days($newDate) || in_array(strtolower($newDate->format('D')), $free_days)) {
$free_days_total++;
}
}
}
return $free_days_total;
}
/**
* Check if selected date is between some of the blackout ranges
* @param Carbon $date
* @return bool
*/
private function check_bo_days(Carbon $date)
{
$bo_days = array();
foreach ($this->bo_days as $day) {
if ($day['from'] && $day['to']) {
$bo_days[] = array(
'from' => new Carbon($day['from']),
'to' => new Carbon($day['to'])
);
}
}
if (!empty($bo_days)) {
foreach ($bo_days as $day) {
if ($date->between($day['from'], $day['to'])) {
return true;
}
}
}
return false;
}
/**
* If document days is more then working days decrease by diff
*
* @param int $sub
*/
public function recursive_decrease($sub = 0)
{
foreach ($this->application_data as $k => $step) {
if ($sub > 0 && $step['step_min_days'] < $step['step_days']) {
$this->application_data[$k]['step_days']--;
$sub--;
}
}
if ($sub > 0) {
$this->recursive_decrease($sub);
}
}
/**
* If document days if less then working days increase by diff
*
* @param int $sub
*/
public function recursive_increase($sub = 0)
{
//var_dump($this->application_data); die;
foreach ($this->application_data as $k => $step) {
if ($sub > 0 && $step['step_max_days'] > $step['step_days']) {
$this->application_data[$k]['step_days']++;
$sub--;
}
}
if ($sub > 0) {
//var_dump($sub);
$this->recursive_increase($sub);
}
}
/**
* Set deadlines for all of the documents and steps
*
* @param Carbon $startDate
*/
public function set_deadlines(Carbon $startDate)
{
$free_days_option = get_user_meta(get_current_user_id(), 'aam_off_days', true);
$free_days = $free_days_option ? array_keys($free_days_option) : array();
$probe = clone $startDate;
foreach ($this->application_data as $sk => $step) {
for ($i = 1; $i <= $step['step_days']; $i++) {
$day = $probe->addDay();
$newDay = $this->find_next_free($day, $free_days);
}
$this->application_data[$sk]['deadline'] = clone $newDay;
}
}
/**
* Recursive function for finding next available day
*
* @param Carbon $day
* @param array $off_days
*
* @return Carbon
*/
private function find_next_free(Carbon $day, $off_days = array())
{
if (in_array(strtolower($day->format('D')), $off_days) || $this->check_bo_days($day)) {
$day->addDay();
return $this->find_next_free($day, $off_days);
} else {
return $day;
}
}
/**
* Save deadlines to helper database
*/
public function save_deadlines()
{
global $wpdb;
$table_name = $wpdb->prefix . $this->table_name;
foreach ($this->application_data as $step) {
$wpdb->update(
$table_name,
array(
'deadline' => $step['deadline']->format('Y-m-d')
),
array(
'id' => $step['id']
)
);
}
do_action('aam_save_deadlines', $this->application_data);
}
}