/wp/wp-content/plugins/hris-leave/includes/balance.php
PHP | 368 lines | 227 code | 51 blank | 90 comment | 46 complexity | 59384f90e91fc358cba81562b5b9dc5b MD5 | raw file
- <?php
- /**
- * Leave balance.
- *
- * @package HRIS Leave
- * @since 0.1.0
- * @author Akeda Bagus <admin@gedex.web.id>
- */
- class HRIS_Leave_Balance implements HRIS_Leave_Component_Interface {
- /**
- *
- * @var array
- */
- private $_post_pre_deleted = array();
- /**
- * User meta key that stores leave balance.
- */
- const LEAVE_BALANCE_USER_META = 'leave_balance';
- public function load() {
- add_action( 'transition_post_status', array( $this, 'on_transition_status' ), 10, 3 );
- add_action( 'before_delete_post', array( $this, 'on_before_delete_post' ), 1 );
- add_action( 'deleted_post', array( $this, 'on_deleted_post' ), 1 );
- $post_type = HRIS_Leave_Post_Type::NAME;
- // Fills customized columns.
- add_action( 'manage_' . $post_type . '_posts_custom_column', array( $this, 'custom_columns_row' ), 99, 2 );
- // Saves leave balance into user meta.
- add_action( 'on_sanitizing_leave_balance_users', array( $this, 'on_sanitizing_leave_balance_users' ) );
- add_action( 'load-post-new.php', array( $this, 'show_remaining_leave_as_notice' ) );
- add_action( 'load-edit.php', array( $this, 'show_remaining_leave_as_notice' ) );
- }
- /**
- * Is a given leave a planned leave. Check its leave type term.
- *
- * @param mixed $post
- * @return bool
- */
- public function is_planned_leave( $post ) {
- $terms = get_the_terms( $post, HRIS_Leave_Type_Taxonomy::NAME );
- if ( ! $terms )
- return false;
- if ( is_wp_error( $terms ) )
- return false;
- $first_term = array_shift( $terms );
- // Get the meta
- $term_meta = get_option( 'taxonomy_' . $first_term->term_id );
- return ( isset( $term_meta['is_planned'] ) && $term_meta['is_planned'] );
- }
- /**
- * If leave is approved, increase number of approved of user meta leave balance.
- *
- * @param string $new_status Transition to this post status.
- * @param string $old_status Previous post status.
- * @param object $post Post data.
- */
- public function on_transition_status( $new_status, $old_status, $post ) {
- if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
- return;
- if ( wp_is_post_revision( $post->ID ) )
- return;
- $excluded_status = array( 'auto-draft', 'draft', 'future', 'private', 'inherit', 'trash' );
- if ( in_array( $new_status, $excluded_status ) )
- return;
- // Unplanned leave?
- if ( ! $this->is_planned_leave( $post ) )
- return;
- $start_date = get_field( 'start_date', $post->ID );
- $strtime_start = strtotime( $start_date );
- $year = intval( date( 'Y', $strtime_start ) );
- $month_start = intval( date( 'm', $strtime_start ) );
- // If from another post status to approved then increases approved_per_month.
- // Please note that using this approach means that number of approved belongs
- // to year/month of start date. This is fine per BMW ID' request.
- if ( HRIS_Approval_Setting::APPROVED !== $old_status && HRIS_Approval_Setting::APPROVED === $new_status ) {
- $number_of_days = get_field( 'number_of_days', $post->ID );
- $this->increase_approved( $post->post_author, $year, $month_start, $number_of_days );
- }
- }
- /**
- * When a leave deleted, decrease number of approved.
- *
- * @action deleted_post
- * @param int $post_id Post ID
- * @return void
- */
- public function on_before_delete_post( $post_id ) {
- $post_obj = get_post( $post_id );
- if ( HRIS_Leave_Post_Type::NAME !== $post_obj->post_type )
- return;
- if ( HRIS_Approval_Setting::APPROVED !== $post_obj->post_status )
- return;
- // Unplanned leave?
- if ( ! $this->is_planned_leave( $post ) )
- return;
- $start_date = get_field( 'start_date', $post_id );
- $end_date = get_field( 'end_date', $post_id );
- $strtime_start = strtotime( $start_date );
- $strtime_end = strtotime( $end_date );
- $year = intval( date( 'Y', $strtime_start ) );
- $month_start = intval( date( 'm', $strtime_start ) );
- $month_end = intval( date( 'm', $strtime_end ) );
- if ( $month_end === $month_start ) {
- $days = hris_get_number_of_days( $start_date, $end_date );
- $month_start_days = $days['number_of_days'];
- $month_end_days = 0;
- } else {
- $days_start = hris_get_number_of_days( $start_date, sprintf( '%d-%d-31', $year, $month_start ) );
- $days_end = hris_get_number_of_days( sprintf( '%d-%d-01', $year, $month_end ), $end_date );
- $month_start_days = $days_start['number_of_days'];
- $month_end_days = $days_end['number_of_days'];
- }
- $user_id = $post_obj->post_author;
- $this->_post_pre_deleted[ $post_id ] = compact(
- 'user_id', 'year', 'month_start', 'month_end', 'month_start_days', 'month_end_days'
- );
- }
- public function on_deleted_post( $post_id ) {
- if ( isset( $this->_post_pre_deleted[ $post_id ] ) ) {
- /**
- * @var $user_id
- * @var $year
- * @var $month_start
- * @var $month_end
- * @var $month_start_days
- * @var $month_end_days
- */
- extract( $this->_post_pre_deleted[ $post_id ] );
- if ( $month_end === $month_start ) {
- $this->decrease_approved( $user_id, $year, $month_start, $month_start_days );
- } else {
- $this->decrease_approved( $user_id, $year, $month_start, $month_start_days );
- $this->decrease_approved( $user_id, $year, $month_end, $month_end_days );
- }
- unset( $this->_post_pre_deleted[ $post_id ] );
- }
- }
- /**
- * Saves leave balance into user meta too with nested array with following structure:
- *
- * ```
- * array(
- * 2013 => array(
- * 'balance' => 24,
- * 'approved_per_month' => array(
- * 1 => 2,
- * ...
- * 12 => 4,
- * )
- * )
- * )
- * ```
- *
- * @param array $val
- */
- public function on_sanitizing_leave_balance_users( $val ) {
- $default_balance = $val['default_annual_leave_balance'];
- $current_year = intval( date('Y') ); // @todo Use date helper from WordPress?
- $default_meta = array(
- $current_year => array(
- 'balance' => $default_balance,
- 'approved_per_month' => array_fill( 1, 12, 0 ),
- ),
- );
- foreach ( $val['leave_balance_users'] as $user_id => $balance ) {
- $meta_leave = get_user_meta( $user_id, self::LEAVE_BALANCE_USER_META, true );
- $balance = (double)$balance;
- if ( ! $meta_leave ) {
- $new_val = $default_meta;
- $new_val[ $current_year ]['balance'] = $balance;
- } else {
- if ( ! isset( $meta_leave[ $current_year ] ) ) {
- $meta_leave[ $current_year ] = array(
- 'balance' => $balance,
- 'approved_per_month' => array_fill( 1, 12, 0 ),
- );
- } else {
- $meta_leave[ $current_year ]['balance'] = $balance;
- }
- $new_val = $meta_leave;
- }
- update_user_meta( $user_id, self::LEAVE_BALANCE_USER_META, $new_val );
- }
- }
- public function custom_columns_row( $column, $post_id ) {
- if ( 'balance' === $column ) {
- $post_obj = get_post( $post_id );
- $year = intval( date( 'Y', strtotime( get_field( 'start_date', $post_id ) ) ) );
- $leave_balance = $this->get_leave_balance( $post_obj->post_author, $year );
- if ( isset( $leave_balance['approved_per_month'] ) && is_array( $leave_balance['approved_per_month'] ) ) {
- echo $this->get_remaining_leave( $post_obj->post_author, $year );
- } else {
- echo sprintf( __( 'The leave balance is not ready for %d.', 'hris-leave' ), $year );
- }
- }
- }
- /**
- * Show remaining leave inside notice in post-new.php
- *
- * @action load-post-new.php
- */
- public function show_remaining_leave_as_notice() {
- if ( ! isset( $_GET['post_type'] ) )
- return;
- if ( HRIS_Leave_Post_Type::NAME !== $_GET['post_type'] )
- return;
- $current_user = wp_get_current_user();
- if ( hris_check_user_role( 'administrator', $current_user->ID ) )
- return;
- wp_enqueue_style( 'leave-remaining-balance-notice', HRIS_LEAVE_URI . '/css/leave-remaining-balance-notice.css' );
- $total_approved = $this->get_remaining_leave( $current_user->ID, date( 'Y' ) );
- add_action( 'admin_notices', function() use( $total_approved ) {
- printf(
- '<div class="updated" id="leave-remaining-balance-notice"><p>%s</p></div>',
- sprintf( __( 'Your remaining leave balance for this year is <strong>%g</strong> days.', 'hris-leave' ), $total_approved )
- );
- } );
- }
- /**
- * Gets leave balance from particular user on a given year.
- *
- * @param int $user_id User ID
- * @param int $year
- * @param int $month
- * @return array
- */
- public function get_leave_balance( $user_id, $year, $month = null ) {
- $leave_balance = get_user_meta( $user_id, self::LEAVE_BALANCE_USER_META, true );
- $year = intval( $year );
- if ( ! $leave_balance )
- return null;
- if ( ! isset( $leave_balance[ $year ] ) )
- return null;
- if ( ! $month )
- return $leave_balance[ $year ];
- if ( ! isset( $leave_balance[ $year ]['approved_per_month'][ $month ] ) )
- return null;
- return $leave_balance[ $year ]['approved_per_month'][ $month ];
- }
- public function get_total_approved( $user_id, $year ) {
- $leave_balance = $this->get_leave_balance( $user_id, $year );
- if ( isset( $leave_balance['approved_per_month'] ) && is_array( $leave_balance['approved_per_month'] ) ) {
- $total_approved = 0;
- foreach ( $leave_balance['approved_per_month'] as $approved ) {
- $total_approved += $approved;
- }
- return $total_approved;
- }
- return 0;
- }
- public function get_remaining_leave( $user_id, $year ) {
- $leave_balance = $this->get_leave_balance( $user_id, $year );
- $balance = isset( $leave_balance['balance'] ) ? $leave_balance['balance'] : 0;
- $total_approved = $this->get_total_approved( $user_id, $year );
- $remaining = $balance - $total_approved;
- if ( $remaining >= 0 ) {
- return $remaining;
- }
- return 0;
- }
- /**
- * Increases total approved of a user for particlar year and month
- *
- * @param int $user_id User ID
- * @param int $year
- * @param int $month
- * @param int $number_of_days
- * @param string $operation Whether 'add', 'increase', 'decrease', 'sub', or 'subtract'
- */
- public function alter_approved( $user_id, $year, $month, $number_of_days, $operation = 'add' ) {
- $year = intval( $year );
- $month = intval( $month );
- $number_of_days = (double)$number_of_days;
- $setting = hris_get_component_from_module( 'leave', 'Setting' );
- $users_balance = $setting->get_setting( 'leave_balance_users' );
- $default_values = array(
- 'balance' => $users_balance[ $user_id ],
- 'approved_per_month' => array(
- $month => $number_of_days,
- ),
- );
- $meta_value = get_user_meta( $user_id, self::LEAVE_BALANCE_USER_META, true );
- if ( ! $meta_value ) {
- $meta_value = array(
- $year => $default_values,
- );
- } else {
- if ( ! isset( $meta_value[ $year ] ) ) {
- $meta_value[ $year ] = $default_values;
- } else if ( ! isset( $meta_value[ $year ]['approved_per_month'] ) ) {
- $meta_value[ $year ] = $default_values['approved_per_month'];
- } else if ( ! isset( $meta_value[ $year ]['approved_per_month'][ $month ] ) ) {
- $meta_value[ $year ]['approved_per_month'] = $default_values['approved_per_month'][ $month ];
- } else { // Increase.
- switch ( $operation ) {
- case 'decrease':
- case 'sub':
- case 'subtract':
- if ( (double) $meta_value[ $year ]['approved_per_month'][ $month ] >= (double) $number_of_days ) {
- $meta_value[ $year ]['approved_per_month'][ $month ] = (double)$meta_value[ $year ]['approved_per_month'][ $month ] - (double)$number_of_days;
- }
- break;
- case 'add':
- case 'increase':
- default:
- $meta_value[ $year ]['approved_per_month'][ $month ] = (double)$meta_value[ $year ]['approved_per_month'][ $month ] + (double)$number_of_days;
- break;
- }
- }
- }
- update_user_meta( $user_id, self::LEAVE_BALANCE_USER_META, $meta_value );
- }
- public function increase_approved( $user_id, $year, $month, $number_of_days ) {
- $this->alter_approved( $user_id, $year, $month, $number_of_days, 'increase' );
- }
- public function decrease_approved( $user_id, $year, $month, $number_of_days ) {
- $this->alter_approved( $user_id, $year, $month, $number_of_days, 'decrease' );
- }
- }