![]() Server : Apache/2.4.62 (Unix) OpenSSL/1.0.2k-fips System : Linux server1.richineiserver.com 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64 User : fdshops ( 1003) PHP Version : 8.2.21 Disable Function : NONE Directory : /home/fdshops/public_html/Modules/Essentials/Http/Controllers/ |
<?php namespace Modules\Essentials\Http\Controllers; use App\AccountTransaction; use App\BusinessLocation; use App\Category; use App\Events\TransactionPaymentAdded; use App\Transaction; use App\TransactionPayment; use App\User; use App\Utils\BusinessUtil; use App\Utils\ModuleUtil; use App\Utils\TransactionUtil; use App\Utils\Util; use DB; use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Routing\Controller; use Illuminate\Support\Facades\View; use Modules\Essentials\Entities\EssentialsAllowanceAndDeduction; use Modules\Essentials\Entities\EssentialsLeave; use Modules\Essentials\Entities\EssentialsUserSalesTarget; use Modules\Essentials\Entities\PayrollGroup; use Modules\Essentials\Notifications\PayrollNotification; use Modules\Essentials\Utils\EssentialsUtil; use Yajra\DataTables\Facades\DataTables; class PayrollController extends Controller { /** * All Utils instance. */ protected $moduleUtil; protected $essentialsUtil; protected $commonUtil; protected $transactionUtil; protected $businessUtil; /** * Constructor * * @param ProductUtils $product * @return void */ public function __construct(ModuleUtil $moduleUtil, EssentialsUtil $essentialsUtil, Util $commonUtil, TransactionUtil $transactionUtil, BusinessUtil $businessUtil) { $this->moduleUtil = $moduleUtil; $this->essentialsUtil = $essentialsUtil; $this->commonUtil = $commonUtil; $this->transactionUtil = $transactionUtil; $this->businessUtil = $businessUtil; } /** * Display a listing of the resource. * * @return Response */ public function index() { $business_id = request()->session()->get('user.business_id'); $can_view_all_payroll = auth()->user()->can('essentials.view_all_payroll'); if (! (auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module'))) { abort(403, 'Unauthorized action.'); } if (request()->ajax()) { $payrolls = $this->essentialsUtil->getPayrollQuery($business_id); if ($can_view_all_payroll) { if (! empty(request()->input('user_id'))) { $payrolls->where('transactions.expense_for', request()->input('user_id')); } if (! empty(request()->input('designation_id'))) { $payrolls->where('dsgn.id', request()->input('designation_id')); } if (! empty(request()->input('department_id'))) { $payrolls->where('dept.id', request()->input('department_id')); } } if (! $can_view_all_payroll) { $payrolls->where('transactions.expense_for', auth()->user()->id); } if (! empty(request()->input('location_id'))) { $payrolls->where('u.location_id', request()->input('location_id')); } $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $payrolls->where(function ($q) use ($permitted_locations) { $q->whereIn('epg.location_id', $permitted_locations) ->orWhereNull('epg.location_id'); }); } if (! empty(request()->month_year)) { $month_year_arr = explode('/', request()->month_year); if (count($month_year_arr) == 2) { $month = $month_year_arr[0]; $year = $month_year_arr[1]; $payrolls->whereDate('transaction_date', $year.'-'.$month.'-01'); } } return Datatables::of($payrolls) ->addColumn( 'action', function ($row) { $html = '<div class="btn-group"> <button type="button" class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-info tw-w-max dropdown-toggle" data-toggle="dropdown" aria-expanded="false">'. __('messages.actions'). '<span class="caret"></span><span class="sr-only">Toggle Dropdown </span> </button> <ul class="dropdown-menu dropdown-menu-right" role="menu">'; $html .= '<li><a href="#" data-href="'.action([\Modules\Essentials\Http\Controllers\PayrollController::class, 'show'], [$row->id]).'" data-container=".view_modal" class="btn-modal"><i class="fa fa-eye" aria-hidden="true"></i> '.__('messages.view').'</a></li>'; // $html .= '<li><a href="' . action([\App\Http\Controllers\TransactionPaymentController::class, 'show'], [$row->id]) . '" class="view_payment_modal"><i class="fa fa-money"></i> ' . __("purchase.view_payments") . '</a></li>'; if (empty($row->payroll_group_id) && $row->payment_status != 'paid' && auth()->user()->can('essentials.create_payroll')) { $html .= '<li><a href="'.action([\App\Http\Controllers\TransactionPaymentController::class, 'addPayment'], [$row->id]).'" class="add_payment_modal"><i class="fa fa-money"></i> '.__('purchase.add_payment').'</a></li>'; } $html .= '</ul></div>'; return $html; } ) ->addColumn('transaction_date', function ($row) { $transaction_date = \Carbon::parse($row->transaction_date); return $transaction_date->format('F Y'); }) ->editColumn('final_total', '<span class="display_currency" data-currency_symbol="true">{{$final_total}}</span>') ->filterColumn('user', function ($query, $keyword) { $query->whereRaw("CONCAT(COALESCE(u.surname, ''), ' ', COALESCE(u.first_name, ''), ' ', COALESCE(u.last_name, '')) like ?", ["%{$keyword}%"]); }) ->editColumn( 'payment_status', '<a href="{{ action([\App\Http\Controllers\TransactionPaymentController::class, \'show\'], [$id])}}" class="view_payment_modal payment-status-label no-print" data-orig-value="{{$payment_status}}" data-status-name="{{__(\'lang_v1.\' . $payment_status)}}"><span class="label @payment_status($payment_status)">{{__(\'lang_v1.\' . $payment_status)}} </span></a> <span class="print_section">{{__(\'lang_v1.\' . $payment_status)}}</span> ' ) ->removeColumn('id') ->rawColumns(['action', 'final_total', 'payment_status']) ->make(true); } $employees = []; if (auth()->user()->can('essentials.create_payroll')) { $employees = $this->__getEmployeesByLocation($business_id); } $departments = Category::forDropdown($business_id, 'hrm_department'); $designations = Category::forDropdown($business_id, 'hrm_designation'); $locations = BusinessLocation::forDropdown($business_id, true, false, true, true); return view('essentials::payroll.index')->with(compact('employees', 'departments', 'designations', 'locations')); } /** * Show the form for creating a new resource. * * @return Response */ public function create() { $business_id = request()->session()->get('user.business_id'); if (! (auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module')) && ! auth()->user()->can('essentials.create_payroll')) { abort(403, 'Unauthorized action.'); } $employee_ids = request()->input('employee_ids'); $month_year_arr = explode('/', request()->input('month_year')); $location_id = request()->get('primary_work_location'); $month = $month_year_arr[0]; $year = $month_year_arr[1]; $transaction_date = $year.'-'.$month.'-01'; //check if payrolls exists for the month year $payrolls = Transaction::where('business_id', $business_id) ->where('type', 'payroll') ->whereIn('expense_for', $employee_ids) ->whereDate('transaction_date', $transaction_date) ->get(); $add_payroll_for = array_diff($employee_ids, $payrolls->pluck('expense_for')->toArray()); if (! empty($add_payroll_for)) { $location = BusinessLocation::where('business_id', $business_id) ->find($location_id); //initialize required data $start_date = $transaction_date; $end_date = \Carbon::parse($start_date)->lastOfMonth(); $month_name = $end_date->format('F'); $employees = User::where('business_id', $business_id) ->find($add_payroll_for); $payrolls = []; foreach ($employees as $employee) { //get employee info $payrolls[$employee->id]['name'] = $employee->user_full_name; $payrolls[$employee->id]['essentials_salary'] = $employee->essentials_salary; $payrolls[$employee->id]['essentials_pay_period'] = $employee->essentials_pay_period; $payrolls[$employee->id]['total_leaves'] = $this->essentialsUtil->getTotalLeavesForGivenDateOfAnEmployee($business_id, $employee->id, $start_date, $end_date->format('Y-m-d')); $payrolls[$employee->id]['total_days_worked'] = $this->essentialsUtil->getTotalDaysWorkedForGivenDateOfAnEmployee($business_id, $employee->id, $start_date, $end_date); //get total work duration of employee(attendance) $payrolls[$employee->id]['total_work_duration'] = $this->essentialsUtil->getTotalWorkDuration('hour', $employee->id, $business_id, $start_date, $end_date->format('Y-m-d')); //get total earned commission for employee $business_details = $this->businessUtil->getDetails($business_id); $pos_settings = empty($business_details->pos_settings) ? $this->businessUtil->defaultPosSettings() : json_decode($business_details->pos_settings, true); $commsn_calculation_type = empty($pos_settings['cmmsn_calculation_type']) || $pos_settings['cmmsn_calculation_type'] == 'invoice_value' ? 'invoice_value' : $pos_settings['cmmsn_calculation_type']; $total_commission = 0; if ($commsn_calculation_type == 'payment_received') { $payment_details = $this->transactionUtil->getTotalPaymentWithCommission($business_id, $start_date, $end_date, null, $employee->id); //Get Commision $total_commission = $employee->cmmsn_percent * $payment_details['total_payment_with_commission'] / 100; } else { $sell_details = $this->transactionUtil->getTotalSellCommission($business_id, $start_date, $end_date, null, $employee->id); $total_commission = $employee->cmmsn_percent * $sell_details['total_sales_with_commission'] / 100; } if ($total_commission > 0) { $payrolls[$employee->id]['allowances']['allowance_names'][] = __('essentials::lang.sale_commission'); $payrolls[$employee->id]['allowances']['allowance_amounts'][] = $total_commission; $payrolls[$employee->id]['allowances']['allowance_types'][] = 'fixed'; $payrolls[$employee->id]['allowances']['allowance_percents'][] = 0; } $settings = $this->essentialsUtil->getEssentialsSettings(); //get total sales added by the employee $sale_totals = $this->transactionUtil->getUserTotalSales($business_id, $employee->id, $start_date, $end_date); $total_sales = ! empty($settings['calculate_sales_target_commission_without_tax']) && $settings['calculate_sales_target_commission_without_tax'] == 1 ? $sale_totals['total_sales_without_tax'] : $sale_totals['total_sales']; //get sales target if exists $sales_target = EssentialsUserSalesTarget::where('user_id', $employee->id) ->where('target_start', '<=', $total_sales) ->where('target_end', '>=', $total_sales) ->first(); $total_sales_target_commission_percent = ! empty($sales_target) ? $sales_target->commission_percent : 0; $total_sales_target_commission = $this->transactionUtil->calc_percentage($total_sales, $total_sales_target_commission_percent); if ($total_sales_target_commission > 0) { $payrolls[$employee->id]['allowances']['allowance_names'][] = __('essentials::lang.sales_target_commission'); $payrolls[$employee->id]['allowances']['allowance_amounts'][] = $total_sales_target_commission; $payrolls[$employee->id]['allowances']['allowance_types'][] = 'fixed'; $payrolls[$employee->id]['allowances']['allowance_percents'][] = 0; } //get earnings & deductions of employee $allowances_and_deductions = $this->essentialsUtil->getEmployeeAllowancesAndDeductions($business_id, $employee->id, $start_date, $end_date); foreach ($allowances_and_deductions as $ad) { if ($ad->type == 'allowance') { $payrolls[$employee->id]['allowances']['allowance_names'][] = $ad->description; $payrolls[$employee->id]['allowances']['allowance_amounts'][] = $ad->amount_type == 'fixed' ? $ad->amount : 0; $payrolls[$employee->id]['allowances']['allowance_types'][] = $ad->amount_type; $payrolls[$employee->id]['allowances']['allowance_percents'][] = $ad->amount_type == 'percent' ? $ad->amount : 0; } else { $payrolls[$employee->id]['deductions']['deduction_names'][] = $ad->description; $payrolls[$employee->id]['deductions']['deduction_amounts'][] = $ad->amount_type == 'fixed' ? $ad->amount : 0; $payrolls[$employee->id]['deductions']['deduction_types'][] = $ad->amount_type; $payrolls[$employee->id]['deductions']['deduction_percents'][] = $ad->amount_type == 'percent' ? $ad->amount : 0; } } } $action = 'create'; return view('essentials::payroll.create') ->with(compact('month_name', 'transaction_date', 'year', 'payrolls', 'action', 'location')); } else { return redirect()->action([\Modules\Essentials\Http\Controllers\PayrollController::class, 'index']) ->with('status', [ 'success' => true, 'msg' => __('essentials::lang.payroll_already_added_for_given_user'), ] ); } } /** * Store a newly created resource in storage. * * @param Request $request * @return Response */ public function store(Request $request) { $business_id = request()->session()->get('user.business_id'); if (! (auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module')) && ! auth()->user()->can('essentials.create_payroll')) { abort(403, 'Unauthorized action.'); } try { $transaction_date = $request->input('transaction_date'); $payrolls = $request->input('payrolls'); $notify_employee = ! empty($request->input('notify_employee')) ? 1 : 0; $payroll_group['business_id'] = $business_id; $payroll_group['name'] = $request->input('payroll_group_name'); $payroll_group['status'] = $request->input('payroll_group_status'); $payroll_group['gross_total'] = $this->transactionUtil->num_uf($request->input('total_gross_amount')); $payroll_group['location_id'] = $request->input('location_id'); $payroll_group['created_by'] = auth()->user()->id; DB::beginTransaction(); $payroll_group = PayrollGroup::create($payroll_group); $transaction_ids = []; foreach ($payrolls as $key => $payroll) { $payroll['transaction_date'] = $transaction_date; $payroll['business_id'] = $business_id; $payroll['created_by'] = auth()->user()->id; $payroll['type'] = 'payroll'; $payroll['payment_status'] = 'due'; $payroll['status'] = 'final'; $payroll['total_before_tax'] = $payroll['final_total']; $payroll['essentials_amount_per_unit_duration'] = $this->moduleUtil->num_uf($payroll['essentials_amount_per_unit_duration']); $allowances_and_deductions = $this->getAllowanceAndDeductionJson($payroll); $payroll['essentials_allowances'] = $allowances_and_deductions['essentials_allowances']; $payroll['essentials_deductions'] = $allowances_and_deductions['essentials_deductions']; //Update reference count $ref_count = $this->moduleUtil->setAndGetReferenceCount('payroll'); //Generate reference number if (empty($payroll['ref_no'])) { $settings = request()->session()->get('business.essentials_settings'); $settings = ! empty($settings) ? json_decode($settings, true) : []; $prefix = ! empty($settings['payroll_ref_no_prefix']) ? $settings['payroll_ref_no_prefix'] : ''; $payroll['ref_no'] = $this->moduleUtil->generateReferenceNumber('payroll', $ref_count, null, $prefix); } unset($payroll['allowance_names'], $payroll['allowance_types'], $payroll['allowance_percent'], $payroll['allowance_amounts'], $payroll['deduction_names'], $payroll['deduction_types'], $payroll['deduction_percent'], $payroll['deduction_amounts'], $payroll['total']); $transaction = Transaction::create($payroll); $transaction_ids[] = $transaction->id; if ($notify_employee && $payroll_group->status == 'final') { $transaction->action = 'created'; $transaction->transaction_for->notify(new PayrollNotification($transaction)); } } $payroll_group->payrollGroupTransactions()->sync($transaction_ids); DB::commit(); $output = ['success' => true, 'msg' => __('lang_v1.added_success'), ]; } catch (\Exception $e) { DB::rollBack(); \Log::emergency('File:'.$e->getFile().'Line:'.$e->getLine().'Message:'.$e->getMessage()); $output = ['success' => false, 'msg' => __('messages.something_went_wrong'), ]; } return redirect()->action([\Modules\Essentials\Http\Controllers\PayrollController::class, 'index'])->with('status', $output); } private function getAllowanceAndDeductionJson($payroll) { $allowance_names = $payroll['allowance_names']; $allowance_types = $payroll['allowance_types']; $allowance_percents = $payroll['allowance_percent']; $allowance_names_array = []; $allowance_percent_array = []; $allowance_amounts = []; foreach ($payroll['allowance_amounts'] as $key => $value) { if (! empty($allowance_names[$key])) { $allowance_amounts[] = $this->moduleUtil->num_uf($value); $allowance_names_array[] = $allowance_names[$key]; $allowance_percent_array[] = ! empty($allowance_percents[$key]) ? $this->moduleUtil->num_uf($allowance_percents[$key]) : 0; } } $deduction_names = $payroll['deduction_names']; $deduction_types = $payroll['deduction_types']; $deduction_percents = $payroll['deduction_percent']; $deduction_names_array = []; $deduction_percents_array = []; $deduction_amounts = []; foreach ($payroll['deduction_amounts'] as $key => $value) { if (! empty($deduction_names[$key])) { $deduction_names_array[] = $deduction_names[$key]; $deduction_amounts[] = $this->moduleUtil->num_uf($value); $deduction_percents_array[] = ! empty($deduction_percents[$key]) ? $this->moduleUtil->num_uf($deduction_percents[$key]) : 0; } } $output['essentials_allowances'] = json_encode([ 'allowance_names' => $allowance_names_array, 'allowance_amounts' => $allowance_amounts, 'allowance_types' => $allowance_types, 'allowance_percents' => $allowance_percent_array, ]); $output['essentials_deductions'] = json_encode([ 'deduction_names' => $deduction_names_array, 'deduction_amounts' => $deduction_amounts, 'deduction_types' => $deduction_types, 'deduction_percents' => $deduction_percents_array, ]); return $output; } /** * Show the specified resource. * * @return Response */ public function show($id) { $business_id = request()->session()->get('user.business_id'); if (! (auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module'))) { abort(403, 'Unauthorized action.'); } $query = Transaction::where('business_id', $business_id) ->with(['transaction_for', 'payment_lines']); if (! auth()->user()->can('essentials.view_all_payroll')) { $query->where('expense_for', auth()->user()->id); } $payroll = $query->findOrFail($id); $transaction_date = \Carbon::parse($payroll->transaction_date); $department = Category::where('category_type', 'hrm_department') ->find($payroll->transaction_for->essentials_department_id); $designation = Category::where('category_type', 'hrm_designation') ->find($payroll->transaction_for->essentials_designation_id); $location = BusinessLocation::where('business_id', $business_id) ->find($payroll->transaction_for->location_id); $month_name = $transaction_date->format('F'); $year = $transaction_date->format('Y'); $allowances = ! empty($payroll->essentials_allowances) ? json_decode($payroll->essentials_allowances, true) : []; $deductions = ! empty($payroll->essentials_deductions) ? json_decode($payroll->essentials_deductions, true) : []; $bank_details = json_decode($payroll->transaction_for->bank_details, true); $payment_types = $this->moduleUtil->payment_types(); $final_total_in_words = $this->commonUtil->numToIndianFormat($payroll->final_total); $start_of_month = \Carbon::parse($payroll->transaction_date); $end_of_month = \Carbon::parse($payroll->transaction_date)->endOfMonth(); $leaves = EssentialsLeave::where('business_id', $business_id) ->where('user_id', $payroll->transaction_for->id) ->whereDate('start_date', '>=', $start_of_month) ->whereDate('end_date', '<=', $end_of_month) ->get(); $total_leaves = 0; $days_in_a_month = \Carbon::parse($start_of_month)->daysInMonth; foreach ($leaves as $key => $leave) { $start_date = \Carbon::parse($leave->start_date); $end_date = \Carbon::parse($leave->end_date); $diff = $start_date->diffInDays($end_date); $diff += 1; $total_leaves += $diff; } $total_days_present = $this->essentialsUtil->getTotalDaysWorkedForGivenDateOfAnEmployee( $business_id, $payroll->transaction_for->id, $start_of_month->format('Y-m-d'), $end_of_month->format('Y-m-d') ); $total_work_duration = $this->essentialsUtil->getTotalWorkDuration('hour', $payroll->transaction_for->id, $business_id, $start_of_month->format('Y-m-d'), $end_of_month->format('Y-m-d')); return view('essentials::payroll.show') ->with(compact('payroll', 'month_name', 'allowances', 'deductions', 'year', 'payment_types', 'bank_details', 'designation', 'department', 'final_total_in_words', 'total_leaves', 'days_in_a_month', 'total_work_duration', 'location', 'total_days_present')); } /** * Show the form for editing the specified resource. * * @return Response */ public function edit($id) { $business_id = request()->session()->get('user.business_id'); if (! (auth()->user()->can('superadmin') || ! $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module')) && ! auth()->user()->can('essentials.update_payroll')) { abort(403, 'Unauthorized action.'); } $payroll = Transaction::where('business_id', $business_id) ->with(['transaction_for']) ->where('type', 'payroll') ->findOrFail($id); $transaction_date = \Carbon::parse($payroll->transaction_date); $month_name = $transaction_date->format('F'); $year = $transaction_date->format('Y'); $allowances = ! empty($payroll->essentials_allowances) ? json_decode($payroll->essentials_allowances, true) : []; $deductions = ! empty($payroll->essentials_deductions) ? json_decode($payroll->essentials_deductions, true) : []; return view('essentials::payroll.edit')->with(compact('payroll', 'month_name', 'allowances', 'deductions', 'year')); } /** * Update the specified resource in storage. * * @param Request $request * @return Response */ public function update(Request $request, $id) { $business_id = request()->session()->get('user.business_id'); if (! (auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module')) && ! auth()->user()->can('essentials.update_payroll')) { abort(403, 'Unauthorized action.'); } try { $input = $request->only(['essentials_duration', 'essentials_amount_per_unit_duration', 'final_total', 'essentials_duration_unit']); $input['essentials_amount_per_unit_duration'] = $this->moduleUtil->num_uf($input['essentials_amount_per_unit_duration']); $input['total_before_tax'] = $input['final_total']; //get pay componentes $payroll['allowance_names'] = $request->input('allowance_names'); $payroll['allowance_types'] = $request->input('allowance_types'); $payroll['allowance_percent'] = $request->input('allowance_percent'); $payroll['allowance_amounts'] = $request->input('allowance_amounts'); $payroll['deduction_names'] = $request->input('deduction_names'); $payroll['deduction_types'] = $request->input('deduction_types'); $payroll['deduction_percent'] = $request->input('deduction_percent'); $payroll['deduction_amounts'] = $request->input('deduction_amounts'); $payroll['final_total'] = $request->input('final_total'); $allowances_and_deductions = $this->getAllowanceAndDeductionJson($payroll); $input['essentials_allowances'] = $allowances_and_deductions['essentials_allowances']; $input['essentials_deductions'] = $allowances_and_deductions['essentials_deductions']; DB::beginTransaction(); $payroll = Transaction::where('business_id', $business_id) ->where('type', 'payroll') ->findOrFail($id); $payroll->update($input); $payroll->action = 'updated'; $payroll->transaction_for->notify(new PayrollNotification($payroll)); $output = ['success' => true, 'msg' => __('lang_v1.updated_success'), ]; DB::commit(); } catch (\Exception $e) { DB::rollBack(); \Log::emergency('File:'.$e->getFile().'Line:'.$e->getLine().'Message:'.$e->getMessage()); $output = ['success' => false, 'msg' => __('messages.something_went_wrong'), ]; } return redirect()->action([\Modules\Essentials\Http\Controllers\PayrollController::class, 'index'])->with('status', $output); } /** * Remove the specified resource from storage. * * @return Response */ public function destroy($id) { $business_id = request()->session()->get('user.business_id'); if (! (auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module')) && ! auth()->user()->can('essentials.delete_payroll')) { abort(403, 'Unauthorized action.'); } if (request()->ajax()) { try { $payroll_group = PayrollGroup::where('business_id', $business_id) ->with(['payrollGroupTransactions']) ->findOrFail($id); DB::beginTransaction(); if ($payroll_group->status == 'draft') { $transaction_ids = $payroll_group->payrollGroupTransactions->pluck('id')->toArray(); //delete all account tranactions AccountTransaction::whereIn('transaction_id', $transaction_ids)->delete(); //delete all transaction payments TransactionPayment::whereIn('transaction_id', $transaction_ids)->delete(); $payroll_group->payrollGroupTransactions()->delete(); $payroll_group->delete(); } DB::commit(); $output = ['success' => true, 'msg' => __('lang_v1.deleted_success'), ]; } catch (\Exception $e) { DB::rollBack(); \Log::emergency('File:'.$e->getFile().'Line:'.$e->getLine().'Message:'.$e->getMessage()); $output = ['success' => false, 'msg' => __('messages.something_went_wrong'), ]; } return $output; } } public function getAllowanceAndDeductionRow(Request $request) { if ($request->ajax()) { $employee = $request->input('employee_id'); $type = $request->input('type'); $ad_row = view('essentials::payroll.allowance_and_deduction_row') ->with(compact('type', 'employee')) ->render(); return $ad_row; } } public function payrollGroupDatatable(Request $request) { $business_id = request()->session()->get('user.business_id'); $is_admin = $this->moduleUtil->is_admin(auth()->user(), $business_id); if (! (auth()->user()->can('superadmin') || $is_admin || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module'))) { abort(403, 'Unauthorized action.'); } if ($request->ajax()) { $payroll_groups = PayrollGroup::where('essentials_payroll_groups.business_id', $business_id) ->join('users as u', 'u.id', '=', 'essentials_payroll_groups.created_by') ->leftJoin('business_locations as BL', 'essentials_payroll_groups.location_id', '=', 'BL.id') ->select('essentials_payroll_groups.id as id', 'essentials_payroll_groups.name as name', 'essentials_payroll_groups.status as status', 'essentials_payroll_groups.created_at as created_at', DB::raw("CONCAT(COALESCE(u.surname, ''), ' ', COALESCE(u.first_name, ''), ' ', COALESCE(u.last_name, '')) as added_by"), 'essentials_payroll_groups.payment_status as payment_status', 'essentials_payroll_groups.gross_total as gross_total', 'BL.name as location_name' ); $permitted_locations = auth()->user()->permitted_locations(); if ($permitted_locations != 'all') { $payroll_groups->where(function ($q) use ($permitted_locations) { $q->whereIn('essentials_payroll_groups.location_id', $permitted_locations) ->orWhereNull('essentials_payroll_groups.location_id'); }); } return Datatables::of($payroll_groups) ->addColumn( 'action', function ($row) { $html = '<div class="btn-group"> <button type="button" class="tw-dw-btn tw-dw-btn-xs tw-dw-btn-outline tw-dw-btn-info tw-w-max dropdown-toggle" data-toggle="dropdown" aria-expanded="false">'. __('messages.actions'). '<span class="caret"></span><span class="sr-only">Toggle Dropdown </span> </button> <ul class="dropdown-menu dropdown-menu-right" role="menu">'; $html .= '<li> <a href="'.action([\Modules\Essentials\Http\Controllers\PayrollController::class, 'viewPayrollGroup'], [$row->id]).'" target="_blank"> <i class="fa fa-eye" aria-hidden="true"></i> ' .__('messages.view'). '</a> </li>'; if (auth()->user()->can('essentials.update_payroll')) { $html .= '<li> <a href="'.action([\Modules\Essentials\Http\Controllers\PayrollController::class, 'getEditPayrollGroup'], [$row->id]).'" target="_blank"> <i class="fas fa-edit" aria-hidden="true"></i> ' .__('messages.edit'). '</a> </li>'; } if (auth()->user()->can('essentials.delete_payroll') && $row->status == 'draft') { $html .= '<li><a href="'.action([\Modules\Essentials\Http\Controllers\PayrollController::class, 'destroy'], [$row->id]).'" class="delete-payroll"><i class="fa fa-trash" aria-hidden="true"></i> '.__('messages.delete').'</a></li>'; } if ($row->status == 'final' && $row->payment_status != 'paid') { $html .= '<li> <a href="'.action([\Modules\Essentials\Http\Controllers\PayrollController::class, 'addPayment'], [$row->id]).'" target="_blank"> <i class="fas fa-money-check" aria-hidden="true"></i> ' .__('purchase.add_payment'). '</a> </li>'; } $html .= '</ul></div>'; return $html; } ) ->editColumn('status', ' @lang("sale.".$status) ') ->editColumn('created_at', ' {{@format_datetime($created_at)}} ') ->editColumn('gross_total', ' @format_currency($gross_total) ') ->editColumn('location_name', ' @if(!empty($location_name)) {{$location_name}} @else {{__("report.all_locations")}} @endif ') ->editColumn( 'payment_status', '<span class="label @payment_status($payment_status)">{{__(\'lang_v1.\' . $payment_status)}} </span> ' ) ->filterColumn('added_by', function ($query, $keyword) { $query->whereRaw("CONCAT(COALESCE(u.surname, ''), ' ', COALESCE(u.first_name, ''), ' ', COALESCE(u.last_name, '')) like ?", ["%{$keyword}%"]); }) ->removeColumn('id') ->rawColumns(['action', 'added_by', 'created_at', 'status', 'gross_total', 'payment_status', 'location_name']) ->make(true); } } public function viewPayrollGroup($id) { $business_id = request()->session()->get('user.business_id'); $is_admin = $this->moduleUtil->is_admin(auth()->user(), $business_id); if (! (auth()->user()->can('superadmin') || $is_admin || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module'))) { abort(403, 'Unauthorized action.'); } $payroll_group = PayrollGroup::where('business_id', $business_id) ->with(['payrollGroupTransactions', 'payrollGroupTransactions.transaction_for', 'businessLocation', 'business']) ->findOrFail($id); $payrolls = []; $month_name = null; $year = null; foreach ($payroll_group->payrollGroupTransactions as $transaction) { //payroll info if (empty($month_name) && empty($year)) { $transaction_date = \Carbon::parse($transaction->transaction_date); $month_name = $transaction_date->format('F'); $year = $transaction_date->format('Y'); } //transaction info $payrolls[$transaction->expense_for]['transaction_id'] = $transaction->id; $payrolls[$transaction->expense_for]['final_total'] = $transaction->final_total; $payrolls[$transaction->expense_for]['payment_status'] = $transaction->payment_status; //get employee info $payrolls[$transaction->expense_for]['employee'] = $transaction->transaction_for->user_full_name; $payrolls[$transaction->expense_for]['bank_details'] = json_decode($transaction->transaction_for->bank_details, true); } return view('essentials::payroll.view_payroll_group') ->with(compact('payroll_group', 'month_name', 'year', 'payrolls')); } public function getEditPayrollGroup($id) { $business_id = request()->session()->get('user.business_id'); if (! (auth()->user()->can('superadmin') || auth()->user()->can('essentials.update_payroll') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module'))) { abort(403, 'Unauthorized action.'); } $payroll_group = PayrollGroup::where('business_id', $business_id) ->with(['payrollGroupTransactions', 'payrollGroupTransactions.transaction_for', 'businessLocation']) ->findOrFail($id); //payroll location $location = $payroll_group->businessLocation; $payrolls = []; $transaction_date = null; $month_name = null; $year = null; foreach ($payroll_group->payrollGroupTransactions as $transaction) { //payroll info if (empty($transaction_date) && empty($month_name) && empty($year)) { $transaction_date = \Carbon::parse($transaction->transaction_date); $month_name = $transaction_date->format('F'); $year = $transaction_date->format('Y'); $start_date = \Carbon::parse($transaction->transaction_date); $end_date = \Carbon::parse($start_date)->lastOfMonth(); } //transaction info $payrolls[$transaction->expense_for]['transaction_id'] = $transaction->id; //get employee info $payrolls[$transaction->expense_for]['name'] = $transaction->transaction_for->user_full_name ?? ''; $payrolls[$transaction->expense_for]['staff_note'] = $transaction->staff_note; $payrolls[$transaction->expense_for]['essentials_amount_per_unit_duration'] = $transaction->essentials_amount_per_unit_duration; $payrolls[$transaction->expense_for]['essentials_duration'] = $transaction->essentials_duration; $payrolls[$transaction->expense_for]['essentials_duration_unit'] = $transaction->essentials_duration_unit; $payrolls[$transaction->expense_for]['total_leaves'] = $this->essentialsUtil->getTotalLeavesForGivenDateOfAnEmployee($business_id, $transaction->expense_for, $start_date->format('Y-m-d'), $end_date->format('Y-m-d')); $payrolls[$transaction->expense_for]['total_days_worked'] = $this->essentialsUtil->getTotalDaysWorkedForGivenDateOfAnEmployee($business_id, $transaction->expense_for, $start_date, $end_date); //get total work duration of employee(attendance) $payrolls[$transaction->expense_for]['total_work_duration'] = $this->essentialsUtil->getTotalWorkDuration('hour', $transaction->expense_for, $business_id, $start_date->format('Y-m-d'), $end_date->format('Y-m-d')); //get earnings employee $allowances = ! empty($transaction->essentials_allowances) ? json_decode($transaction->essentials_allowances, true) : []; if (empty($allowances['allowance_names']) && empty($allowances['allowance_amounts'])) { $allowances['allowance_names'][] = ''; $allowances['allowance_amounts'][] = 0; $allowances['allowance_types'][] = 'fixed'; $allowances['allowance_percents'][] = ''; } $payrolls[$transaction->expense_for]['allowances'] = $allowances; //get deductions of employee $deductions = ! empty($transaction->essentials_deductions) ? json_decode($transaction->essentials_deductions, true) : []; if (empty($deductions['deduction_names']) && empty($deductions['deduction_amounts'])) { $deductions['deduction_names'][] = ''; $deductions['deduction_amounts'][] = 0; $deductions['deduction_types'][] = 'fixed'; $deductions['deduction_percents'][] = ''; } $payrolls[$transaction->expense_for]['deductions'] = $deductions; } $action = 'edit'; return view('essentials::payroll.create') ->with(compact('month_name', 'transaction_date', 'year', 'payrolls', 'payroll_group', 'action', 'location')); } public function getUpdatePayrollGroup(Request $request) { $business_id = request()->session()->get('user.business_id'); if (! (auth()->user()->can('superadmin') || auth()->user()->can('essentials.update_payroll') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module'))) { abort(403, 'Unauthorized action.'); } try { $transaction_date = $request->input('transaction_date'); $payrolls = $request->input('payrolls'); $notify_employee = ! empty($request->input('notify_employee')) ? 1 : 0; $payroll_group_id = $request->input('payroll_group_id'); $pg_input['name'] = $request->input('payroll_group_name'); $pg_input['status'] = $request->input('payroll_group_status'); $pg_input['gross_total'] = $this->transactionUtil->num_uf($request->input('total_gross_amount')); DB::beginTransaction(); $payroll_group = PayrollGroup::where('business_id', $business_id) ->findOrFail($payroll_group_id); $payroll_group->update($pg_input); foreach ($payrolls as $key => $payroll) { $transaction_id = $payroll['transaction_id']; $payroll['total_before_tax'] = $payroll['final_total']; $payroll['essentials_amount_per_unit_duration'] = $this->moduleUtil->num_uf($payroll['essentials_amount_per_unit_duration']); $allowances_and_deductions = $this->getAllowanceAndDeductionJson($payroll); $payroll['essentials_allowances'] = $allowances_and_deductions['essentials_allowances']; $payroll['essentials_deductions'] = $allowances_and_deductions['essentials_deductions']; unset($payroll['allowance_names'], $payroll['allowance_types'], $payroll['allowance_percent'], $payroll['allowance_amounts'], $payroll['deduction_names'], $payroll['deduction_types'], $payroll['deduction_percent'], $payroll['deduction_amounts'], $payroll['total'], $payroll['transaction_id']); $payroll_trans = Transaction::where('business_id', $business_id) ->where('type', 'payroll') ->find($transaction_id); if (! empty($payroll_trans)) { $payroll_trans->update($payroll); if ($notify_employee && $payroll_group->status == 'final') { $payroll_trans->action = 'updated'; $payroll_trans->transaction_for->notify(new PayrollNotification($payroll_trans)); } } } DB::commit(); $output = ['success' => true, 'msg' => __('lang_v1.updated_success'), ]; } catch (Exception $e) { DB::rollBack(); \Log::emergency('File:'.$e->getFile().'Line:'.$e->getLine().'Message:'.$e->getMessage()); $output = ['success' => false, 'msg' => __('messages.something_went_wrong'), ]; } return redirect()->action([\Modules\Essentials\Http\Controllers\PayrollController::class, 'index'])->with('status', $output); } public function addPayment($id) { $business_id = request()->session()->get('user.business_id'); $is_admin = $this->moduleUtil->is_admin(auth()->user(), $business_id); if (! (auth()->user()->can('superadmin') || $is_admin || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module'))) { abort(403, 'Unauthorized action.'); } $payroll_group = PayrollGroup::where('business_id', $business_id) ->with(['payrollGroupTransactions', 'payrollGroupTransactions.transaction_for', 'businessLocation', 'business']) ->findOrFail($id); $payrolls = []; $month_name = null; $year = null; foreach ($payroll_group->payrollGroupTransactions as $transaction) { //payroll info if (empty($month_name) && empty($year)) { $transaction_date = \Carbon::parse($transaction->transaction_date); $month_name = $transaction_date->format('F'); $year = $transaction_date->format('Y'); } //transaction info $paid_amount = $this->transactionUtil->getTotalPaid($transaction->id); $pending_amount = $transaction->final_total - $paid_amount; if ($pending_amount < 0) { $pending_amount = 0; } $payrolls[$transaction->expense_for]['amount'] = $pending_amount; $payrolls[$transaction->expense_for]['amount_formated'] = $this->transactionUtil->num_f($pending_amount); $payrolls[$transaction->expense_for]['payments'] = TransactionPayment::where('transaction_id', $transaction->id)->get(); $payrolls[$transaction->expense_for]['transaction_id'] = $transaction->id; $payrolls[$transaction->expense_for]['final_total'] = $transaction->final_total; $payrolls[$transaction->expense_for]['payment_status'] = $transaction->payment_status; $payrolls[$transaction->expense_for]['paid_on'] = \Carbon::now(); //get employee info $payrolls[$transaction->expense_for]['employee'] = $transaction->transaction_for->user_full_name; $payrolls[$transaction->expense_for]['employee_id'] = $transaction->transaction_for->id; $payrolls[$transaction->expense_for]['bank_details'] = json_decode($transaction->transaction_for->bank_details, true); } $payment_types = $this->transactionUtil->payment_types(); $accounts = $this->moduleUtil->accountsDropdown($business_id, true, false, true); return view('essentials::payroll.pay_payroll_group') ->with(compact('payroll_group', 'month_name', 'year', 'payrolls', 'payment_types', 'accounts')); } public function postAddPayment(Request $request) { $business_id = request()->session()->get('user.business_id'); $is_admin = $this->moduleUtil->is_admin(auth()->user(), $business_id); if (! (auth()->user()->can('superadmin') || $is_admin || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module'))) { abort(403, 'Unauthorized action.'); } try { $payments = $request->input('payments'); $payroll_group_id = $request->input('payroll_group_id'); foreach ($payments as $employee_id => $payment) { $transaction = Transaction::where('business_id', $business_id)->findOrFail($payment['transaction_id']); $transaction_before = $transaction->replicate(); if ($transaction->payment_status != 'paid' && ! empty($payment['final_total']) && ! empty($payment['method'])) { $input['method'] = $payment['method']; $input['note'] = $payment['payment_note']; $input['card_number'] = $payment['card_number']; $input['card_holder_name'] = $payment['card_holder_name']; $input['card_transaction_number'] = $payment['card_transaction_number']; $input['card_type'] = $payment['card_type']; $input['card_month'] = $payment['card_month']; $input['card_year'] = $payment['card_year']; $input['card_security'] = $payment['card_security']; $input['cheque_number'] = $payment['cheque_number']; $input['bank_account_number'] = $payment['bank_account_number']; $input['business_id'] = $business_id; $input['paid_on'] = $this->transactionUtil->uf_date($payment['paid_on'], true); $input['transaction_id'] = $payment['transaction_id']; $input['amount'] = $this->transactionUtil->num_uf($payment['final_total']); $input['created_by'] = auth()->user()->id; if ($input['method'] == 'custom_pay_1') { $input['transaction_no'] = $payment['transaction_no_1']; } elseif ($input['method'] == 'custom_pay_2') { $input['transaction_no'] = $payment['transaction_no_2']; } elseif ($input['method'] == 'custom_pay_3') { $input['transaction_no'] = $payment['transaction_no_3']; } if (! empty($payment['account_id']) && $input['method'] != 'advance') { $input['account_id'] = $payment['account_id']; } DB::beginTransaction(); $ref_count = $this->transactionUtil->setAndGetReferenceCount('purchase_payment'); // Generate reference number $input['payment_ref_no'] = $this->transactionUtil->generateReferenceNumber('purchase_payment', $ref_count); $tp = TransactionPayment::create($input); $input['transaction_type'] = $transaction->type; event(new TransactionPaymentAdded($tp, $input)); //update payment status $payment_status = $this->transactionUtil->updatePaymentStatus($input['transaction_id']); $transaction->payment_status = $payment_status; $this->transactionUtil->activityLog($transaction, 'payment_edited', $transaction_before); DB::commit(); //unset transaction type after insert data unset($input['transaction_type']); } } $this->_updatePayrollGroupPaymentStatus($payroll_group_id, $business_id); $output = ['success' => true, 'msg' => __('purchase.payment_added_success'), ]; } catch (Exception $e) { DB::rollBack(); \Log::emergency('File:'.$e->getFile().'Line:'.$e->getLine().'Message:'.$e->getMessage()); $output = ['success' => false, 'msg' => __('messages.something_went_wrong'), ]; } return redirect()->action([\Modules\Essentials\Http\Controllers\PayrollController::class, 'index'])->with('status', $output); } protected function _updatePayrollGroupPaymentStatus($payroll_group_id, $business_id) { $payroll_group = PayrollGroup::where('business_id', $business_id) ->with(['payrollGroupTransactions']) ->findOrFail($payroll_group_id); $total_transaction = count($payroll_group->payrollGroupTransactions); $total_paid = $payroll_group->payrollGroupTransactions->where('payment_status', 'paid')->count(); $total_due = $payroll_group->payrollGroupTransactions->where('payment_status', '=', 'due')->count(); if ($total_transaction == $total_paid) { $payment_status = 'paid'; } elseif ($total_transaction == $total_due) { $payment_status = 'due'; } else { $payment_status = 'partial'; } $payroll_group->payment_status = $payment_status; $payroll_group->save(); } /** * List payrolls & pay components * of an user * * @return Response */ public function getMyPayrolls(Request $request) { $business_id = request()->session()->get('user.business_id'); if (! $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module')) { abort(403, 'Unauthorized action.'); } if ($request->ajax()) { $payrolls = $this->essentialsUtil->getPayrollQuery($business_id); $payrolls->where('transactions.expense_for', auth()->user()->id); return Datatables::of($payrolls) ->addColumn( 'action', function ($row) { $html = '<a href="#" data-href="'.action([\Modules\Essentials\Http\Controllers\PayrollController::class, 'show'], [$row->id]).'" data-container=".view_modal" class="btn-modal btn-info btn btn-sm"> <i class="fa fa-eye" aria-hidden="true"></i> ' .__('messages.view'). '</a>'; return $html; } ) ->addColumn('transaction_date', function ($row) { $transaction_date = \Carbon::parse($row->transaction_date); return $transaction_date->format('F Y'); }) ->editColumn('final_total', '<span class="display_currency" data-currency_symbol="true">{{$final_total}}</span>') ->editColumn( 'payment_status', '<span class="label @payment_status($payment_status)">{{__(\'lang_v1.\' . $payment_status)}} </span>' ) ->removeColumn('id') ->rawColumns(['action', 'final_total', 'payment_status']) ->make(true); } $pay_components = EssentialsAllowanceAndDeduction::join('essentials_user_allowance_and_deductions as EUAD', 'essentials_allowances_and_deductions.id', '=', 'EUAD.allowance_deduction_id') ->where('essentials_allowances_and_deductions.business_id', $business_id) ->where('EUAD.user_id', auth()->user()->id) ->get(); return view('essentials::payroll.partials.user_payrolls') ->with(compact('pay_components')); } public function getEmployeesBasedOnLocation(Request $request) { $business_id = request()->session()->get('user.business_id'); if (! (auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'essentials_module'))) { abort(403, 'Unauthorized action.'); } try { $location_id = $request->get('location_id'); $employees = $this->__getEmployeesByLocation($business_id, $location_id); //dynamically generate dropdown $employees_html = view('essentials::payroll.partials.employee_dropdown') ->with(compact('employees')) ->render(); $output = [ 'success' => true, 'msg' => __('lang_v1.success'), 'employees_html' => $employees_html, ]; } catch (Exception $e) { $output = [ 'success' => false, 'msg' => __('messages.something_went_wrong'), ]; } return $output; } private function __getEmployeesByLocation($business_id, $location_id = null) { $query = User::where('business_id', $business_id) ->user(); if (! empty($location_id)) { $query->where('location_id', $location_id); } else { $query->whereNull('location_id'); } $users = $query->select('id', DB::raw("CONCAT(COALESCE(surname, ''),' ',COALESCE(first_name, ''),' ',COALESCE(last_name,'')) as full_name"))->get(); $employees = $users->pluck('full_name', 'id')->toArray(); return $employees; } }