<?php


function get_rate_table_result($table_id, $employee_code, $ot_hours, $payroll_run_id, $based_on_full_value = false)
{
    $value = 0;
    $payroll_ot_hours = 0;
    
    $my_row = select_value_table_record($table_id, $ot_hours);
    if($my_row == null){
        return array(0,0);
    }
    
    if($my_row['accumulated_total'] == "1"){
        $rtar = get_rate_table_accumulated_result($table_id, $employee_code, $ot_hours, $payroll_run_id, $based_on_full_value);
        $value = $rtar['total_value'];
        $payroll_ot_hours = $rtar['payroll_ot_hours'];
    }
    else{
        if($my_row['calculation_type'] == "V"){
            $value = ($my_row['calculation_value'] * $ot_hours) + $my_row['fixed_value'];
            $payroll_ot_hours = $ot_hours;
        }
        elseif($my_row['calculation_type'] == "P"){
            $calculated_payroll_value = get_calculated_payroll_value($my_row['process_code'], $employee_code, $payroll_run_id, $based_on_full_value);
            $value = ((($calculated_payroll_value * $my_row['calculation_value'])/100) * $ot_hours) + $my_row['fixed_value'];
            $payroll_ot_hours = $ot_hours;
        }
    }
    
    return array($value, $payroll_ot_hours);
}


function get_rate_table_accumulated_result($table_id, $employee_code, $ot_hours, $payroll_run_id, $based_on_full_value = false)
{
    $remaining_hours = $ot_hours;
    $payroll_ot_hours = 0;
    $total_value = 0;
    $previous_limit = 0;
    
    $result = select_value_table_all_records($table_id);
    
    while ($myrow = db_fetch($result)){
        if($remaining_hours <= 0){
            break;
        }
        
        $values = "";
        $values = get_rate_table_record_result($myrow, $employee_code, $payroll_run_id, $previous_limit, $ot_hours, $based_on_full_value);

        $this_slab_size = $myrow['upto'] - $previous_limit;

        if($this_slab_size <= $remaining_hours){
            $total_value += ((double)$values['variable_value'] * $this_slab_size) + (double)$values['fixed_value'];
            $payroll_ot_hours += $this_slab_size * $myrow['value2'];
            $remaining_hours -= $this_slab_size;
        }
        else{
            if($myrow['calculation_type'] == "V"){
                $total_value += ((double)$values['variable_value'] * $remaining_hours) + (double)$values['fixed_value'];
                $payroll_ot_hours += $remaining_hours * $myrow['value2'];
            }
            if($myrow['calculation_type'] == "P"){
                $total_value += ((double)$values['variable_value'] * $remaining_hours) + (double)$values['fixed_value'];
                $payroll_ot_hours += $remaining_hours * $myrow['value2'];
            }
            $remaining_hours = 0;
        }

        $previous_limit = $myrow['upto'];        
    }
    
    return array('total_value' => $total_value, 'payroll_ot_hours' => $payroll_ot_hours);
}


function get_rate_table_record_result($value_table_row, $employee_code, $payroll_run_id, $previous_limit, $ot_hours, $based_on_full_value = false)
{
    $variable_value = $fixed_value = 0.00000;
    
    if($value_table_row['calculation_type'] == "V"){
        $variable_value = $value_table_row['calculation_value'];
        $fixed_value = $value_table_row['fixed_value'];
    }
    elseif($value_table_row['calculation_type'] == "P"){
        $calculated_payroll_value = get_calculated_payroll_value($value_table_row['process_code'], $employee_code, $payroll_run_id, $based_on_full_value);
        
        $variable_value = ($calculated_payroll_value * $value_table_row['calculation_value'])/100; 
        $fixed_value = $value_table_row['fixed_value'];
    }
    
    return array("variable_value" => $variable_value, "fixed_value" => $fixed_value);

}



function get_salary_total_value($process_code, $employee, $payroll_run, $nopay_days, $nopay_reference_days_factor = 30)
{
    $employee_code = $employee['employee_code'];
    
    $gstr_msg = get_salary_total_result($process_code, $employee, $payroll_run, $nopay_days);
    $saving_value = 0;
    if($gstr_msg['success'] === true){
        $calculated_value = $gstr_msg['calculated_value'];
        $full_value = $gstr_msg['full_value'];
        if($gstr_msg['save_full_value'] == true){
            $saving_value = $full_value;
        }
        else{
            $saving_value = $calculated_value; 
        }
    }
    else{
        $calculated_value = 0;
        $full_value = 0;
    }
    
    insert_payroll_run_detail($payroll_run['id'], $employee_code, $process_code, $saving_value, $gstr_msg['comment']);
    
    return array("calculated_value" => $calculated_value, "full_value" => $full_value);
}



function get_value_table_result($table_id, $employee_code, $calculated_payroll_value, $payroll_run_id, $payroll_days_factor = 1, $based_on_full_value = false)
{

    //$calculated_payroll_value = get_calculated_payroll_value($salary_total_code, $employee_code, $payroll_run_id);
    
    $my_row = select_value_table_record($table_id, $calculated_payroll_value);
    if($my_row == null)
        return 0;
    
    if($my_row['accumulated_total'] == "1"){
        $value = get_value_table_accumulated_result($table_id, $employee_code, $calculated_payroll_value, $payroll_run_id, $payroll_days_factor, $based_on_full_value);
    }
    else{
        if($my_row['calculation_type'] == "V"){
            $value = $my_row['calculation_value'] + $my_row['fixed_value'];
            $value = $value * $payroll_days_factor;
        }
        elseif($my_row['calculation_type'] == "P"){
            $calculated_payroll_value_P = get_calculated_payroll_value($my_row['process_code'], $employee_code, $payroll_run_id, $based_on_full_value);
            $value = ($calculated_payroll_value_P * $my_row['calculation_value'])/100 + ($my_row['fixed_value'] * $payroll_days_factor);
        }
    }
    
    return $value;
}


function get_value_table_accumulated_result($table_id, $employee_code, $reference_value, $payroll_run_id, $payroll_days_factor = 1, $based_on_full_value = false)
{
    $remaining_value = $reference_value;
    $total_value = 0;
    $previous_limit = 0;
    
    $result = select_value_table_all_records($table_id);
    
    while ($myrow = db_fetch($result)){
        if($remaining_value <= 0){
            break;
        }
        
        $values = "";
        $values = get_value_table_record_result($myrow, $employee_code, $payroll_run_id, $previous_limit, $payroll_days_factor, $based_on_full_value);

        $this_slab_size = $myrow['upto'] - $previous_limit;

        if($this_slab_size <= $remaining_value){
            $total_value += (double)$values['variable_value'] + (double)$values['fixed_value'];
            $remaining_value -= $this_slab_size;
        }
        else{
            if($myrow['calculation_type'] == "V"){
                $total_value += ((double)$values['variable_value'] * ($remaining_value/$this_slab_size)) + (double)$values['fixed_value'];
            }
            if($myrow['calculation_type'] == "P"){
                $total_value += (double)$values['variable_value'] + (double)$values['fixed_value'];
            }
            $remaining_value = 0;
        }

        $previous_limit = $myrow['upto'];        
    }
    
    return $total_value;
}


function get_value_table_record_result($value_table_row, $employee_code, $payroll_run_id, $previous_limit, $payroll_days_factor = 1, $based_on_full_value = false)
{
    $variable_value = $fixed_value = 0;
    
    if($value_table_row['calculation_type'] == "V"){
        $variable_value = $value_table_row['calculation_value'] * $payroll_days_factor;
        $fixed_value = $value_table_row['fixed_value'];
    }
    elseif($value_table_row['calculation_type'] == "P"){
        $calculated_payroll_value = get_calculated_payroll_value($value_table_row['process_code'], $employee_code, $payroll_run_id, $based_on_full_value);
        
        if($calculated_payroll_value >= $value_table_row['upto']){
            $calculated_payroll_value = $value_table_row['upto'];
        }
        if($calculated_payroll_value > $previous_limit){
            $calculated_payroll_value -= $previous_limit;
        }
        
        $variable_value = ($calculated_payroll_value * $value_table_row['calculation_value'])/100; 
        $fixed_value = $value_table_row['fixed_value'] * $payroll_days_factor;
    }
    
    return array("variable_value" => $variable_value, "fixed_value" => $fixed_value);

}


function get_calculated_payroll_value($process_code, $employee_code, $payroll_run_id, $full_value = false)
{
//    $my_row = select_calculated_payroll_value($process_code, $employee_code, $payroll_run_id);
//    if($my_row == null)
//        return 0;
    
    $calculated_payroll_value = get_calculated_salary_component_value($process_code, $full_value);
    
    return $calculated_payroll_value;
    
}

function get_calculated_salary_component_value($process_code, $full_value = false)
{
    global $salary;
    
    foreach ($salary as $element) {
        if($element['component'] == $process_code){
            if($full_value){
                return $element['full_value'];
            }
            else{
                 return $element['calculated_value'];
            }
        }        
    }
    
    return 0;
}


function get_calculated_payroll_db_value($process_code, $employee_code, $payroll_run_id)
{
    $my_row = select_calculated_payroll_value($process_code, $employee_code, $payroll_run_id);
    if($my_row == null){
        return 0;  
    }
    else{
        return $my_row['value'];
    }
}

function get_last_completed_emloyee($payroll_run_id)
{
    $my_row = select_last_completed_emloyee($payroll_run_id);
    if($my_row == null){
        return "";
    }
    return $my_row['last_completed_employee_code'];
}

function get_payroll_calculation_applicable_values($payroll_run, $employee, 
                                                    $salary_component, $nopay_days,  
                                                    &$applicable_start_date, &$applicable_end_date, &$payroll_days_factor,
                                                    $nopay_reference_days_factor = 30)
{    
    $resigned = $employee['resigned'];
    $applicable_start_date = sql2date($payroll_run['period_start_date']);
    $applicable_end_date = sql2date($payroll_run['period_end_date']);
    
    $payroll_days = date_diff2($applicable_end_date, $applicable_start_date, 'd') + 1;
    
    $salary_component_effective_date = $salary_component['effective_date'];
    $salary_component_end_date = $salary_component['end_date']; 
    
    $salary_component_start_date = sql2date($salary_component_effective_date);
    if(date1_greater_date2($salary_component_start_date, $applicable_start_date)){
        $applicable_start_date = $salary_component_start_date;
    }
    
    $date_of_joining = sql2date($employee['date_of_joining']);
    if(date1_greater_date2($date_of_joining, $applicable_start_date)){
        $applicable_start_date = $date_of_joining;
    }
    
    
    $salary_component_end_date = sql2date($salary_component_end_date);
    if(date1_greater_date2($applicable_end_date, $salary_component_end_date)){
        $applicable_end_date = $salary_component_end_date;
    }
    
    if($resigned){
        $date_of_resignation = sql2date($employee['date_of_resignation']);
        if(date1_greater_date2($applicable_end_date, $date_of_resignation)){
            $applicable_end_date = $date_of_resignation;
        }
    }
    
    
    if($applicable_start_date == $applicable_end_date){
        $applicable_days = 1;
    }
    elseif(date1_greater_date2($applicable_end_date, $applicable_start_date)){
        $applicable_days = date_diff2($applicable_end_date, $applicable_start_date, 'd') + 1;
    }
    else{
        $applicable_days = 0;
    }
    
    if($applicable_days < 0){
        $applicable_days = 0;
    }
    
    if($salary_component['full_amount'] == 1){
        $applicable_start_date = $payroll_run['period_start_date'];
        $applicable_end_date = $payroll_run['period_end_date'];
    }
    else{
        $applicable_start_date = date2sql($applicable_start_date);
        $applicable_end_date = date2sql($applicable_end_date);
    }
    
    
    
//    if($applicable_days < 28){
//        $payroll_days_factor = $applicable_days/30;
//    }
       
    if($nopay_reference_days_factor == 0){
        $payroll_days_factor = 0;
        return 0;
    }
    
    /* Modified as per the calculation described in the Excel file
     * Partial Salary Calculation JULY.xlsx finalized by Sithumi (hr1@sawengineering.com) and sent in the email
     * "Types of Employee working days" on 2017/09/04
     */
    switch ($payroll_days) {
        case 31:
            if($applicable_days == 31){
                $applicable_days = 30;
            }
            break;        
        case 29:
            if($applicable_days == 29){
                $applicable_days = 30;
            }
            break; 
            
        case 28:
            if($applicable_days == 28){
                $applicable_days = 30;
            }
            break; 
    }
    
    

        
    $period_based_days_factor = $applicable_days/30;
    
    if($salary_component['nopay_deduct'] == 1){
        //$applicable_days -= $nopay_days; 
        
        if($nopay_reference_days_factor == 30){
            $nopay_based_days_factor = $nopay_days/30;
        }
        elseif($nopay_reference_days_factor == 25){
            $nopay_based_days_factor = $nopay_days/25;
        }
        else{
            $nopay_based_days_factor = $nopay_days/30;
        }
    }
    else{
        $nopay_based_days_factor = 0;
    }
    
    //$nopay_based_days_factor = $nopay_days/25;
    
    $payroll_days_factor = $period_based_days_factor - $nopay_based_days_factor;
    if($payroll_days_factor < 0){
        $payroll_days_factor = 0;
    }
    
    return $applicable_days;
}

function get_salary_component_calculation_result($employee_code, $payroll_run_id, $salary_component, 
                                                $payroll_days_factor, $table_calculation_type, $table_source_value = null, 
                                                $based_on_full_value = false)

{
        $salary_component_value = 0;
        $comment = '';
        
        if($salary_component['calculation_type'] == "V"){
            $salary_component_value = $salary_component['amount'] * $payroll_days_factor;        
        }
        elseif($salary_component['calculation_type'] == "P"){
            $base_value = get_calculated_payroll_value($salary_component['salary_total_code'], $employee_code, $payroll_run_id, $based_on_full_value);
            $salary_component_value = ($base_value * $salary_component['amount'])/100;
        }    
        elseif($salary_component['calculation_type'] == "T"){
            // Calculate on salary component configuration values
            if($table_calculation_type == "V"){
                    //$salary_component_value = get_value_table_result($salary_component['table_id'], $employee_code, $salary_component['salary_total_code'], $payroll_run_id, $payroll_days_factor);               
                    $source_value  = get_calculated_payroll_value($salary_component['salary_total_code'], $employee_code, $payroll_run_id);
                    $salary_component_value = get_value_table_result($salary_component['table_id'], $employee_code, $source_value, $payroll_run_id, $payroll_days_factor);               
            }
            // Calculate value on sending source value
            elseif($table_calculation_type == "S"){
                    $salary_component_value = get_value_table_result($salary_component['table_id'], $employee_code, $table_source_value, $payroll_run_id, $payroll_days_factor);               
            }
            // Calculate rate on sending source value
            elseif($table_calculation_type == "R"){
                    $rate_table_result = get_rate_table_result($salary_component['table_id'], $employee_code, $table_source_value, 
                                                                    $payroll_run_id, $based_on_full_value);
                    $salary_component_value = $rate_table_result[0] * $rate_table_result[1];
            }
            else{
                    $salary_component_value = 0;
            }
        }
        elseif($salary_component['calculation_type'] == "R"){
                $gstr_msg = get_salary_component_program_result($employee_code, $payroll_run_id, $salary_component, $payroll_days_factor, $table_source_value);
                if($gstr_msg['success'] === true){
                    $salary_total_value = $gstr_msg['message'];
                    $comment = $gstr_msg['comment'];
                }
                else{
                    $salary_total_value = 0;
                    $comment = $gstr_msg['comment'];
                }
        } 
        
        return array($salary_component_value, $comment);
}

function get_payroll_employee_total_nopay_days($employee_code, $payroll_run){
    
    $my_row = select_payroll_employee_total_nopay_days($employee_code, $payroll_run['period_start_date'], $payroll_run['period_end_date']);
    if($my_row == null){
        return 0;
    }
    else{
        return $my_row['total_nopay_days'];
    }
}


function nopay_reference_days_factor($employee_code, $payroll_run)
{
    $employment_type = get_applicable_employment_type($employee_code, $payroll_run['period_start_date'], $payroll_run['period_end_date']);
    if(!$employment_type){
        $comment = "ERROR  ERROR  ERROR  ERROR  ERROR  ERROR  ERROR\r\n";
        $comment .= "No applicable employment type found for this employee\r\n";
        $comment .= "ERROR  ERROR  ERROR  ERROR  ERROR  ERROR  ERROR\r\n";
        insert_payroll_run_detail($payroll_run['id'], $employee_code, "ERROR-EMPLOYMENT_TYPE", -1000000, $comment);
        return 0;
    }
    
    $nopay_reference = select_nopay_refercnce_details($payroll_run['payroll_id'], $employment_type['employment_type_id']);
    if(!$nopay_reference){
        $comment = "ERROR  ERROR  ERROR  ERROR  ERROR  ERROR  ERROR\r\n";
        $comment .= "No nopay reference defined for employment type id [".$employment_type['employment_type_id']."] for this payroll\r\n";
        $comment .= "ERROR  ERROR  ERROR  ERROR  ERROR  ERROR  ERROR\r\n";
        insert_payroll_run_detail($payroll_run['id'], $employee_code, "ERROR-NOPAY_REFERENCE", -1000000, $comment);
        return 0;
    }
//    
//    
//    $list_value = get_list_value($nopay_reference['nopay_reference_value_id']);
//
//    $nopay_reference_code = $list_value['value_code'];
//
//    $nopay_reference_value = get_calculated_payroll_value($nopay_reference_code, $employee_code, $payroll_run['id'], true);
    $nopay_reference_days_factor  = $nopay_reference['days_factor'];
    
    return $nopay_reference_days_factor;
    
}

?>
