<?php
namespace App\Http\Controllers\Admin;
use App\Classes\Reply;
use App\Http\Controllers\AdminBaseController;
use App\Models\Attendance;
use App\Models\Company;
use App\Models\EmailTemplate;
use App\Models\Employee;
use App\Models\Holiday;
use App\Models\Leavetype;
use Carbon\Carbon;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\DB;
use Yajra\DataTables\Facades\DataTables;
use Illuminate\Http\Request;
use App\Http\Requests\Admin\Attendance\UpdateRequest;
use App\Http\Requests;
/*
* Attendance Controller of Admin Panel
*/
class AttendancesController extends AdminBaseController
{
public function __construct()
{
parent::__construct();
$this->attendanceOpen = 'active';
$this->pageTitle = trans("pages.attendances.indexTitle");
$timezones = [
"Pacific/Pago_Pago" => "-11:00",
"Pacific/Midway" => "-11:00",
"Pacific/Niue" => "-11:00",
"Pacific/Honolulu" => "-10:00",
"Pacific/Tahiti" => "-10:00",
"Pacific/Rarotonga" => "-10:00",
"Pacific/Marquesas" => "-09:30",
"America/Adak" => "-09:00",
"Pacific/Gambier" => "-09:00",
"America/Anchorage" => "-08:00",
"America/Nome" => "-08:00",
"America/Sitka" => "-08:00",
"America/Yakutat" => "-08:00",
"America/Metlakatla" => "-08:00",
"America/Juneau" => "-08:00",
"Pacific/Pitcairn" => "-08:00",
"America/Phoenix" => "-07:00",
"America/Creston" => "-07:00",
"America/Dawson" => "-07:00",
"America/Los_Angeles" => "-07:00",
"America/Dawson_Creek" => "-07:00",
"America/Whitehorse" => "-07:00",
"America/Hermosillo" => "-07:00",
"America/Fort_Nelson" => "-07:00",
"America/Tijuana" => "-07:00",
"America/Vancouver" => "-07:00",
"America/Chihuahua" => "-06:00",
"America/Cambridge_Bay" => "-06:00",
"America/Boise" => "-06:00",
"America/Denver" => "-06:00",
"America/El_Salvador" => "-06:00",
"America/Costa_Rica" => "-06:00",
"America/Mazatlan" => "-06:00",
"America/Ojinaga" => "-06:00",
"America/Guatemala" => "-06:00",
"America/Edmonton" => "-06:00",
"America/Inuvik" => "-06:00",
"America/Belize" => "-06:00",
"America/Managua" => "-06:00",
"America/Swift_Current" => "-06:00",
"America/Regina" => "-06:00",
"Pacific/Galapagos" => "-06:00",
"America/Yellowknife" => "-06:00",
"America/Tegucigalpa" => "-06:00",
"America/Monterrey" => "-05:00",
"America/Menominee" => "-05:00",
"America/Bahia_Banderas" => "-05:00",
"America/Bogota" => "-05:00",
"America/Cancun" => "-05:00",
"America/Merida" => "-05:00",
"America/Chicago" => "-05:00",
"America/Winnipeg" => "-05:00",
"America/Eirunepe" => "-05:00",
"America/Atikokan" => "-05:00",
"America/Matamoros" => "-05:00",
"Pacific/Easter" => "-05:00",
"America/Guayaquil" => "-05:00",
"America/Indiana/Knox" => "-05:00",
"America/Indiana/Tell_City" => "-05:00",
"America/Jamaica" => "-05:00",
"America/Lima" => "-05:00",
"America/Mexico_City" => "-05:00",
"America/Cayman" => "-05:00",
"America/Rainy_River" => "-05:00",
"America/Rankin_Inlet" => "-05:00",
"America/Rio_Branco" => "-05:00",
"America/North_Dakota/Center" => "-05:00",
"America/Panama" => "-05:00",
"America/Resolute" => "-05:00",
"America/North_Dakota/New_Salem" => "-05:00",
"America/North_Dakota/Beulah" => "-05:00",
"America/New_York" => "-04:00",
"America/Puerto_Rico" => "-04:00",
"America/Porto_Velho" => "-04:00",
"America/Grand_Turk" => "-04:00",
"America/Guadeloupe" => "-04:00",
"America/Grenada" => "-04:00",
"America/Marigot" => "-04:00",
"America/Martinique" => "-04:00",
"America/Port_of_Spain" => "-04:00",
"America/Port-au-Prince" => "-04:00",
"America/Guyana" => "-04:00",
"America/Indiana/Indianapolis" => "-04:00",
"America/Manaus" => "-04:00",
"America/Havana" => "-04:00",
"America/Tortola" => "-04:00",
"America/Indiana/Marengo" => "-04:00",
"America/Indiana/Petersburg" => "-04:00",
"America/Indiana/Vevay" => "-04:00",
"America/Indiana/Vincennes" => "-04:00",
"America/Indiana/Winamac" => "-04:00",
"America/Iqaluit" => "-04:00",
"America/Kentucky/Louisville" => "-04:00",
"America/Kentucky/Monticello" => "-04:00",
"America/Kralendijk" => "-04:00",
"America/La_Paz" => "-04:00",
"America/Pangnirtung" => "-04:00",
"America/Dominica" => "-04:00",
"America/Nassau" => "-04:00",
"America/Campo_Grande" => "-04:00",
"America/Montserrat" => "-04:00",
"America/Lower_Princes" => "-04:00",
"America/Aruba" => "-04:00",
"America/Asuncion" => "-04:00",
"America/Nipigon" => "-04:00",
"America/Barbados" => "-04:00",
"America/St_Barthelemy" => "-04:00",
"America/St_Kitts" => "-04:00",
"America/Blanc-Sablon" => "-04:00",
"America/Boa_Vista" => "-04:00",
"America/Detroit" => "-04:00",
"America/St_Thomas" => "-04:00",
"America/St_Lucia" => "-04:00",
"America/Caracas" => "-04:00",
"America/Toronto" => "-04:00",
"America/Antigua" => "-04:00",
"America/St_Vincent" => "-04:00",
"America/Anguilla" => "-04:00",
"America/Cuiaba" => "-04:00",
"America/Curacao" => "-04:00",
"America/Santo_Domingo" => "-04:00",
"America/Thunder_Bay" => "-04:00",
"Atlantic/Stanley" => "-03:00",
"America/Montevideo" => "-03:00",
"America/Paramaribo" => "-03:00",
"America/Moncton" => "-03:00",
"America/Sao_Paulo" => "-03:00",
"America/Thule" => "-03:00",
"America/Santarem" => "-03:00",
"Antarctica/Rothera" => "-03:00",
"America/Santiago" => "-03:00",
"America/Punta_Arenas" => "-03:00",
"Antarctica/Palmer" => "-03:00",
"America/Recife" => "-03:00",
"Atlantic/Bermuda" => "-03:00",
"America/Maceio" => "-03:00",
"America/Argentina/Tucuman" => "-03:00",
"America/Araguaina" => "-03:00",
"America/Argentina/Buenos_Aires" => "-03:00",
"America/Argentina/Catamarca" => "-03:00",
"America/Argentina/Cordoba" => "-03:00",
"America/Argentina/Jujuy" => "-03:00",
"America/Argentina/Mendoza" => "-03:00",
"America/Argentina/Rio_Gallegos" => "-03:00",
"America/Argentina/Salta" => "-03:00",
"America/Argentina/San_Juan" => "-03:00",
"America/Argentina/San_Luis" => "-03:00",
"America/Argentina/La_Rioja" => "-03:00",
"America/Argentina/Ushuaia" => "-03:00",
"America/Fortaleza" => "-03:00",
"America/Halifax" => "-03:00",
"America/Goose_Bay" => "-03:00",
"America/Glace_Bay" => "-03:00",
"America/Belem" => "-03:00",
"America/Cayenne" => "-03:00",
"America/Bahia" => "-03:00",
"America/St_Johns" => "-02:30",
"America/Noronha" => "-02:00",
"America/Godthab" => "-02:00",
"America/Miquelon" => "-02:00",
"Atlantic/South_Georgia" => "-02:00",
"Atlantic/Cape_Verde" => "-01:00",
"Africa/Bissau" => "+00:00",
"Africa/Freetown" => "+00:00",
"Africa/Dakar" => "+00:00",
"Africa/Conakry" => "+00:00",
"Atlantic/Reykjavik" => "+00:00",
"Africa/Banjul" => "+00:00",
"Atlantic/Azores" => "+00:00",
"Africa/Bamako" => "+00:00",
"Africa/Accra" => "+00:00",
"Atlantic/St_Helena" => "+00:00",
"Africa/Lome" => "+00:00",
"America/Scoresbysund" => "+00:00",
"Africa/Abidjan" => "+00:00",
"Africa/Nouakchott" => "+00:00",
"Africa/Monrovia" => "+00:00",
"America/Danmarkshavn" => "+00:00",
"Africa/Ouagadougou" => "+00:00",
"Africa/Sao_Tome" => "+00:00",
"Europe/Dublin" => "+01:00",
"Europe/Isle_of_Man" => "+01:00",
"Europe/Jersey" => "+01:00",
"Africa/Porto-Novo" => "+01:00",
"Africa/Bangui" => "+01:00",
"Europe/Lisbon" => "+01:00",
"Europe/London" => "+01:00",
"Africa/Niamey" => "+01:00",
"Africa/Brazzaville" => "+01:00",
"Africa/Casablanca" => "+01:00",
"Africa/Ndjamena" => "+01:00",
"Africa/Douala" => "+01:00",
"Africa/El_Aaiun" => "+01:00",
"Africa/Luanda" => "+01:00",
"Africa/Malabo" => "+01:00",
"Atlantic/Canary" => "+01:00",
"Africa/Libreville" => "+01:00",
"Africa/Lagos" => "+01:00",
"Africa/Kinshasa" => "+01:00",
"Atlantic/Faroe" => "+01:00",
"Atlantic/Madeira" => "+01:00",
"Africa/Tunis" => "+01:00",
"Africa/Algiers" => "+01:00",
"Europe/Guernsey" => "+01:00",
"Europe/Paris" => "+02:00",
"Europe/Ljubljana" => "+02:00",
"Europe/Luxembourg" => "+02:00",
"Europe/Madrid" => "+02:00",
"Europe/Malta" => "+02:00",
"Europe/Kaliningrad" => "+02:00",
"Europe/Oslo" => "+02:00",
"Europe/Monaco" => "+02:00",
"Africa/Lusaka" => "+02:00",
"Europe/Gibraltar" => "+02:00",
"Europe/Copenhagen" => "+02:00",
"Europe/Busingen" => "+02:00",
"Europe/Budapest" => "+02:00",
"Europe/Brussels" => "+02:00",
"Europe/Bratislava" => "+02:00",
"Europe/Prague" => "+02:00",
"Europe/Berlin" => "+02:00",
"Europe/Belgrade" => "+02:00",
"Europe/Andorra" => "+02:00",
"Europe/Amsterdam" => "+02:00",
"Africa/Tripoli" => "+02:00",
"Africa/Windhoek" => "+02:00",
"Europe/Podgorica" => "+02:00",
"Europe/Sarajevo" => "+02:00",
"Europe/Warsaw" => "+02:00",
"Africa/Gaborone" => "+02:00",
"Antarctica/Troll" => "+02:00",
"Africa/Blantyre" => "+02:00",
"Europe/Zagreb" => "+02:00",
"Europe/Rome" => "+02:00",
"Africa/Bujumbura" => "+02:00",
"Europe/Vienna" => "+02:00",
"Africa/Cairo" => "+02:00",
"Europe/Vatican" => "+02:00",
"Europe/Vaduz" => "+02:00",
"Africa/Ceuta" => "+02:00",
"Africa/Mbabane" => "+02:00",
"Europe/Tirane" => "+02:00",
"Africa/Harare" => "+02:00",
"Europe/Stockholm" => "+02:00",
"Africa/Johannesburg" => "+02:00",
"Europe/Skopje" => "+02:00",
"Africa/Khartoum" => "+02:00",
"Africa/Kigali" => "+02:00",
"Africa/Maseru" => "+02:00",
"Africa/Maputo" => "+02:00",
"Africa/Lubumbashi" => "+02:00",
"Europe/San_Marino" => "+02:00",
"Europe/Zurich" => "+02:00",
"Indian/Comoro" => "+03:00",
"Europe/Athens" => "+03:00",
"Indian/Mayotte" => "+03:00",
"Europe/Riga" => "+03:00",
"Europe/Bucharest" => "+03:00",
"Europe/Chisinau" => "+03:00",
"Europe/Zaporozhye" => "+03:00",
"Europe/Vilnius" => "+03:00",
"Europe/Helsinki" => "+03:00",
"Europe/Istanbul" => "+03:00",
"Europe/Kiev" => "+03:00",
"Europe/Kirov" => "+03:00",
"Europe/Uzhgorod" => "+03:00",
"Europe/Tallinn" => "+03:00",
"Europe/Sofia" => "+03:00",
"Europe/Mariehamn" => "+03:00",
"Europe/Minsk" => "+03:00",
"Europe/Simferopol" => "+03:00",
"Europe/Moscow" => "+03:00",
"Indian/Antananarivo" => "+03:00",
"Asia/Amman" => "+03:00",
"Asia/Aden" => "+03:00",
"Africa/Mogadishu" => "+03:00",
"Asia/Kuwait" => "+03:00",
"Asia/Nicosia" => "+03:00",
"Asia/Baghdad" => "+03:00",
"Antarctica/Syowa" => "+03:00",
"Asia/Jerusalem" => "+03:00",
"Asia/Bahrain" => "+03:00",
"Asia/Gaza" => "+03:00",
"Asia/Qatar" => "+03:00",
"Asia/Famagusta" => "+03:00",
"Asia/Riyadh" => "+03:00",
"Africa/Nairobi" => "+03:00",
"Asia/Hebron" => "+03:00",
"Africa/Kampala" => "+03:00",
"Asia/Damascus" => "+03:00",
"Asia/Beirut" => "+03:00",
"Africa/Dar_es_Salaam" => "+03:00",
"Africa/Djibouti" => "+03:00",
"Africa/Asmara" => "+03:00",
"Africa/Addis_Ababa" => "+03:00",
"Africa/Juba" => "+03:00",
"Indian/Mauritius" => "+04:00",
"Asia/Tbilisi" => "+04:00",
"Europe/Saratov" => "+04:00",
"Asia/Dubai" => "+04:00",
"Europe/Astrakhan" => "+04:00",
"Indian/Mahe" => "+04:00",
"Europe/Ulyanovsk" => "+04:00",
"Asia/Baku" => "+04:00",
"Indian/Reunion" => "+04:00",
"Europe/Samara" => "+04:00",
"Asia/Muscat" => "+04:00",
"Asia/Yerevan" => "+04:00",
"Europe/Volgograd" => "+04:00",
"Asia/Kabul" => "+04:30",
"Asia/Tehran" => "+04:30",
"Asia/Aqtobe" => "+05:00",
"Asia/Aqtau" => "+05:00",
"Asia/Karachi" => "+05:00",
"Antarctica/Mawson" => "+05:00",
"Asia/Oral" => "+05:00",
"Asia/Tashkent" => "+05:00",
"Indian/Kerguelen" => "+05:00",
"Indian/Maldives" => "+05:00",
"Asia/Atyrau" => "+05:00",
"Asia/Qyzylorda" => "+05:00",
"Asia/Dushanbe" => "+05:00",
"Asia/Samarkand" => "+05:00",
"Asia/Yekaterinburg" => "+05:00",
"Asia/Ashgabat" => "+05:00",
"Asia/Colombo" => "+05:30",
"Asia/Kolkata" => "+05:30",
"Asia/Kathmandu" => "+05:45",
"Asia/Dhaka" => "+06:00",
"Asia/Bishkek" => "+06:00",
"Asia/Thimphu" => "+06:00",
"Asia/Omsk" => "+06:00",
"Antarctica/Vostok" => "+06:00",
"Indian/Chagos" => "+06:00",
"Asia/Urumqi" => "+06:00",
"Asia/Almaty" => "+06:00",
"Asia/Qostanay" => "+06:00",
"Indian/Cocos" => "+06:30",
"Asia/Yangon" => "+06:30",
"Antarctica/Davis" => "+07:00",
"Asia/Tomsk" => "+07:00",
"Asia/Vientiane" => "+07:00",
"Asia/Barnaul" => "+07:00",
"Asia/Krasnoyarsk" => "+07:00",
"Asia/Pontianak" => "+07:00",
"Asia/Ho_Chi_Minh" => "+07:00",
"Asia/Hovd" => "+07:00",
"Asia/Phnom_Penh" => "+07:00",
"Asia/Jakarta" => "+07:00",
"Indian/Christmas" => "+07:00",
"Asia/Novosibirsk" => "+07:00",
"Asia/Novokuznetsk" => "+07:00",
"Asia/Bangkok" => "+07:00",
"Antarctica/Casey" => "+08:00",
"Asia/Shanghai" => "+08:00",
"Asia/Brunei" => "+08:00",
"Asia/Kuala_Lumpur" => "+08:00",
"Australia/Perth" => "+08:00",
"Asia/Manila" => "+08:00",
"Asia/Ulaanbaatar" => "+08:00",
"Asia/Macau" => "+08:00",
"Asia/Kuching" => "+08:00",
"Asia/Makassar" => "+08:00",
"Asia/Taipei" => "+08:00",
"Asia/Choibalsan" => "+08:00",
"Asia/Irkutsk" => "+08:00",
"Asia/Hong_Kong" => "+08:00",
"Asia/Singapore" => "+08:00",
"Australia/Eucla" => "+08:45",
"Asia/Chita" => "+09:00",
"Asia/Tokyo" => "+09:00",
"Pacific/Palau" => "+09:00",
"Asia/Khandyga" => "+09:00",
"Asia/Yakutsk" => "+09:00",
"Asia/Seoul" => "+09:00",
"Asia/Dili" => "+09:00",
"Asia/Jayapura" => "+09:00",
"Asia/Pyongyang" => "+09:00",
"Australia/Adelaide" => "+09:30",
"Australia/Darwin" => "+09:30",
"Australia/Broken_Hill" => "+09:30",
"Pacific/Guam" => "+10:00",
"Pacific/Port_Moresby" => "+10:00",
"Antarctica/DumontDUrville" => "+10:00",
"Pacific/Chuuk" => "+10:00",
"Australia/Currie" => "+10:00",
"Pacific/Saipan" => "+10:00",
"Australia/Hobart" => "+10:00",
"Australia/Sydney" => "+10:00",
"Australia/Lindeman" => "+10:00",
"Australia/Melbourne" => "+10:00",
"Asia/Ust-Nera" => "+10:00",
"Asia/Vladivostok" => "+10:00",
"Australia/Brisbane" => "+10:00",
"Australia/Lord_Howe" => "+10:30",
"Pacific/Pohnpei" => "+11:00",
"Asia/Srednekolymsk" => "+11:00",
"Antarctica/Macquarie" => "+11:00",
"Asia/Sakhalin" => "+11:00",
"Pacific/Efate" => "+11:00",
"Pacific/Bougainville" => "+11:00",
"Asia/Magadan" => "+11:00",
"Pacific/Kosrae" => "+11:00",
"Pacific/Noumea" => "+11:00",
"Pacific/Norfolk" => "+11:00",
"Pacific/Guadalcanal" => "+11:00",
"Pacific/Tarawa" => "+12:00",
"Pacific/Wake" => "+12:00",
"Pacific/Wallis" => "+12:00",
"Pacific/Nauru" => "+12:00",
"Pacific/Majuro" => "+12:00",
"Pacific/Kwajalein" => "+12:00",
"Pacific/Funafuti" => "+12:00",
"Pacific/Fiji" => "+12:00",
"Pacific/Auckland" => "+12:00",
"Antarctica/McMurdo" => "+12:00",
"Asia/Anadyr" => "+12:00",
"Asia/Kamchatka" => "+12:00",
"Pacific/Chatham" => "+12:45",
"Pacific/Fakaofo" => "+13:00",
"Pacific/Enderbury" => "+13:00",
"Pacific/Apia" => "+13:00",
"Pacific/Tongatapu" => "+13:00",
"Pacific/Kiritimati" => "+14:00",
];
$this->timezones = array_flip($timezones);
}
/*
* This is the view page of attendance.
*/
public function index()
{
$this->viewAttendanceActive = 'active';
/*$this->date = Carbon::now()->format('Y-m-d');
return View::make('admin.attendances.index', $this->data);*/
$this->attendances = Attendance::all();
$this->viewAttendanceActive = 'active';
$this->date = date('Y-m-d');
$this->daysInMonth = Carbon::now()->daysInMonth;
$this->employees = Employee::manager()
->select('full_name', 'employees.id','employeeID')
->where('status', '=', 'active')->get();
return View::make('admin.attendances.attendance-sheet', $this->data);
}
/*
* This is the view page of attendance.
*/
public function attendanceEmployee()
{
$this->viewAttendanceEmployeeActive = 'active';
$this->date = Carbon::now()->format('Y-m-d');
return View::make('admin.attendances.index', $this->data);
}
public function ajax_employees()
{
// Using this query in front end too
$result = Employee::manager(admin()->id)
->select('employees.employeeID as employeeID',
'profile_image', 'employees.full_name as full_name',
\DB::raw('GROUP_CONCAT(DISTINCT a.leave_type SEPARATOR ",") as leave_types'),
\DB::raw('GROUP_CONCAT(a.leave_count SEPARATOR ",") as leave_count'),
'annual_leave',
'employees.status',
'last_absent','employees.id')
->leftJoin(\DB::raw('(
SELECT attendance.leaveType as leave_type, COUNT(attendance.leaveType) as leave_count, attendance.employee_id, MAX(attendance.date) as last_absent
FROM attendance INNER JOIN employees On employees.id = attendance.employee_id
WHERE leaveType is not null
GROUP BY attendance.leaveType, attendance.employee_id )
as a'), "a.employee_id", "=", "employees.id")
->groupBy("employees.employeeID");
$leaveTypes = Leavetype::pluck("leaveType");
return DataTables::of($result)
->addColumn('edit', function ($row) {
$string = ' <a class="btn purple btn-sm" href="' . route('admin.attendances.show', $row->id) . '">
<i class="fa fa-eye"></i> ' . trans("core.view") . ' </a>';
return $string;
})
->editColumn('status', function ($row) {
$color = ['active' => 'success', 'inactive' => 'danger'];
return "<span id='status{$row->id}' class='label label-{$color[$row->status]}'>" . trans("core." . $row->status) . "</span>";
})
->editColumn('last_absent', function ($row) {
if ($row->last_absent == null) {
return '<span class="label label-success">Never</span>';
} else {
$carbon = Carbon::createFromFormat("Y-m-d", $row->last_absent);
return $carbon->format("d-M-Y") . " (" . $carbon->diffForHumans() . ")";
}
})
->editColumn('leave_types', function ($row) use ($leaveTypes) {
$takenLeaveTypes = explode(",", $row->leave_types);
$takenLeaves = explode(",", $row->leave_count);
$data = '<table width="100%">';
foreach ($leaveTypes as $leaveType) {
$data .= ' <tr>';
$data .= '<td ><strong>' . ucfirst($leaveType) . '</strong>: </td>';
if (($key = array_search($leaveType, $takenLeaveTypes)) !== FALSE) {
$data .= '<td>' . $takenLeaves[$key] . '</td>';
} else {
$data .= '<td>0</td>';
}
$data .= '</tr>';
}
$data .= '</table>';
return $data;
})
->editColumn('profile_image', function ($employee) {
return \HTML::image($employee->profile_image_url, 'ProfileImage', ['height' => '80px']);
})
->editColumn('employeeID', function ($employee) {
return $employee->employeeID;
})->editColumn('full_name', function ($row) {
$employee = Employee::find($row->id);
return $employee->decryptToCollection()->full_name;
})
->removeColumn('id')
->rawColumns(['profile_image', 'leave_types', 'last_absent', 'status', 'edit'])
->make(true);
}
/**
* @return mixed
* This method is called when we mark the attendance and redirects to edit page.
*/
public function create()
{
$date = Carbon::now()->timezone($this->timezones[admin()->company->timezone])->format("Y-m-d");
$attendance_count = Attendance::where('date', '=', $date)
->count();
$employee_count = Employee::where('status', '=', 'active')
->count();
if ($employee_count == $attendance_count && ($attendance_count)>0) {
if (!\Session::get('success')) {
\Session::flash('success', trans("messages.attendanceAlreadyMarked"));
}
} else {
\Session::forget('success');
}
return \Redirect::route('admin.attendances.edit', $date);
}
/**
* Display the specified attendance
*/
public function show($id)
{
$this->employee = Employee::findOrFail($id);
if ($this->employee == null) {
return View::make('admin.errors.noaccess', $this->data);
}
$this->viewAttendanceActive = 'active';
$this->attendance = Attendance::where('employee_id', '=', $id)->where(function ($query) {
$query->where('application_status', '=', 'approved')
->orwhere('application_status', '=', null)
->orwhere('status', '=', 'present');
})->get();
$this->holidays = Holiday::get();
$this->employeeslist = Employee::manager()
->select('full_name', 'employees.id','employeeID')
->where('status', '=', 'active')->get();
return View::make('admin.attendances.show', $this->data);
}
/**
* Show the form for editing the specified attendance.
*/
public function edit($date_str)
{
$dateObj = Carbon::createFromFormat("Y-m-d", $date_str, $this->data["setting"]->timezone)->timezone('UTC');
$date = $dateObj->format("Y-m-d");
$this->markAttendanceActive = 'active';
$attendanceArray = [];
$this->attendance = Employee::manager(admin()->id)
->leftJoin("attendance", function ($query) use ($date) {
$query->on("attendance.employee_id", "=", "employees.employeeID");
$query->on("attendance.date", "=", \DB::raw('"' . $date . '"'));
})
->select('employees.full_name',
'employees.employeeID as employeeID',
'attendance.status',
'attendance.date',
'attendance.leaveType',
'attendance.halfDayType',
'attendance.application_status',
'attendance.applied_on',
'attendance.clock_in',
'attendance.clock_out',
'attendance.clock_in_ip_address',
'attendance.clock_out_ip_address',
'attendance.working_from',
'attendance.notes',
'attendance.reason',
'attendance.is_late'
)
->where("employees.status", "active")
->take(10)
->get();
$this->todays_holidays = Holiday::where('date', '=', $date)
->get()
->first();
foreach ($this->attendance as $attend) {
$attendanceArray[$attend['employeeID']] = $attend;
}
$this->date = $dateObj->timezone($this->timezones[admin()->company->timezone]);
$this->attendanceArray = $attendanceArray;
$this->leaveTypes = Attendance::leaveTypesEmployees($this->company_id);
$this->data["employees_count"] = Employee::count();
$this->officeStartTime = Carbon::createFromFormat('H:i:s', admin()->company->office_start_time, 'UTC')->timezone($this->timezones[admin()->company->timezone])->format('g:i A');
$this->timeZoneLocal = admin()->company->timezone;
$this->officeEndTime = Carbon::createFromFormat('H:i:s', admin()->company->office_end_time, 'UTC')->timezone($this->timezones[admin()->company->timezone])->format('g:i A');
return \View::make('admin.attendances.edit', $this->data);
}
/**
* Update the specified attendance in storage.
*/
public function update($date_str)
{
$date = Carbon::parse($date_str)->format("Y-m-d");
$data = json_decode(request()->get("data"), true);
$employeeIDs = array_keys($data);
\DB::beginTransaction();
// Get all employee ids for this company
$allEmployeeIDs = Employee::pluck("id");
try {
foreach ($allEmployeeIDs as $employeeID) {
/** @var Attendance $attendance */
$attendance = Attendance::firstOrCreate(['employee_id' => $employeeID, 'date' => $date]);
if (in_array($employeeID, $employeeIDs)) {
// If employee's leave is approved but admin marks him present, then we remove his leave and mark him present
if ($attendance->application_status != 'approved' || ($attendance->application_status == 'approved' && $data[$employeeID]["status"] == 'true')) {
// We separately set all parameters for present and absent
// so that previously set values are overwritten. For example,
// if a person was marked present for a day but then he was updated as absent
// then his clocking details should be null to prevent wrong calculations
if ($data[$employeeID]["status"] == "true") {
$attendance->status = "present";
$attendance->leaveType = null;
$attendance->halfDayType = null;
$attendance->reason = '';
$attendance->application_status = null;
$clock_in = Carbon::createFromFormat('g:i A', $data[$employeeID]["clock_in"], admin()->company->timezone)
->timezone('UTC');
$clock_out = Carbon::createFromFormat('g:i A', $data[$employeeID]["clock_out"], admin()->company->timezone)
->timezone('UTC');
// When admin is updating, late mark should not be according to clock in/clock out
if ($data[$employeeID]["late"] == "true") {
$attendance->is_late = 1;
} else {
$attendance->is_late = 0;
}
$attendance->clock_in = $clock_in->format('H:i:s');
$attendance->clock_out = $clock_out->format('H:i:s');
$attendance->working_from = "Office";
$attendance->notes = "";
} else {
$attendance->status = "absent";
$attendance->leaveType = $data[$employeeID]["leaveType"];
$attendance->halfDayType = ($data[$employeeID]["halfDay"] == 'true') ? 'yes' : 'no';
$attendance->reason = $data[$employeeID]["reason"];
$attendance->application_status = null;
$attendance->is_late = 0;
$attendance->clock_in = null;
$attendance->clock_out = null;
$attendance->working_from = "";
$attendance->notes = "";
}
$attendance->office_start_time = admin()->company->office_start_time;
$attendance->office_end_time = admin()->company->office_end_time;
$attendance->last_updated_by = admin()->id;
$attendance->save();
}
} else {
if ($attendance->status != "absent") {
$attendance->status = "present";
$attendance->leaveType = null;
$attendance->halfDayType = null;
$attendance->reason = '';
$attendance->application_status = null;
$attendance->last_updated_by = admin()->id;
$attendance->is_late = 0;
$attendance->clock_in = $this->data["active_company"]->office_start_time;
$attendance->clock_out = $this->data["active_company"]->office_end_time;
$attendance->office_start_time = admin()->company->office_start_time;
$attendance->office_end_time = admin()->company->office_end_time;
$attendance->clock_in_ip_address = null;
$attendance->clock_out_ip_address = null;
$attendance->working_from = 'Office';
$attendance->notes = '';
$attendance->save();
}
}
}
} catch (\Exception $e) {
\DB::rollback();
throw $e;
}
\DB::commit();
$this->date = Carbon::parse($date_str)->format("d M Y");
if (admin()->company->attendance_notification == 1) {
$employees = Employee::select('email', 'full_name')
->where('status', '=', 'active')
->get();
//---- Attendance Marked EMAIL TEMPLATE-----
// Do not send email notifications if there are more than x employees in database
if ($employees->count() <= EmployeesController::$MAX_EMPLOYEES) {
foreach ($employees as $employee) {
$email = "{$employee->email}";
$emailInfo = ['from_email' => $this->setting->email,
'from_name' => $this->setting->name,
'to' => $email,
'active_company' => admin()->company];
$fieldValues = ['NAME' => $employee->full_name, 'DATE' => $this->date];
EmailTemplate::prepareAndSendEmail('ATTENDANCE_MARKED', $emailInfo, $fieldValues);
}
}
//---- Attendance Marked EMAIL TEMPLATE-----
}
return ["status" => "success",
"message" => trans("messages.attendanceUpdateMessage", ["attendance" => date('d M Y', strtotime($date))]),
'toastrHeading' => trans('messages.success'),
'toastrMessage' => trans("messages.attendanceUpdateMessage", ["attendance" => date('d M Y', strtotime($date))]),
'toastrType' => 'success',
'action' => 'showToastr',
'date' => $date];
}
public function report()
{
$month = request()->get('month');
$year = request()->get('year');
$employeeID = request()->get('employee_id');
$firstDay = $year . '-' . $month . '-01';
$presentCount = Attendance::countPresentDays($month, $year, $employeeID);
$totalDays = date('t', strtotime($firstDay));
$holidaycount = count(DB::select(DB::raw("SELECT * FROM holidays WHERE MONTH(date)=" . $month . " AND YEAR(date)=" . $year . " AND company_id=" . $this->company_id)));
$workingDays = $totalDays - $holidaycount;
$percentage = ($presentCount / $workingDays) * 100;
$output['success'] = 'success';
$output['presentByWorking'] = "{$presentCount}/$workingDays";
$output['attendancePerReport'] = number_format((float)$percentage, 2, '.', '');
return Response::json($output, 200);
}
/**
* Remove the specified attendance from storage.
*/
public function destroy($id)
{
Attendance::destroy($id);
return Redirect::route('admin.attendances.index');
}
/**
*Updates the single Row Attendance
*
*/
public function updateAttendanceRow(UpdateRequest $request)
{
$input = $request->all();
$date = Carbon::createFromFormat("d-m-Y", $input['date'])->timezone('UTC')->format('Y-m-d');
/** @var Attendance $attendance */
$attendance = Attendance::firstOrCreate(['employee_id' => request()->get('id'), 'date' => $date]);
if ($attendance->application_status != 'approved' || ($attendance->application_status == 'approved' && $input['status'] == 'present')) {
if ($input['status'] == 'present') {
$attendance->status = 'present';
$attendance->leaveType = null;
$attendance->halfDayType = "no";
$clock_in = Carbon::createFromFormat('g:i A', request()->get('clock_in'))->timezone('UTC');
$clock_out = Carbon::createFromFormat('g:i A', request()->get('clock_out'))->timezone('UTC');
$attendance->clock_in = $clock_in->format('H:i:s');
$attendance->clock_out = $clock_out->format('H:i:s');
if ($input["is_late"] == "true") {
$attendance->is_late = 1;
} else {
$attendance->is_late = 0;
}
$clock_in_ip = request()->get('clock_in_ip');
$clock_out_ip = request()->get('clock_out_ip');
$working_from = request()->get('work');
$notes = request()->get('notes');
if ($clock_in_ip != 'Not Set') {
$attendance->clock_in_ip_address = $clock_in_ip;
}
if ($clock_out_ip != 'Not Set') {
$attendance->clock_out_ip_address = $clock_out_ip;
}
$attendance->working_from = $working_from;
$attendance->notes = $notes;
} else {
$attendance->status = 'absent';
if ($input['half_day'] == 'true') {
$attendance->halfDayType = "yes";
} else {
$attendance->halfDayType = "no";
}
$attendance->leaveType = request()->get('leave_type');
$attendance->reason = $input['reason'];
$attendance->clock_in = null;
$attendance->clock_out = null;
$attendance->is_late = 0;
$attendance->clock_in_ip_address = null;
$attendance->clock_out_ip_address = null;
$attendance->working_from = "";
$attendance->notes = "";
}
$attendance->last_updated_by = admin()->id;
$attendance->office_start_time = admin()->company->office_start_time;
$attendance->office_end_time = admin()->company->office_end_time;
$attendance->save();
return [
'status' => 'success',
'toastrMessage' => trans('messages.successUpdate'),
'toastrHeading' => trans('messages.success'),
'action' => 'showToastr',
'checkbox' => $attendance->is_late,
'divHTML' => \View::make("admin.attendances.col3", ["row" => $attendance])->render()
];
}
return [
'status' => 'fail',
'msg' => "Failed in outer loop",
'toastrMessage' => trans('messages.successUpdate'),
'toastrHeading' => trans('messages.success'),
'toastrType' => 'error',
'action' => 'showToastr',
'divHTML' => \View::make("admin.attendances.col3", ["row" => $attendance])->render()
];
}
public function ajax_attendance(Request $request)
{
if ($request->has('date')) {
$date = Carbon::parse(request()->get('date'))->format('Y-m-d');
} else {
$date = Carbon::now()->format('Y-m-d');
}
$leaveTypes = Attendance::leaveTypesEmployees($this->company_id);
$result = Employee::manager(admin()->id)
->leftJoin("attendance", function ($query) use ($date) {
$query->on("attendance.employee_id", "=", "employees.id");
$query->on("attendance.date", "=", \DB::raw('"' . $date . '"'));
})
->select('employees.full_name as full_name',
'employees.id as employeeID',
'attendance.status',
'attendance.date',
'attendance.leaveType',
'attendance.halfDayType',
'attendance.application_status',
'attendance.applied_on',
'attendance.clock_in',
'attendance.clock_out',
'attendance.clock_in_ip_address',
'attendance.clock_out_ip_address',
'attendance.working_from',
'attendance.notes',
'attendance.reason',
'attendance.is_late',
'employees.id',
'employees.employeeID as eID'
)
->where("employees.status", "active")
->get();
return DataTables::of($result)
->editColumn('eID', function ($row) {
return $row->eID . "</strong><p>" . $row->full_name . "</p></td>";
})
->editColumn('status', function ($row) use ($leaveTypes) {
return \View::make("admin.attendances.col2", ["row" => $row, "leaveTypes" => $leaveTypes])->render();
})
->editColumn('date', function ($row) {
$attendance_mark = \View::make("admin.attendances.col3", ["row" => $row])->render();
return $attendance_mark;
})
->editColumn('clock_in', function ($row) {
if ($row->clock_in != null) {
$input_value_clock_in = Carbon::createFromFormat('H:i:s', $row->clock_in, 'UTC')->timezone($this->timezones[admin()->company->timezone])->format('g:i A');
} else {
$input_value_clock_in = Carbon::createFromFormat('H:i:s', admin()->company->office_start_time, 'UTC')->timezone($this->timezones[admin()->company->timezone])->format('g:i A');
}
if ($row->clock_out != null) {
$input_value_clock_out = Carbon::createFromFormat('H:i:s', $row->clock_out, 'UTC')->timezone($this->timezones[admin()->company->timezone])->format('g:i A');
} else {
$input_value_clock_out = Carbon::createFromFormat('H:i:s', admin()->company->office_end_time, 'UTC')->timezone($this->timezones[admin()->company->timezone])->format('g:i A');
}
return \View::make("admin.attendances.col4", [
"row" => $row, "clock_in" => $input_value_clock_in,
"clock_out" => $input_value_clock_out])->render();
})
->addColumn('action', function ($row) {
return '<button type="button" class="btn blue btn-sm" id="update_row' . $row->id . '" onclick="attendanceRow(\'' . $row->id . '\')"><i class="fa fa-check"></i></button>';
})
->removeColumn('leaveType')
->removeColumn('id')
->removeColumn('halfDayType')
->removeColumn('application_status')
->removeColumn('applied_on')
->removeColumn('clock_out')
->removeColumn('clock_in_ip_address')
->removeColumn('clock_out_ip_address')
->removeColumn('is_late')
->removeColumn('reason')
->removeColumn('notes')
->removeColumn('working_from')
->rawColumns(['eID', 'status', 'date', 'clock_in', 'action'])
->make();
}
public function filterAttendance(Request $request)
{
$employees = Employee::with(['attendance' => function($query) use($request) {
$query->whereRaw('MONTH(date) = ?', [$request->month])->whereRaw('YEAR(date) = ?', [$request->year]);
}]);
if($request->employee_id == 'all') {
$employees = $employees->get();
} else {
$employees = $employees->where('id', $request->employee_id)->get();
}
$final = [];
$this->daysInMonth = cal_days_in_month(CAL_GREGORIAN, $request->month, $request->year);
foreach($employees as $employee) {
$final[$employee->id.'#'.$employee->full_name] = array_fill(1, $this->daysInMonth, '-');
foreach($employee->attendance as $attendance) {
$final[$employee->id.'#'.$employee->full_name][Carbon::parse($attendance->date)->day] =
($attendance->status == 'absent') ?
'<i class="fa fa-close text-danger"></i>' :
'<i class="fa fa-check text-success"></i>';
}
}
$this->employeeAttendence = $final;
$view = View::make('admin.attendances.load', $this->data)->render();
return Reply::successWithDataNew($view);
}
}