<?php
/**********************************************************************
***********************************************************************/
include_once($path_to_root . "/includes/date_functions.inc");
include_once($path_to_root . "/payroll/includes/salary_totals.inc");
include_once($path_to_root . "/payroll/includes/db/salary_totals_db.inc");
include_once($path_to_root . "/payroll/includes/salary_component_programs.inc");
include_once($path_to_root . "/payroll/includes/db/salary_component_programs_db.inc");
include_once($path_to_root . "/payroll/includes/db/loan_installments_db.inc");
include_once($path_to_root . "/admin/db/list_values_db.inc");
include_once($path_to_root . "/payroll/includes/db/salary_total_configuration_db.inc");
include_once($path_to_root . "/payroll/includes/db/salary_functions_details_db.inc");

include_once($path_to_root . "/payroll/includes/payroll_calculation/pc_attendance_allowances.inc");
include_once($path_to_root . "/payroll/includes/payroll_calculation/pc_components.inc");
include_once($path_to_root . "/payroll/includes/payroll_calculation/pc_employee_allowances_over_usage.inc");
include_once($path_to_root . "/payroll/includes/payroll_calculation/pc_functions.inc");
include_once($path_to_root . "/payroll/includes/payroll_calculation/pc_loan_installments.inc");
include_once($path_to_root . "/payroll/includes/payroll_calculation/pc_mobile_allowance_over_usage.inc");
include_once($path_to_root . "/payroll/includes/payroll_calculation/pc_nopay_deductions.inc");
include_once($path_to_root . "/payroll/includes/payroll_calculation/pc_ot.inc");
include_once($path_to_root . "/payroll/includes/payroll_calculation/pc_performance_incentives.inc");
include_once($path_to_root . "/payroll/includes/payroll_calculation/pc_rounding_off.inc");
include_once($path_to_root . "/payroll/includes/payroll_calculation/pc_salary_adjustments.inc");
include_once($path_to_root . "/payroll/includes/payroll_calculation/pc_worktime_deficits.inc");
include_once($path_to_root . "/payroll/includes/payroll_calculation/pc_salary_function_calculations.inc");


//$pcs = "";

/*
Calulation Run
===============
N New
U Updated
C Calculating
L Calculated
S Calculation Stopped

Processing Run
=============
P Processing
R Processed
T Processing Stopped

OT (attendance)
---------------
N - New
U - Updated
W - Awaiting approval
A - Approved
J - Rejected

L - Calculated //calculation run - OT_CALCULATIONS
D - Paid	//processing run - OT_CALCULATIONS
S - Selected	//calculation run - GET_OT_PAYMENTS
Y - Payroll	//processing run - GET_OT_PAYMENTS

Salary Advances (Salary Deductions)
-----------------------------------
N - New
U - Updated
A - Approved
J - Rejected
D - Paid

L - Calculated //calculation run
Y - Payroll	//processing run 
        
*/

$salary = array();

function calculate_payroll($payroll_run_id)
{
    global $salary;
    
    $payroll_run = get_payroll_run_details($payroll_run_id);
    
    $result = get_payroll_calculation_seq($payroll_run['payroll_id']);
    if(!db_num_rows($result) > 0){
        return array("passed" => false, "message" => _("No applicable components found in the payroll calculation sequence."));
    }
    while ($myrow = db_fetch($result)){
        $pcs[] = array('process_code' => $myrow['process_code'], 'process_type' => $myrow['process_type']);
    } 
    
    //$nopay_reference_code = "";
    $payroll_seetings = select_payroll_settings($payroll_run['payroll_id']);
    if($payroll_seetings == null){
        return array("passed" => false, "message" => _("Payroll settings not set."));
    }
    //$nopay_reference_code = $payroll_seetings['nopay_reference_code'];
    
    $last_completed_employee_code = get_last_completed_emloyee($payroll_run['id']);

    $employee = get_next_payroll_employee($last_completed_employee_code, $payroll_run);
    if($employee != null){
        $employee_code = $employee['employee_code'];
    }
    else{
        // if the last completed employee of the previous run is the final employee of the list, start from the beginning.
        if(strlen($last_completed_employee_code)> 0){
            $employee = get_next_payroll_employee('', $payroll_run);
            $employee_code = $employee['employee_code'];
        }
        else{
            return array("passed" => false, "message" => _("No next payroll employee found. Could not run payroll calculation"));
        }
    }
    
    update_payroll_run_status($payroll_run['id'], "C", true, false, true); // Calculating
    
//    delete_payroll_run_details($payroll_run['id']);
    
    if(strlen($last_completed_employee_code) > 0){
        delete_incomplete_payroll_run_details($payroll_run_id, $last_completed_employee_code);
        delete_payroll_component_summary($payroll_run_id);
		delete_payroll_departments_summary($payroll_run_id);
    }
    
    while (strlen($employee_code) > 0)
    {       
        $salary_elements_total = 0;
        $group_total = 0;
        $salary = '';
           
        $group_total_calculated_value = 0;
        $group_total_full_value = 0;
        
        $nopay_days = get_payroll_employee_total_nopay_days($employee_code, $payroll_run);
        
        $nopay_reference_days_factor = nopay_reference_days_factor($employee_code, $payroll_run);
        
        foreach ($pcs as $process){
                
//            if($employee_code == '0131'){
//                exit();
//            }
            
            switch ($process['process_type']) {
            case 'COMPANY_ADDITION_SALARY_COMP':
                    $values = get_salary_component_value(SCT_COMPANY_ADDITIONS, $process['process_code'], $employee, $payroll_run, $nopay_days, $nopay_reference_days_factor);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'COMPANY_DEDUCTION_SALARY_COMP':
                    $values = get_salary_component_value(SCT_COMPANY_DEDUCTIONS, $process['process_code'], $employee, $payroll_run, $nopay_days, $nopay_reference_days_factor);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'GROUP_ADDITION_SALARY_COMP':
                    $values = get_salary_component_value(SCT_GROUP_ADDITIONS, $process['process_code'], $employee, $payroll_run, $nopay_days, $nopay_reference_days_factor);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'GROUP_DEDUCTION_SALARY_COMP':
                    $values = get_salary_component_value(SCT_GROUP_DEDUCTIONS, $process['process_code'], $employee, $payroll_run, $nopay_days, $nopay_reference_days_factor);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'EMPLOYEE_ADDITION_SALARY_COMP':
                    $values = get_salary_component_value(SCT_EMPLOYEE_ADDITIONS, $process['process_code'], $employee, $payroll_run, $nopay_days, $nopay_reference_days_factor);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'EMPLOYEE_DEDUCTION_SALARY_COMP':
                    $values = get_salary_component_value(SCT_EMPLOYEE_DEDUCTIONS, $process['process_code'], $employee, $payroll_run, $nopay_days, $nopay_reference_days_factor);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'EMPLOYEE_ALLOWANCES_OVER_USAGE':
                    $values = get_employee_allawance_usage_value(SCT_ATTENDANCE_ALLOWANCES, $process['process_code'], $employee, $payroll_run, $nopay_days, $nopay_reference_days_factor);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'ATTENDANCE_ALLOWANCES':
                    $values = get_attendance_allowance_value(SCT_ATTENDANCE_ALLOWANCES, $process['process_code'], $employee, $payroll_run);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'WORKTIME_DEFICITS':
                    $values = get_worktime_deficit_deduction_value(SCT_WORKTIME_DEFICITS, $process['process_code'], $employee, $payroll_run);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'PERFORMANCE_RATE_INCENTIVES':
                    $values = get_performance_incentive_value(SCT_PERFORMANCE_RATE_INCENTIVES, $process['process_code'], $employee, $payroll_run, $nopay_days, $nopay_reference_days_factor);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'PERFORMANCE_VALUE_INCENTIVES':
                    $values = get_performance_incentive_value(SCT_PERFORMANCE_VALUE_INCENTIVES, $process['process_code'], $employee, $payroll_run, $nopay_days, $nopay_reference_days_factor);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'MOBILE_ALLOWANCES_OVER_USAGE':
                    $values = get_mobile_component_value(SCT_MOBILE_OVER_USAGE, $process['process_code'], $employee, $payroll_run, $nopay_days, $nopay_reference_days_factor);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'SALARY_ADVANCES':
                    $values = get_salary_advances_total($process['process_code'], $employee_code, $payroll_run);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'SALARY_DEDUCTIONS':
                    $values = get_salary_deductions_total($process['process_code'], $employee_code, $payroll_run);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'SALARY_ADDITIONS':
                    $values = get_salary_additions_total($process['process_code'], $employee_code, $payroll_run);
                    $group_total_calculated_value += $values['calculated_value'];
                    $group_total_full_value += $values['full_value'];
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    break;
            case 'SALARY_GROUP_TOTALS':
                    insert_payroll_run_detail($payroll_run['id'], $employee_code, $process['process_code'], $group_total_calculated_value);
                    $group_total_values = array('calculated_value' => $group_total_calculated_value,  'full_value' => $group_total_full_value);
                    add_to_salary_array($process['process_type'], $process['process_code'],$group_total_values);
                    $group_total_calculated_value = 0;
                    $group_total_full_value = 0;
                    break;
            case 'SALARY_TOTALS':
                    $values = get_salary_total_value($process['process_code'], $employee, $payroll_run, $nopay_days, $nopay_reference_days_factor);
                    add_to_salary_array($process['process_type'], $process['process_code'],$values);
                    $group_total_calculated_value = 0;
                    $group_total_full_value = 0;
                    break;
            case 'COMMON_PAYROLL_PROCESSES':
                    switch ($process['process_code']){;
                        case 'LOAN_INSTALLMENTS':
                            $values = get_loan_installments_total($process['process_code'], $employee_code, $payroll_run);
                            $group_total_calculated_value += $values['calculated_value'];
                            $group_total_full_value += $values['full_value'];
                            add_to_salary_array($process['process_type'], $process['process_code'],$values);
                            break;
                        case 'NO_PAY_DEDUCTIONS':
                            $values = get_nopay_deductions_total($process['process_code'], $employee_code, $payroll_run);
                            $group_total_calculated_value += $values['calculated_value'];
                            $group_total_full_value += $values['full_value'];
                            add_to_salary_array($process['process_type'], $process['process_code'],$values);
                            break;
//                        case 'WORKTIME_DEFICITS':
//                            $value = get_worktime_deficit_deductions_total($process['process_code'], $employee_code, $payroll_run, $nopay_reference_code);
//                            $salary_elements_total += $value;
//                            break;
                        case 'OT_CALCULATIONS':
                            $values = get_ot_calculation_total($process['process_code'], $employee_code, $payroll_run, true);
                            $group_total_calculated_value += $values['calculated_value'];
                            $group_total_full_value += $values['full_value'];
                            add_to_salary_array($process['process_type'], $process['process_code'],$values);
                            break;
                        case 'GET_OT_PAYMENTS':
                            $values = get_ot_payments_total($process['process_code'], $employee_code, $payroll_run);
                            $group_total_calculated_value += $values['calculated_value'];
                            $group_total_full_value += $values['full_value'];
                            add_to_salary_array($process['process_type'], $process['process_code'],$values);
                            break;
                        case 'ROUNDING_OFF':
                            $values = get_rounded_off_salary($process['process_code'], $employee_code, $payroll_run);
                            $group_total_calculated_value += $values['calculated_value'];
                            $group_total_full_value += $values['full_value'];
                            add_to_salary_array($process['process_type'], $process['process_code'],$values);
                            break;
                        default:
                    }
            default:
            }
        }
        
        $last_completed_employee_code = $employee_code;
        update_last_completed_employee_code($last_completed_employee_code, $payroll_run['id']);
        $employee = get_next_payroll_employee($last_completed_employee_code, $payroll_run);
        if($employee != null){
            $employee_code = $employee['employee_code'];
            //if(strlen($to_employee)> 0{
                // if($employee_code > $to_employee{
                // $calculate_component_totals = false
                // break;
            //}
        }
        else{
            $employee_code = '';
            //if(strlen($last_completed_employee_code)> 0{
            // $calculate_component_totals = true;
            //}
        }
//        break;
    }
    
    // if($calculate_component_totals){
    foreach ($pcs as $process){
        $com_total = select_component_total($payroll_run['id'], $process['process_code']);
        if($com_total){
            $component_total = $com_total['component_total'];
            if($component_total != 0){
                insert_payroll_run_detail($payroll_run['id'], '', $process['process_code'], $component_total);
            }
        }
    }
    //}
    
    update_last_completed_employee_code("", $payroll_run['id']);
    update_payroll_run_status($payroll_run['id'], "L", false, true, false); // Calculated
    
    return array("passed" => true, "message" => $payroll_run['id']);

}


function get_next_payroll_employee($last_employee_code, $payroll_run)
{
    $my_row = select_next_payroll_employee($last_employee_code, $payroll_run);
//    if($my_row == null){
//        return "";
//    }
    return $my_row;
}

function add_to_salary_array($process_type, $process_code, $values)
{
    global $salary;
    
    $element = array('type' => $process_type, 'component' => $process_code, 
                    'calculated_value' => $values['calculated_value'], 'full_value' => $values['full_value']);
    $salary[] = $element;
}



?>
