<?php

namespace App\Controllers;

use App\Controllers\BaseController;
use CodeIgniter\HTTP\ResponseInterface;

// Models
use App\Models\PayrollGroupModel;
use App\Models\IncomeDeductionModel;
use App\Models\PayrollTypeModel;
use App\Models\EmployeePayrollInfoModel;
use App\Models\EmployeeModel;
use App\Models\EmpPayIncomeDeductionModel;
use App\Models\SettingsModel;
use App\Models\PayrollScheduleModel;
use App\Models\PayrollTransactionModel;
use App\Models\EmployeePayTransactionModel;
use App\Models\EmpPayTransIncomeDeductionModel;
use App\Models\AttendanceSummaryModel;


// Entities
use App\Entities\PayrollGroup;
use App\Entities\IncomeDeduction;
use App\Entities\PayrollType;
use App\Entities\EmployeePayrollInfo;
use App\Entities\Employee;
use App\Entities\EmpPayIncomeDeduction;
use App\Entities\Settings;
use App\Entities\PayrollSchedule;
use App\Entities\PayrollTransaction;
use App\Entities\EmployeePayTransaction;
use App\Entities\EmpPayTransIncomeDeduction;
use App\Entities\AttendanceSummary;

// Class Library
use App\ClassLib\MiscLib;
use App\ClassLib\PayrollComputation;

class PayrollController extends BaseController
{
    public function index()
    {
        return redirect()->to(base_url('/login'));
    }

    // Internally used functions

    private function computeEmployeePayroll($emppaytransid, $save = false, $instanceOfEmpPayTransModel = null, $instanceOfEmpPayTransInDedModel = null)
    {
        if ($instanceOfEmpPayTransModel == null)
            $empPayTransModel = new EmployeePayTransactionModel();
        else
            $empPayTransModel = $instanceOfEmpPayTransModel;

        if ($instanceOfEmpPayTransInDedModel == null)
            $empPayTransInDedModel = new EmpPayTransIncomeDeductionModel();
        else
            $empPayTransInDedModel = $instanceOfEmpPayTransInDedModel;

        $empPayTrans = $empPayTransModel->find($emppaytransid);

        // Compute basic pay first
        // DAILY, SEMIMONTHLY, MONTHLY reference is in PayrollComputation
        switch ($empPayTrans->basic_sal_computation) {
            case 'DAILY':
                $empPayTrans->basic_pay = $empPayTrans->actual_work_days * $empPayTrans->basic_daily_pay;
                break;
            case 'SEMIMONTHLY':
                $empPayTrans->basic_pay = $empPayTrans->basic_semi_monthly_pay;
                break;
            case 'MONTHLY':
                $empPayTrans->basic_pay = $empPayTrans->basic_monthly_pay;
                break;
        }

        $empPayTrans->taxable_income = $empPayTransInDedModel->getTotalIncomeDeduction($emppaytransid, 1, 1) + $empPayTrans->basic_pay;
        $empPayTrans->nontaxable_income = $empPayTransInDedModel->getTotalIncomeDeduction($emppaytransid, 1, 0);
        $empPayTrans->taxable_deduction = $empPayTransInDedModel->getTotalIncomeDeduction($emppaytransid, 0, 1);
        $empPayTrans->nontaxable_deduction = $empPayTransInDedModel->getTotalIncomeDeduction($emppaytransid, 0, 0);

        // Compute gross first before getting taxable income to avoid misscalculation of net income
        $empPayTrans->gross_income = $empPayTrans->taxable_income + $empPayTrans->nontaxable_income;

        // Deduct SSS, Philhealth, Pagibig and Union Dues
        $empPayTrans->taxable_income -= $empPayTrans->nontaxable_deduction;

        // Compute Income Tax after getting taxable income
        $payCompute = new PayrollComputation();
        $empPayTrans->income_tax = $payCompute->computeIncomeTax($empPayTrans->taxable_income);

        // Deduction and net pay
        $empPayTrans->total_deduction = $empPayTrans->taxable_deduction + $empPayTrans->nontaxable_deduction + $empPayTrans->income_tax;
        $empPayTrans->net_pay = $empPayTrans->gross_income - $empPayTrans->total_deduction;

        if ($save)
            $empPayTransModel->save($empPayTrans);
    }

    private function printRaw($label, $data)
    {
        echo $label . ": ";
        print_r($data);
        echo "<br><br>";
    }


    // --end-- Internally used functions


    public function payrollGroup()
    {
        $payGroups = (new PayrollGroupModel())->findAll();

        $payGroupHTMLTable = new \CodeIgniter\View\Table();
        $payGroupHTMLTable->setTemplate(MiscLib::adminLTETableTemplate());

        if ($payGroups == null)
            $data['tblPayGroup'] = '<p>No groups found.</p>';
        else {
            $payGroupHTMLTable->setHeading('ID', 'Group Code', 'Group Name', 'Action');

            foreach ($payGroups as $group) {
                $iconView = '<a href="#" class="ml-3" data-toggle="tooltip" title="View Group Information"><i class="fas fa-eye "></i></a>';

                $payGroupHTMLTable->addRow($group->pay_group_id, $group->pay_group_code, $group->pay_group_name, "$iconView");
            }

            $data['tblPayGroup'] = $payGroupHTMLTable->generate();
        }

        return view('payroll/paygroupview', $data);
    }

    public function addPayrollGroup()
    {
        $payrollGroup = new PayrollGroup();
        $payrollGroupModel = new PayrollGroupModel();

        $rawData = $this->request->getPost();

        $payrollGroup->fill($rawData);
        $payrollGroupModel->save($payrollGroup);

        if ($payrollGroupModel->getInsertID() == 0)
            return redirect()->back()->withInput()->with('error', 'Failed to add payroll group');
        else
            return redirect()->to('/payroll/paygroup')->with('message', 'Payroll Group Added');
    }

    public function incomeDeduction()
    {
        $incomeDeductions = (new IncomeDeductionModel())->findAll();

        $inDedHTMLTable = new \CodeIgniter\View\Table();
        $inDedHTMLTable->setTemplate(MiscLib::adminLTEDataTable1Template("tblIncomeDeduction"));

        if ($incomeDeductions == null)
            $data['tblIncomeDeduction'] = '<p>No income and deduction found.</p>';
        else 
        {
            $inDedHTMLTable->setHeading('ID', 'Payslip Display', 'Deduction Name', 'Income', 'Taxable', 'Include in Gross', 'Action');

            foreach ($incomeDeductions as $incomeDeduction) {
                $indedHTMLData = 'data-inded_id="' . $incomeDeduction->inded_id .
                    '" data-payslip_display="' . $incomeDeduction->payslip_display .
                    '" data-inded_name="' . $incomeDeduction->inded_name .
                    '" data-coa_code="' . $incomeDeduction->coa_code .
                    '" data-is_income="' . $incomeDeduction->is_income .
                    '" data-is_taxable="' . $incomeDeduction->is_taxable .
                    '" data-include_in_gross="' . $incomeDeduction->include_in_gross . '"';

                $iconView = '<a href="/payroll/indedtransupdate/'.$incomeDeduction->inded_id.'" class="ml-3" data-toggle="tooltip" title="View Affected Transactions"><i class="fas fa-eye "></i></a>';
                $iconEdit = '<a href="#" class="ml-3" ' . $indedHTMLData . ' onclick="editIncomeDeduction(this)" data-toggle="tooltip" title="Edit Deduction Information"><i class="fas fa-edit"></i></a>';
                $iconDelete = '<a href="/payroll/delinded/'.$incomeDeduction->inded_id.'" onclick="return confirm(\'Are you sure you want to delete this Income or Deduction?\')" class="ml-3" data-toggle="tooltip" title="Delete Deduction Information"><i class="fas fa-trash"></i></a>';

                $inDedHTMLTable->addRow($incomeDeduction->inded_id, $incomeDeduction->payslip_display, $incomeDeduction->inded_name, ($incomeDeduction->is_income) ? 'Yes' : 'No', ($incomeDeduction->is_taxable) ? 'Yes' : 'No', ($incomeDeduction->include_in_gross) ? 'Yes' : 'No', $iconView . ' ' . $iconEdit . ' ' . $iconDelete);
            }

            $data['tblIncomeDeduction'] = $inDedHTMLTable->generate();
        }

        return view('payroll/incomedeductionview', $data);
    }

    public function saveIncomeDeduction()
    {
        $incomeDeduction = new IncomeDeduction();
        $incomeDeductionModel = new IncomeDeductionModel();

        $rawData = $this->request->getPost();

        // Handle checkbox inputs
        $rawData['is_income'] = isset($rawData['is_income']) ? 1 : 0; // Set to 1 if checked, 0 if not
        $rawData['is_taxable'] = isset($rawData['is_taxable']) ? 1 : 0; // Same for taxable
        $rawData['include_in_gross'] = isset($rawData['include_in_gross']) ? 1 : 0; // Same for include in gross

        $incomeDeduction->fill($rawData);

        if ($incomeDeductionModel->save($incomeDeduction)) 
        {
            if (isset($rawData['inded_id']))
                return redirect()->to('/payroll/inded')->with('message', 'Income or Deduction Successfully Updated');
            else
                return redirect()->to('/payroll/inded')->with('message', 'Income or Deduction Added');
        } 
        else
            return redirect()->back()->withInput()->with('error', 'Failed to add income or deduction');
    }

    public function incomeDeductionTransUpdate($indedid)
    {
        $empPayTransInDedModel = new EmpPayTransIncomeDeductionModel();

        $data['incomeDeduction'] = (new IncomeDeductionModel())->find($indedid);
        $data['empPayTransInDedCount'] = $empPayTransInDedModel->getEmpPayTransInDedCountxEmPayTransPayTransByInDedId($indedid);
        
        return view('payroll/incomedeductiontransupdateview', $data);
    }

    public function incomeDeductionTransApplyUpdate($indedid, $paytransid)
    {
        $empPayTransInDedModel = new EmpPayTransIncomeDeductionModel();

        $incomeDeduction = (new IncomeDeductionModel())->find($indedid);
        $empPayTransInDeds = $empPayTransInDedModel->getEmpPayTransInDedxEmPayTransByPayTransIdInDedId($paytransid, $indedid);

        $empPayTransIncomeDeduction = new EmpPayTransIncomeDeduction();

        $updateCount = 0;
        foreach($empPayTransInDeds as $empPayTransInDed)
        {
            $empPayTransIncomeDeduction->fill([
                'emppaytransinded_id' => $empPayTransInDed->emppaytransinded_id,
                'emppaytrans_id' => $empPayTransInDed->emppaytrans_id,
                'inded_id' => $empPayTransInDed->inded_id,
                'payslip_display' => $empPayTransInDed->payslip_display,
                'inded_name' => $empPayTransInDed->inded_name,
                'coa_code' => $incomeDeduction->coa_code,
                'is_income' => $incomeDeduction->is_income,
                'is_taxable' => $incomeDeduction->is_taxable,
                'include_in_gross' => $incomeDeduction->include_in_gross,
                'is_fixed_amt' => $empPayTransInDed->is_fixed_amt,
                'is_percent_amt' => $empPayTransInDed->is_percent_amt,
                'worked_days_based' => $empPayTransInDed->worked_days_based,
                'amount' => $empPayTransInDed->amount,
                'base_amount' => $empPayTransInDed->base_amount,
                'is_override' => $empPayTransInDed->is_override
            ]);

            if($empPayTransInDedModel->save($empPayTransInDed))
                $updateCount++;
        }

        return redirect()->back()->with('message', $updateCount . ' items in Income or Deduction was Successfully Updated');
    }

    public function deleteIncomeDeduction($indedid)
    {
        $incomeDeductionModel = new IncomeDeductionModel();

        if ($incomeDeductionModel->delete($indedid))
            return redirect()->back()->with('message', 'Income or Deduction Successfully Deleted');
        else
            return redirect()->back()->with('error', 'Failed to delete income or deduction');
    }

    public function payrollType()
    {
        $payrollTypes = (new PayrollTypeModel())->findAll();

        $payTypeHTMLTable = new \CodeIgniter\View\Table();
        $payTypeHTMLTable->setTemplate(MiscLib::adminLTETableTemplate());

        if ($payrollTypes == null)
            $data['tblPayrollType'] = '<p>No payroll type found.</p>';
        else {
            $payTypeHTMLTable->setHeading('ID', 'Code', 'Name', 'Monthly', 'Semi-Monthly', 'Daily', 'Hourly', 'Action');

            foreach ($payrollTypes as $payrollType) {
                $iconView = '<a href="#" class="ml-3" data-toggle="tooltip" title="View Information"><i class="fas fa-eye "></i></a>';

                $payTypeHTMLTable->addRow($payrollType->paytype_id, $payrollType->paytype_code, $payrollType->paytype_name, ($payrollType->is_monthly) ? 'Yes' : 'No', ($payrollType->is_semi_monthly) ? 'Yes' : 'No', ($payrollType->is_daily) ? 'Yes' : 'No', ($payrollType->is_hourly) ? 'Yes' : 'No', $iconView);
            }

            $data['tblPayrollType'] = $payTypeHTMLTable->generate();
        }

        return view('payroll/paytypeview', $data);
    }

    public function addPayrollType()
    {
        $payrollType = new PayrollType();
        $payrollTypeModel = new PayrollTypeModel();

        $rawData = $this->request->getPost();

        // Initialize all payroll type fields to 0
        $rawData['is_monthly'] = 0;
        $rawData['is_semi_monthly'] = 0;
        $rawData['is_daily'] = 0;
        $rawData['is_hourly'] = 0;

        // Handle radio button input
        if (isset($rawData['paytype_sched'])) {
            switch ($rawData['paytype_sched']) {
                case 'monthly':
                    $rawData['is_monthly'] = 1;
                    break;
                case 'semi_monthly':
                    $rawData['is_semi_monthly'] = 1;
                    break;
                case 'daily':
                    $rawData['is_daily'] = 1;
                    break;
                case 'hourly':
                    $rawData['is_hourly'] = 1;
                    break;
            }
        }

        $payrollType->fill($rawData);
        $payrollTypeModel->save($payrollType);

        if ($payrollTypeModel->getInsertID() == 0)
            return redirect()->back()->withInput()->with('error', 'Failed to add payroll type');
        else
            return redirect()->to('/payroll/paytype')->with('message', 'Payroll Type Added');
    }

    public function employeePayrollInfo()
    {
        $payCompute = new PayrollComputation();
        $empPayInfoModel = new EmployeePayrollInfoModel();
        $empPayInfos = $empPayInfoModel->getAllEmpPayInfoXEmpPayType();

        $data['employees'] = (new EmployeeModel())->findAll();
        $data['paytypes'] = (new PayrollTypeModel())->findAll();
        $data['workdaystype'] = $payCompute->workdays_type;
        $data['salarycomputations'] = $payCompute->basic_salary_computations;

        $empPayInfoHTMLTable = new \CodeIgniter\View\Table();
        $empPayInfoHTMLTable->setTemplate(MiscLib::adminLTEDataTable1Template("tblEmployeeInfo"));

        if ($empPayInfos == null)
            $data['tblEmpPayInfo'] = '<p>No employee payroll type found.</p>';
        else {
            $empPayInfoHTMLTable->setHeading('ID', 'Payroll Type', 'Employee ID', 'Employee Name', 'Monthly', 'Semi-Monthly', 'Daily', 'Hourly', 'Action');

            foreach ($empPayInfos as $empPayInfo) {
                $empayHTMLData = 'data-emppay_id="' . $empPayInfo->emppay_id .
                    '" data-employee_id="' . $empPayInfo->employee_id .
                    '" data-paytype_id="' . $empPayInfo->paytype_id .
                    '" data-is_atm="' . $empPayInfo->is_ATM .
                    '" data-savings_account="' . $empPayInfo->savings_account .
                    '" data-work_days="' . $empPayInfo->work_days .
                    '" data-basic_sal_computation="' . $empPayInfo->basic_sal_computation .
                    '" data-basic_monthly_pay="' . $empPayInfo->basic_monthly_pay .
                    '" data-basic_semi_monthly_pay="' . $empPayInfo->basic_semi_monthly_pay .
                    '" data-basic_daily_pay="' . $empPayInfo->basic_daily_pay .
                    '" data-basic_hourly_pay="' . $empPayInfo->basic_hourly_pay .
                    '" data-has_cola="' . $empPayInfo->has_cola .
                    '" data-has_philhealth="' . $empPayInfo->has_philhealth .
                    '" data-has_hdmf="' . $empPayInfo->has_hdmf .
                    '" data-has_sss="' . $empPayInfo->has_sss .
                    '" data-has_gsis="' . $empPayInfo->has_gsis .
                    '" data-company_issued_id="' . $empPayInfo->company_issued_id .
                    '" data-last_name="' . $empPayInfo->last_name .
                    '" data-first_name="' . $empPayInfo->first_name . '"';


                $iconView = '<a href="#" class="ml-3" data-toggle="tooltip" title="View Information"><i class="fas fa-eye "></i></a>';
                $iconEdit = '<a href="#" class="ml-3" ' . $empayHTMLData . ' onclick="editEmpPayInfo(this)" data-toggle="tooltip" title="Edit Information"><i class="fas fa-edit "></i></a>';
                $iconDelete = '<a href="/payroll/delempayinfo/' . $empPayInfo->emppay_id . '" onclick="return confirm(\'Are you sure you want to delete this employee?\')" class="ml-3" data-toggle="tooltip" title="Delete Information"><i class="fas fa-trash "></i></a>';

                $empPayInfoHTMLTable->addRow($empPayInfo->emppay_id, $empPayInfo->paytype_name, $empPayInfo->company_issued_id, $empPayInfo->last_name . ', ' . $empPayInfo->first_name, $empPayInfo->basic_monthly_pay, $empPayInfo->basic_semi_monthly_pay, $empPayInfo->basic_daily_pay, $empPayInfo->basic_hourly_pay, $iconView . " " . $iconEdit . " " . $iconDelete);
            }

            $data['tblEmpPayInfo'] = $empPayInfoHTMLTable->generate();
        }

        return view('payroll/empinfoview', $data);
    }

    public function saveEmployeePayrollInfo()
    {
        $empPayInfo = new EmployeePayrollInfo();
        $empPayInfoModel = new EmployeePayrollInfoModel();

        $rawData = $this->request->getPost();

        $rawData['is_ATM'] = isset($rawData['is_ATM']) ? 1 : 0;
        $rawData['has_cola'] = isset($rawData['has_cola']) ? 1 : 0;
        $rawData['has_philhealth'] = isset($rawData['has_philhealth']) ? 1 : 0;
        $rawData['has_hdmf'] = isset($rawData['has_hdmf']) ? 1 : 0;
        $rawData['has_sss'] = isset($rawData['has_sss']) ? 1 : 0;
        $rawData['has_gsis'] = isset($rawData['has_gsis']) ? 1 : 0;

        $empPayInfo->fill($rawData);

        if ($empPayInfoModel->save($empPayInfo)) {
            if (isset($rawData['emppay_id']))
                return redirect()->to('/payroll/emppayinfo')->with('message', 'Employee Payroll Successfully Updated');
            else
                return redirect()->to('/payroll/emppayinfo')->with('message', 'Employee Payroll Type Added');
        } else
            return redirect()->back()->withInput()->with('error', 'Failed to add employee payroll type');
    }

    public function deleteEmployeePayrollInfo($emppayid)
    {
        $empPayInfoModel = new EmployeePayrollInfoModel();

        if ($empPayInfoModel->delete($emppayid))
            return redirect()->back()->with('message', 'Employee Deleted on Payroll');
        else
            return redirect()->back()->with('error', 'Failed to delete employee on payroll');
    }

    public function employeeCompensationBenefits()
    {
        $empPayInfoModel = new EmployeePayrollInfoModel();
        $incomeDeductionModel = new IncomeDeductionModel();
        $empPayInDedModel = new EmpPayIncomeDeductionModel();

        $data['paySchedules'] = (new PayrollScheduleModel())->findAll();
        $data['incomeList'] = $incomeDeductionModel->where("is_income", 1)->findAll();
        $data['deductionList'] = $incomeDeductionModel->where("is_income", 0)->findAll();
        $data['empPayInfos'] = $empPayInfoModel->getAllEmpPayInfoXEmpPayType();
        $data['empLoaded'] = false;

        if ($this->request->getGet('empid') != null) {
            $settingsModel = new SettingsModel();

            $iconView = '<a href="#" class="ml-3" data-toggle="tooltip" title="View Employee Information" ><i class="fas fa-eye "></i></a>';
            $iconEdit = '<a href="#" class="ml-3" data-toggle="tooltip" title="Edit Employee Information" ><i class="fas fa-edit "></i></a>';
            $iconDelete = '<a href="#" class="ml-3" data-toggle="tooltip" title="Delete Employee Information"><i class="fas fa-trash "></i></a>';

            $data['empLoaded'] = true;
            $data['selectedEmployee'] = $empPayInfoModel->getEmpPayInfoXEmpPayTypeByEmpID($this->request->getGet('empid'));
            $data['empPayIncomeList'] = $empPayInDedModel->getEmpPayInDedByEmpPayIdSchedIdIsIncome($data['selectedEmployee']->emppay_id, $this->request->getGet('payschedid'), true);
            $data['empPayDeductionList'] = $empPayInDedModel->getEmpPayInDedByEmpPayIdSchedIdIsIncome($data['selectedEmployee']->emppay_id, $this->request->getGet('payschedid'), false);
        }

        return view('payroll/compensationbenefitsview', $data);
    }

    public function saveEmployeeCompensationBenefits()
    {
        $empPayInDed = new EmpPayIncomeDeduction();
        $empPayInDedModel = new EmpPayIncomeDeductionModel();

        $rawData = $this->request->getPost();

        // Initialize all payroll type fields to 0
        $rawData['is_fixed_amt'] = 0;
        $rawData['is_percent_amt'] = 0;
        $rawData['worked_days_based'] = 0;

        // Handle radio button input
        if (isset($rawData['amount_type'])) {
            switch ($rawData['amount_type']) {
                case 'fixed':
                    $rawData['is_fixed_amt'] = 1;
                    break;
                case 'perc':
                    $rawData['is_percent_amt'] = 1;
                    break;
                case 'daysbased':
                    $rawData['worked_days_based'] = 1;
                    break;
            }
        }

        $rawData['is_override'] = isset($rawData['is_override']) ? 1 : 0;

        $empPayInDed->fill($rawData);

        if ($empPayInDedModel->save($empPayInDed)) {
            if (isset($rawData['emppayinded_id']))
                return redirect()->to('/payroll/compben?payschedid=' . $this->request->getPost('payschedule_id') . '&empid=' . $this->request->getPost('emp_id'))->with('message', 'Employee Compensation Benefits edited');
            else
                return redirect()->to('/payroll/compben?payschedid=' . $this->request->getPost('payschedule_id') . '&empid=' . $this->request->getPost('emp_id'))->with('message', 'Employee Compensation Benefits Added');
        } else
            return redirect()->back()->withInput()->with('error', 'Failed to add employee compensation benefits');
    }

    public function deleteEmployeeCompensationBenefits()
    {
        $empPayInDedModel = new EmpPayIncomeDeductionModel();

        if ($empPayInDedModel->delete($this->request->getPost('emppayinded_id')))
            return redirect()->to('/payroll/compben?payschedid=' . $this->request->getPost('payschedule_id') . '&empid=' . $this->request->getPost('emp_id'))->with('message', 'Employee Compensation Benefits deleted');
        else
            return redirect()->back()->with('error', 'Failed to delete employee compensation benefits');
    }

    public function payrollSettings()
    {
        $incomeDeductionModel = new IncomeDeductionModel();
        $settingsModel = new SettingsModel();
        $settings = new Settings();

        if ($this->request->is('post')) {
            $settings->fill($this->request->getPost());
            $settingsModel->save($settings);
        }

        $data['indedList'] = $incomeDeductionModel->findAll();
        $data['basicSalVal'] = $settingsModel->where('key', 'BasicSalary')->first();
        $data['COLAVal'] = $settingsModel->where('key', 'COLA')->first();
        $data['PhilhealthVal'] = $settingsModel->where('key', 'Philhealth')->first();
        $data['HDMFVal'] = $settingsModel->where('key', 'HDMF')->first();
        $data['SSSVal'] = $settingsModel->where('key', 'SSS')->first();
        $data['GSISVal'] = $settingsModel->where('key', 'GSIS')->first();

        return view('payroll/paysettingsview', $data);
    }

    public function payrollTransactions()
    {
        $data['paytypes'] = (new PayrollTypeModel())->findAll();
        $data['paySchedules'] = (new PayrollScheduleModel())->findAll();

        $payTrans = (new PayrollTransactionModel())->orderBy('created_at', 'DESC')->findAll();

        $payTransHTMLTable = new \CodeIgniter\View\Table();
        $payTransHTMLTable->setTemplate(MiscLib::adminLTETableTemplate());

        if ($payTrans == null)
            $data['tblPayTrans'] = '<p>No transactions found.</p>';
        else {
            $payTransHTMLTable->setHeading('ID', 'From', 'To', 'No. of Days', 'Status', 'Remarks', 'Action');

            foreach ($payTrans as $trans) {
                $iconView = '<a href="/payroll/paytransreview/' . $trans->paytrans_id . '" class="ml-3" data-toggle="tooltip" title="View Payroll Transaction"><i class="fas fa-eye "></i></a>';
                $iconEdit = '<a href="/payroll/emppaytrans/' . $trans->paytrans_id . '" class="ml-3" data-toggle="tooltip" title="Edit Payroll Transaction"><i class="fas fa-edit"></i></a>';

                $payTransHTMLTable->addRow($trans->paytrans_id, $trans->payroll_from, $trans->payroll_to, $trans->no_of_days, $trans->is_open ? 'Open' : ' Closed', $trans->remarks, $iconView . ' ' . $iconEdit);
            }

            $data['tblPayTrans'] = $payTransHTMLTable->generate();
        }

        return view('payroll/paytransactionview', $data);
    }

    public function addPayrollTransactions()
    {
        $payTransModel = new PayrollTransactionModel();
        $payTrans = new PayrollTransaction();

        $rawData = $this->request->getPost();

        $payTrans->fill($rawData);

        if ($payTransModel->save($payTrans))
            return redirect()->to('/payroll/paytrans')->with('message', 'Payroll Transaction Added');
        else
            return redirect()->back()->withInput()->with('error', 'Failed to add payroll transaction');
    }

    public function employeePayrollTransactions($paytransid)
    {
        $incomeDeductionModel = new IncomeDeductionModel();

        $data['paygroupid'] = $this->request->getGet('grpid');

        // INIT, OPEN, CLOSED
        $data['transactionStatus'] = 'INIT';

        //$payTrans = (new PayrollTransactionModel())->where('paytrans_id', $paytransid)->first();
        $data['payTrans'] = (new PayrollTransactionModel())->find($paytransid);

        $data['paygroups'] = (new PayrollGroupModel())->findAll();
        $data['incomeList'] = $incomeDeductionModel->where("is_income", 1)->findAll();
        $data['deductionList'] = $incomeDeductionModel->where("is_income", 0)->findAll();

        $empPayTrans = (new EmployeePayTransactionModel())->getEmpPayTransByPayTransIdGroupId($paytransid, $data['paygroupid']);

        $empPayTransHTMLTable = new \CodeIgniter\View\Table();
        $empPayTransHTMLTable->setTemplate(MiscLib::adminLTETableTemplate());

        if ($empPayTrans == null) {
            $empPayTrans = (new EmployeePayrollInfoModel())->getEmpPayInfoXEmpPayTypeByPayGrpId($data['paygroupid'], $data['payTrans']->paytype_id);
            $attSummary = (new AttendanceSummaryModel())->where('paytrans_id', $paytransid)->findAll();

            $empPayTransHTMLTable->setHeading('ID', 'Company ID', 'Name', 'Branch', 'Daily Basic', 'Work Days');

            if ($empPayTrans != null) {
                $data['transactionStatus'] = 'INIT';

                foreach ($empPayTrans as $trans) {
                    $empAttSum = MiscLib::searchFromAsocArray('employee_id', $trans->employee_id, $attSummary);
                    $empPayTransHTMLTable->addRow($trans->employee_id, $trans->company_issued_id, $trans->last_name . ', ' . $trans->first_name, $trans->branch_code, $trans->basic_monthly_pay, ($empAttSum === null) ? 0 : $empAttSum->att_work_days);
                }

                $data['tblEmpPayTrans'] = $empPayTransHTMLTable->generate();
            } else
                $data['tblEmpPayTrans'] = '<p>No Employee Found on this Payroll Group</p>';
        } else {
            $data['transactionStatus'] = 'OPEN';

            $empPayTransHTMLTable->setHeading('ID', 'Name', 'Branch', 'Basic Salary', 'Days Work', 'Gross', 'Deduction', 'Net', 'Action');

            foreach ($empPayTrans as $trans) {
                //$iconView = '<a href="#" class="ml-3" data-toggle="tooltip" title="View Information" onclick="showEmpPayTransDetails('.$trans->emppaytrans_id.')"><i class="fas fa-eye "></i></a>';
                $iconCopy = '<a href="/payroll/emppaytransempreinitpay/' . $trans->emppaytrans_id . '/' . $trans->employee_id . '/' . $trans->paytype_id . '" class="ml-3" data-toggle="tooltip" title="Copy from Payroll Information" onclick="return confirm(\'This will copy payroll information to this record but income and deduction is not affected. Would you like to proceed?\')"><i class="fa fa-copy" aria-hidden="true"></i></a>';
                $iconEdit = '<a href="#" class="ml-3" data-toggle="tooltip" title="Edit Information" onclick="showEmpPayTransDetails(' . $trans->emppaytrans_id . ')"><i class="fas fa-edit "></i></a>';
                $iconDelete = '<a href="/payroll/emppaytransdel/' . $trans->emppaytrans_id . '" class="ml-3" data-toggle="tooltip" title="Delete Information" onclick="return confirm(\'Are you sure you want to delete this record?\')"><i class="fas fa-trash"></i></a>';

                $empPayTransHTMLTable->addRow($trans->employee_id, $trans->last_name . ', ' . $trans->first_name, $trans->branch_code, $trans->basic_pay, $trans->actual_work_days, $trans->gross_income, $trans->total_deduction, $trans->net_pay, $iconCopy . ' ' . $iconEdit . ' ' . $iconDelete);

                // Get Emp Trans In Ded
                $empPayTransInDedModel = new EmpPayTransIncomeDeductionModel();
                $data['emppaytrans'][] = [
                    "empPayTrans" => $trans,
                    "empPayTransInDedIncome" => $empPayTransInDedModel->where(["emppaytrans_id"=>$trans->emppaytrans_id, "is_income"=>true])->findAll(),
                    "empPayTransInDedDeduction" => $empPayTransInDedModel->where(["emppaytrans_id"=>$trans->emppaytrans_id, "is_income"=>false])->findAll()
                ];
            }

            $data['tblEmpPayTrans'] = $empPayTransHTMLTable->generate();
        }

        return view('payroll/emppaytransactionview', $data);
    }

    public function employeePayrollTransactionsViewEmpForInit($paytransid, $paygroupid)
    {
        $incomeDeductionModel = new IncomeDeductionModel();

        $data['payGroup'] = (new PayrollGroupModel())->find($paygroupid);
        $data['payTrans'] = (new PayrollTransactionModel())->find($paytransid);

        // INIT, OPEN, CLOSED
        $data['transactionStatus'] = 'INIT';

        $empPayTrans = (new EmployeePayTransactionModel())->getEmpPayTransByPayTransIdGroupId($paytransid, $paygroupid);
        $empPayInfos = (new EmployeePayrollInfoModel())->getEmpPayInfoXEmpPayTypeByPayGrpId($paygroupid, $data['payTrans']->paytype_id);

        $empPayTransHTMLTable = new \CodeIgniter\View\Table();
        $empPayTransHTMLTable->setTemplate(MiscLib::adminLTETableTemplate());

        $attSummary = (new AttendanceSummaryModel())->where('paytrans_id', $paytransid)->findAll();

        $empPayTransHTMLTable->setHeading('ID', 'Company ID', 'Name', 'Branch', 'Daily Basic', 'Work Days', 'Action');

        foreach ($empPayInfos as $empPayInfo) {
            $empAttSum = MiscLib::searchFromAsocArray('employee_id', $empPayInfo->employee_id, $attSummary);
            $empIsInEmpPayTrans = (MiscLib::searchFromAsocArray('employee_id', $empPayInfo->employee_id, $empPayTrans) == null) ? false : true;
            $empPayTransHTMLTable->addRow($empPayInfo->employee_id, $empPayInfo->company_issued_id, $empPayInfo->last_name . ', ' . $empPayInfo->first_name, $empPayInfo->branch_code, $empPayInfo->basic_monthly_pay, ($empAttSum === null) ? 0 : $empAttSum->att_work_days, ($empIsInEmpPayTrans) ? '<button type="button" class="btn btn-primary btn-sm" disabled>Already Initialized</button>' : '<a href="/payroll/emppaytransempinit/' . $data['payTrans']->paytrans_id . '/' . $empPayInfo->emppay_id . '" class="btn btn-warning btn-sm">Initialize</a>');
        }

        $data['tblEmpPayTrans'] = $empPayTransHTMLTable->generate();

        return view('payroll/emppaytransinitempview', $data);
    }

    public function employeePayrollTransactionsDeleteEmp($emppaytransid)
    {
        if((new EmployeePayTransactionModel())->delete($emppaytransid)) 
            return redirect()->back()->with('message', 'Employee Payroll Transaction Deleted');
        else
            return redirect()->back()->with('error', 'Employee Payroll Transaction Deletion Failed');
    }

    public function empPayTransFillArrayFromEmpPayInfo($paytransid, $empPayInfo, $empAttSum)
    {
        return [
            'paytrans_id' => $paytransid,
            'company_id' => $empPayInfo->company_id,
            'branch_code' => $empPayInfo->branch_code,
            'dept_id' => $empPayInfo->dept_id,
            'job_title_id' => $empPayInfo->job_title_id,
            'pay_group_id' => $empPayInfo->pay_group_id,
            'emp_status_id' => $empPayInfo->emp_status_id,
            'employee_id' => $empPayInfo->employee_id,
            'company_issued_id' => $empPayInfo->company_issued_id,
            'last_name' => $empPayInfo->last_name,
            'first_name' => $empPayInfo->first_name,
            'middle_name' => $empPayInfo->middle_name,
            'suffix' => $empPayInfo->suffix,
            'email_address' => $empPayInfo->email_address,
            'is_ATM' => $empPayInfo->is_ATM,
            'savings_account' => $empPayInfo->savings_account,
            'basic_sal_computation' => $empPayInfo->basic_sal_computation,
            'basic_monthly_pay' => $empPayInfo->basic_monthly_pay,
            'basic_semi_monthly_pay' => $empPayInfo->basic_semi_monthly_pay,
            'basic_daily_pay' => $empPayInfo->basic_daily_pay,
            'basic_hourly_pay' => $empPayInfo->basic_hourly_pay,
            'has_cola' => $empPayInfo->has_cola,
            'has_philhealth' => $empPayInfo->has_philhealth,
            'has_hdmf' => $empPayInfo->has_hdmf,
            'has_sss' => $empPayInfo->has_sss,
            'has_gsis' => $empPayInfo->has_gsis,
            'actual_work_days' => ($empAttSum === null) ? 0 : $empAttSum->att_work_days,
            'basic_pay' => 0,
            'gross_income' => 0,
            'taxable_income' => 0,
            'nontaxable_income' => 0,
            'income_tax' => 0,
            'total_deduction' => 0,
            'taxable_deduction' => 0,
            'nontaxable_deduction' => 0,
            'net_pay' => 0
        ];
    }

    public function empPayTransInDedFillArrayFromEmpPayInDed($emppaytransid, $empPayInDed, $amount)
    {
        return [
            'emppaytrans_id' => $emppaytransid,
            'inded_id' => $empPayInDed->inded_id,
            'payslip_display' => $empPayInDed->payslip_display,
            'inded_name' => $empPayInDed->inded_name,
            'coa_code' => $empPayInDed->coa_code,
            'is_income' => $empPayInDed->is_income,
            'is_taxable' => $empPayInDed->is_taxable,
            'include_in_gross' => $empPayInDed->include_in_gross,
            'is_fixed_amt' => $empPayInDed->is_fixed_amt,
            'is_percent_amt' => $empPayInDed->is_percent_amt,
            'worked_days_based' => $empPayInDed->worked_days_based,
            'amount' => $amount,
            'base_amount' => $empPayInDed->amount,
            'is_override' => $empPayInDed->is_override
        ];
    }

    public function empPayTransInitializePayroll($paytransid, $paygroupid, $transtypid)
    {
        $empPayInfos = (new EmployeePayrollInfoModel())->getEmpPayInfoXEmpPayTypeByPayGrpId($paygroupid, $transtypid);
        $attSummary = (new AttendanceSummaryModel())->where('paytrans_id', $paytransid)->findAll();
        $payTrans = (new PayrollTransactionModel())->find($paytransid);
        $empPayTransactionModel = new EmployeePayTransactionModel();

        foreach ($empPayInfos as $empPayInfo) {
            $empPayTransaction = new EmployeePayTransaction();
            $empAttSum = MiscLib::searchFromAsocArray('employee_id', $empPayInfo->employee_id, $attSummary);

            $empPayTransaction->fill($this->empPayTransFillArrayFromEmpPayInfo($paytransid, $empPayInfo, $empAttSum));

            $empPayTransactionModel->save($empPayTransaction);
            $empPayTransaction = $empPayTransactionModel->find($empPayTransactionModel->getInsertID());

            $empPayInDeds = (new EmpPayIncomeDeductionModel())->getEmpPayInDedByEmpPayIdSchedId($empPayInfo->emppay_id, $payTrans->payschedule_id);

            foreach ($empPayInDeds as $empPayInDed) {
                $empPayTransInDed = new EmpPayTransIncomeDeduction();
                $empPayTransInDedModel = new EmpPayTransIncomeDeductionModel();

                $payCompute = new PayrollComputation();
                $rawData = [
                    'amount' => $empPayInDed->amount,
                    'is_fixed_amt' => $empPayInDed->is_fixed_amt,
                    'is_percent_amt' => $empPayInDed->is_percent_amt,
                    'worked_days_based' => $empPayInDed->worked_days_based
                ];
                $amount = $payCompute->computeIncomeDeductionByComputationType($rawData, $empPayTransaction);

                $empPayTransInDed->fill($this->empPayTransInDedFillArrayFromEmpPayInDed($empPayTransaction->emppaytrans_id, $empPayInDed, $amount));

                $empPayTransInDedModel->save($empPayTransInDed);
            }

            $this->computeEmployeePayroll($empPayTransaction->emppaytrans_id, true);
        }

        return redirect()->back()->withInput()->with('message', 'Payroll processed. Please verify the entries.');
    }

    public function empPayTransInitializeEmpPayroll($paytransid, $emppayid)
    {
        $empPayTransactionModel = new EmployeePayTransactionModel();

        $empPayInfo = (new EmployeePayrollInfoModel())->getEmpPayInfoXEmpPayTypeByEmpPayId($emppayid);
        $payTrans = (new PayrollTransactionModel())->find($paytransid);
        $attSummary = (new AttendanceSummaryModel())->where('paytrans_id', $paytransid)->findAll();
        $empAttSum = MiscLib::searchFromAsocArray('employee_id', $empPayInfo->employee_id, $attSummary);

        $empPayTransaction = new EmployeePayTransaction();
        $empPayTransaction->fill($this->empPayTransFillArrayFromEmpPayInfo($paytransid, $empPayInfo, $empAttSum));

        $empPayTransactionModel->save($empPayTransaction);
        $empPayTransaction = $empPayTransactionModel->find($empPayTransactionModel->getInsertID());

        $empPayInDeds = (new EmpPayIncomeDeductionModel())->getEmpPayInDedByEmpPayIdSchedId($empPayInfo->emppay_id, $payTrans->payschedule_id);

        foreach ($empPayInDeds as $empPayInDed) {
            $empPayTransInDed = new EmpPayTransIncomeDeduction();
            $empPayTransInDedModel = new EmpPayTransIncomeDeductionModel();

            $payCompute = new PayrollComputation();
            $rawData = [
                'amount' => $empPayInDed->amount,
                'is_fixed_amt' => $empPayInDed->is_fixed_amt,
                'is_percent_amt' => $empPayInDed->is_percent_amt,
                'worked_days_based' => $empPayInDed->worked_days_based
            ];
            $amount = $payCompute->computeIncomeDeductionByComputationType($rawData, $empPayTransaction);

            $empPayTransInDed->fill($this->empPayTransInDedFillArrayFromEmpPayInDed($empPayTransaction->emppaytrans_id, $empPayInDed, $amount));

            $empPayTransInDedModel->save($empPayTransInDed);
        }

        $this->computeEmployeePayroll($empPayTransaction->emppaytrans_id, true);

        return redirect()->back()->withInput()->with('message', 'Payroll processed. Please verify the entries.');
    }

    public function empPayTransReInitEmpPayroll($emppaytransid, $employeeid, $paytypeid)
    {
        $empPayTransactionModel = new EmployeePayTransactionModel();

        $currentEmpPayTransaction = $empPayTransactionModel->find($emppaytransid);

        $empPayInfo = (new EmployeePayrollInfoModel())->where(['employee_id' => $employeeid, 'paytype_id' => $paytypeid])->first();

        if ($empPayInfo == null)
            return redirect()->back()->withInput()->with('error', 'Employee Payroll Information not found. Please check payroll information.');

        $attSummary = (new AttendanceSummaryModel())->where('paytrans_id', $currentEmpPayTransaction->paytrans_id)->findAll();
        $empAttSum = MiscLib::searchFromAsocArray('employee_id', $empPayInfo->employee_id, $attSummary);

        $empPayTransaction = new EmployeePayTransaction();
        $empPayTransaction->fill($this->empPayTransFillArrayFromEmpPayInfo($currentEmpPayTransaction->paytrans_id, $empPayInfo, $empAttSum));
        $empPayTransaction->emppaytrans_id = $emppaytransid;

        if ($empPayTransactionModel->save($empPayTransaction)) {
            $this->computeEmployeePayroll($emppaytransid, true);
            return redirect()->back()->withInput()->with('message', 'Payroll re-initialize. Please verify the entries.');
        } else
            return redirect()->back()->withInput()->with('error', 'Failed to re-initialize payroll.');
    }

    public function employeePayrollTransactionsEditDaysWorked()
    {
        $empPayTransModel = new EmployeePayTransactionModel();

        $rawData = $this->request->getPost();

        $empPayTransModel->changeActualDaysWorked($rawData['emppaytrans_id'], $rawData['actual_work_days']);
        $this->computeEmployeePayroll($rawData['emppaytrans_id'], true, $empPayTransModel);

        return redirect()->back()->withInput()->with('message', 'Days worked updated.');
    }

    public function employeePayrollTransactionsRecompute($emppaytransid)
    {
        $this->computeEmployeePayroll($emppaytransid, true);
        return redirect()->back()->with('message', 'Employee Payroll Recomputed');
    }

    public function saveEmpPayTransIncomeDeduction()
    {
        $empPayTransInDed = new EmpPayTransIncomeDeduction();
        $empPayTransInDedModel = new EmpPayTransIncomeDeductionModel();
        $empPayTransactionModel = new EmployeePayTransactionModel();
        $incomeDeductionModel = new IncomeDeductionModel();

        $rawData = $this->request->getPost();

        // Initialize all payroll type fields to 0
        $rawData['is_fixed_amt'] = 0;
        $rawData['is_percent_amt'] = 0;
        $rawData['worked_days_based'] = 0;

        // Handle radio button input
        if (isset($rawData['amount_type'])) {
            switch ($rawData['amount_type']) {
                case 'fixed':
                    $rawData['is_fixed_amt'] = 1;
                    break;
                case 'perc':
                    $rawData['is_percent_amt'] = 1;
                    break;
                case 'daysbased':
                    $rawData['worked_days_based'] = 1;
                    break;
            }
        }

        $rawData['is_override'] = isset($rawData['is_override']) ? 1 : 0;

        $empPayTrans = $empPayTransactionModel->find($rawData['emppaytrans_id']);
        $incomeDeduction = $incomeDeductionModel->find($rawData['inded_id']);

        //$amount = $rawData['is_fixed_amt'] ? $rawData['amount'] : ($rawData['amount'] / 100) * $empPayTrans->basic_pay;
        $payCompute = new PayrollComputation();
        $amount = $payCompute->computeIncomeDeductionByComputationType($rawData, $empPayTrans);

        $empPayTransInDed->fill([
            'emppaytransinded_id' => (isset($rawData['emppaytransinded_id'])) ? $rawData['emppaytransinded_id'] : null,
            'emppaytrans_id' => $rawData['emppaytrans_id'],
            'inded_id' => $rawData['inded_id'],
            'payslip_display' => $incomeDeduction->payslip_display,
            'inded_name' => $incomeDeduction->inded_name,
            'coa_code' => $incomeDeduction->coa_code,
            'is_income' => $incomeDeduction->is_income,
            'is_taxable' => $incomeDeduction->is_taxable,
            'include_in_gross' => $incomeDeduction->include_in_gross,
            'is_fixed_amt' => $rawData['is_fixed_amt'],
            'is_percent_amt' => $rawData['is_percent_amt'],
            'worked_days_based' => $rawData['worked_days_based'],
            'amount' => $amount,
            'base_amount' => $rawData['amount'],
            'is_override' => $rawData['is_override']
        ]);

        if ($empPayTransInDedModel->save($empPayTransInDed)) {
            $this->computeEmployeePayroll($rawData['emppaytrans_id'], true, $empPayTransactionModel, $empPayTransInDedModel);

            if (isset($rawData['emppaytransinded_id']))
                return redirect()->back()->with('message', 'Income or Deduction Updated');
            else
                return redirect()->back()->with('message', 'Income or Deduction Added');
        } else
            return redirect()->back()->withInput()->with('error', 'Failed to add income or deduction');
    }

    public function deleteEmpPayTransIncomeDeduction($emppaytransindedid, $emppaytransid)
    {
        $empPayTransInDedModel = new EmpPayTransIncomeDeductionModel();

        if ($empPayTransInDedModel->delete($emppaytransindedid)) {
            $this->computeEmployeePayroll($emppaytransid, true, null, $empPayTransInDedModel);
            return redirect()->back()->with('message', 'Income or Deduction Deleted');
        } else
            return redirect()->back()->with('error', 'Failed to delete income or deduction');
    }

    public function empPayTransReport($paytransid, $paygroupid)
    {
        $data['payTrans'] = (new PayrollTransactionModel())->find($paytransid);
        $data['payGroup'] = (new PayrollGroupModel())->find($paygroupid);

        $employeePayTransactionModel = new EmployeePayTransactionModel();
        $empPayTransInDeds = $employeePayTransactionModel->getEmpPayTransInDedByPayTransIdGroupId($paytransid, $paygroupid);
        $empPayTransactions = $employeePayTransactionModel->getEmpPayTransByPayTransIdGroupId($paytransid, $paygroupid);

        $empPayTransHTMLTable = new \CodeIgniter\View\Table();
        $empPayTransHTMLTable->setTemplate(MiscLib::adminLTEDataTableTemplate('tblEmpPayTransInDed'));

        //return view('payroll/emppaytransreportview', $data);

        $inDedList = []; //This is for the creation of the header
        foreach($empPayTransInDeds as $empPayTransInDed)
        {
            if(!in_array("[".$empPayTransInDed->inded_id."]".$empPayTransInDed->payslip_display, $inDedList))
                $inDedList[] = "[".$empPayTransInDed->inded_id."]".$empPayTransInDed->payslip_display;
        }

        $empInDedList = []; //This is for the content that will align with the header
        foreach($empPayTransInDeds as $empPayTransInDed)
        {
            if(isset($empInDedList[$empPayTransInDed->employee_id.':'.$empPayTransInDed->inded_id]))
                $empInDedList[$empPayTransInDed->employee_id.':'.$empPayTransInDed->inded_id] += $empPayTransInDed->amount;
            else
                $empInDedList[$empPayTransInDed->employee_id.':'.$empPayTransInDed->inded_id] = $empPayTransInDed->amount;
        }


        $HTMLHeadCols = [
            'ID', 
            'Last Name',
            'First Name', 
            'Branch', 
            'Daily Rate',
            'Work Days',
            'Monthly Basic', 
            'Income Tax'
        ];

        $HTMLTailCols = [ 
            'Gross Amt',
            'Deduction Amt',
            'Net Amt'
        ];
        $HTMLColumns = array_merge($HTMLHeadCols, $inDedList, $HTMLTailCols);
        $empPayTransHTMLTable->setHeading($HTMLColumns);

        foreach($empPayTransactions as $empPayTrans)
        {
            $HTMLColValues = [
                $empPayTrans->employee_id, 
                $empPayTrans->last_name,
                $empPayTrans->first_name,
                "[" . $empPayTrans->branch_code . "] " . $empPayTrans->branch_name, 
                $empPayTrans->basic_daily_pay,
                $empPayTrans->actual_work_days,
                $empPayTrans->basic_pay, 
                $empPayTrans->income_tax
            ];

            $HTMLTailColValues = [
                $empPayTrans->gross_income,
                $empPayTrans->total_deduction,
                $empPayTrans->net_pay
            ];

            foreach($inDedList as $inDedId)
            {
                // Extract Income Deduction ID from this string example --> [1] Allowance.
                preg_match_all('/\[(.*?)\]/', $inDedId, $matches);

                if(isset($empInDedList[$empPayTrans->employee_id.':'.$matches[1][0]]))
                    $HTMLColValues = array_merge($HTMLColValues, [$empInDedList[$empPayTrans->employee_id.':'.$matches[1][0]]]);
                else
                    $HTMLColValues = array_merge($HTMLColValues, ['0.00']);
            }

            $HTMLColValues = array_merge($HTMLColValues, $HTMLTailColValues);

            $empPayTransHTMLTable->addRow($HTMLColValues);
        }

        $data['tblEmpPayTransInDed'] = $empPayTransHTMLTable->generate();

        return view('payroll/emppaytransreportview', $data);
    }

    public function empPayslip($paytransid, $paygroupid)
    {
        $data['payTrans'] = (new PayrollTransactionModel())->find($paytransid);
        $data['payGroup'] = (new PayrollGroupModel())->find($paygroupid);

        $employeePayTransactionModel = new EmployeePayTransactionModel();
        $data['empPayTransInDeds'] = $employeePayTransactionModel->getEmpPayTransInDedByPayTransIdGroupId($paytransid, $paygroupid);
        $data['empPayTransactions'] = $employeePayTransactionModel->getEmpPayTransByPayTransIdGroupId($paytransid, $paygroupid);

        return view('payroll/emppayslipviewprint', $data);
    }

    public function payrollTransactionsReview($paytransid)
    {
        $data['paytransid'] = $paytransid;

        $payTransModel = new PayrollTransactionModel();
        $data['payTrans'] = $payTransModel->getPayTransXPayTypeXPaySchedByPayTransId($paytransid);

        $data['totalEmp'] = 0;
        $data['totalGross'] = 0;
        $data['totalDeduction'] = 0;
        $data['totalNet'] = 0;
        $data['totalSSSContri'] = 0;
        $data['totalPhilhealthContri'] = 0;
        $data['totalPagibigContri'] = 0;
        $data['totalTax'] = 0;

        return view('payroll/paytransactionreview', $data);
    }
}
