bug fixes, daily reports, holidays
This commit is contained in:
42
app/Http/Controllers/DailyReportController.php
Normal file
42
app/Http/Controllers/DailyReportController.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\DailyReport;
|
||||
use App\Models\ReportOverride;
|
||||
use App\Http\Requests\StoreDailyReportRequest;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use App\Mail\DailyReportSubmitted;
|
||||
|
||||
class DailyReportController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$reports = auth()->user()->dailyReports()
|
||||
->orderBy('report_date', 'desc')
|
||||
->paginate(15);
|
||||
|
||||
return view('reports.index', compact('reports'));
|
||||
}
|
||||
public function store(StoreDailyReportRequest $request)
|
||||
{
|
||||
$report = DailyReport::create([
|
||||
'user_id' => auth()->id(),
|
||||
'report_date' => $request->report_date,
|
||||
'content' => $request->content,
|
||||
]);
|
||||
|
||||
// If they used an override, optionally delete or mark it as used so it can't be reused
|
||||
ReportOverride::where('user_id', auth()->id())
|
||||
->where('report_date', $request->report_date)
|
||||
->delete();
|
||||
|
||||
$managementEmails = ['samuel@click-mobile.com'];
|
||||
Mail::to($managementEmails)->send(new DailyReportSubmitted($report, auth()->user()));
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Daily report submitted successfully.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ use App\Models\OfficeLocation;
|
||||
use App\Models\StaffMember;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Models\PublicHoliday;
|
||||
|
||||
|
||||
class OfficeLocationController extends Controller
|
||||
{
|
||||
@@ -114,5 +116,14 @@ class OfficeLocationController extends Controller
|
||||
|
||||
$document->delete();
|
||||
return response()->json(['success' => true, 'message' => 'Document deleted.']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Swift track malawi
|
||||
// eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI3MTYiLCJvaWQiOjcxNiwidWlkIjoiNDU3OTIzYzgtYmNkMS00ZWJhLWI3NzYtMGYyOTJmNmYzNWM4IiwiYXBpZCI6NTcxLCJpYXQiOjE3ODg1MzYwMzgsImV4cCI6MjEyODUzNjAzOH0.xbcNFzMNcryMACwYjOQMfF4Q06S80ttH4gYrcbduekTRXQcE4LptFEmir7iyeshghXy-C7Jcqno4UCKRIVnNig
|
||||
|
||||
|
||||
|
||||
// klick
|
||||
// eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI2OSIsIm9pZCI6NjksInVpZCI6IjEyMTdiMmE4LWNlYTYtNGE3ZC1hODlmLTFiODBhNDQxMzRjYSIsImFwaWQiOjQwMCwiaWF0IjoxNzI2NDc2MTc4LCJleHAiOjIwNjY0NzYxNzh9.7Yv2dyT3wEGz28ddFEMdEN0EsmD18hLSaHfNxIPCAskPjHFQ8819u5cLwfzNeZy5Xa3Xaz1ZNc66j0Fd8xSWDw
|
||||
@@ -30,6 +30,7 @@ class ProfileController extends Controller
|
||||
'photo' => 'nullable|image|mimes:jpg,jpeg,png|max:2048',
|
||||
]);
|
||||
// Combine month and day if both are provided (e.g., "12-25")
|
||||
|
||||
if (!empty($request->birth_month) && !empty($request->birth_day)) {
|
||||
$validated['dob'] = $request->birth_month . '-' . $request->birth_day;
|
||||
} else {
|
||||
@@ -52,8 +53,6 @@ class ProfileController extends Controller
|
||||
return response()->json(['success' => true, 'message' => 'Profile updated successfully!']);
|
||||
}
|
||||
|
||||
// --- DEPENDENTS / EMERGENCY CONTACTS CRUD ---
|
||||
|
||||
public function storeDependent(Request $request)
|
||||
{
|
||||
$staff = StaffMember::where('email', auth()->user()->email)->firstOrFail();
|
||||
|
||||
81
app/Http/Controllers/PublicHolidaysController.php
Normal file
81
app/Http/Controllers/PublicHolidaysController.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\OfficeLocation;
|
||||
use App\Models\PublicHoliday;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class PublicHolidaysController extends Controller
|
||||
{
|
||||
public function index($officeId)
|
||||
{
|
||||
$holidays = PublicHoliday::where('office_location_id', $officeId)
|
||||
->orderBy('holiday_date', 'asc')
|
||||
->get();
|
||||
|
||||
return response()->json($holidays);
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'office_location_id' => 'required|exists:office_locations,id',
|
||||
'name' => 'required|string|max:255',
|
||||
'holiday_date' => 'required|date',
|
||||
'is_recurring' => 'boolean',
|
||||
]);
|
||||
|
||||
$validated['is_recurring'] = $request->has('is_recurring');
|
||||
|
||||
PublicHoliday::create($validated);
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
|
||||
public function destroy(PublicHoliday $holiday)
|
||||
{
|
||||
$holiday->delete();
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
|
||||
public function importFromApi(Request $request, $officeId)
|
||||
{
|
||||
$location = OfficeLocation::findOrFail($officeId);
|
||||
$year = $request->input('year', now()->year);
|
||||
$countryCode = $request->input('country_code');
|
||||
|
||||
if (!$countryCode) {
|
||||
return response()->json(['success' => false, 'message' => 'Country code missing.'], 400);
|
||||
}
|
||||
|
||||
$response = Http::get("https://date.nager.at/api/v3/PublicHolidays/{$year}/{$countryCode}");
|
||||
|
||||
if ($response->successful()) {
|
||||
$apiHolidays = $response->json();
|
||||
$count = 0;
|
||||
|
||||
foreach ($apiHolidays as $holiday) {
|
||||
PublicHoliday::updateOrCreate(
|
||||
[
|
||||
'office_location_id' => $location->id,
|
||||
'holiday_date' => $holiday['date'],
|
||||
],
|
||||
[
|
||||
'name' => $holiday['name'],
|
||||
'is_recurring' => $holiday['fixed'] ?? false,
|
||||
]
|
||||
);
|
||||
$count++;
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => "Successfully imported {$count} holidays."
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json(['success' => false, 'message' => 'Failed to fetch from API.'], 500);
|
||||
}
|
||||
}
|
||||
41
app/Http/Controllers/ReportOverrideController.php
Normal file
41
app/Http/Controllers/ReportOverrideController.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\ReportOverride;
|
||||
use Illuminate\Http\Request;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class ReportOverrideController extends Controller
|
||||
{
|
||||
public function store(Request $request)
|
||||
{
|
||||
// Todo : Add middleware or policy checks for management
|
||||
|
||||
$request->validate([
|
||||
'user_id' => 'required|exists:staff_members,id',
|
||||
'report_date' => 'required|date',
|
||||
'hours_valid' => 'nullable|integer|min:1|max:72',
|
||||
]);
|
||||
|
||||
$hoursValid = (int) ($request->input('hours_valid') ?? 24);
|
||||
|
||||
ReportOverride::updateOrCreate(
|
||||
[
|
||||
'user_id' => $request->user_id,
|
||||
'report_date' => $request->report_date,
|
||||
],
|
||||
[
|
||||
'granted_by' => auth()->id(),
|
||||
'expires_at' => now()->addHours($hoursValid),
|
||||
// 'expires_at' => now()->addHours($request->hours_valid ?? 24),
|
||||
|
||||
]
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Late submission override granted successfully.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@ class StaffMembersController extends Controller
|
||||
{
|
||||
$query = StaffMember::query();
|
||||
|
||||
// 1. Search Filter
|
||||
if ($request->filled('search')) {
|
||||
$search = $request->search;
|
||||
$query->where(function($q) use ($search) {
|
||||
@@ -28,12 +27,11 @@ class StaffMembersController extends Controller
|
||||
});
|
||||
}
|
||||
|
||||
// 2. Department Filter
|
||||
if ($request->filled('department_id')) {
|
||||
$query->where('department_id', $request->department_id);
|
||||
}
|
||||
|
||||
// 3. Status Filter
|
||||
|
||||
if ($request->filled('status')) {
|
||||
$query->where('status', $request->status);
|
||||
}
|
||||
@@ -41,15 +39,19 @@ class StaffMembersController extends Controller
|
||||
$staffMembers = $query->orderBy('name', 'asc')->paginate(12);
|
||||
$staffMembers->appends($request->query());
|
||||
|
||||
// Fetch dynamic dropdown lists
|
||||
$departments = Department::orderBy('name', 'asc')->get();
|
||||
$countries = Country::orderBy('en_short_name', 'asc')->get();
|
||||
$allstaffMembers = StaffMember::orderBy('name')->get(['id', 'name']);
|
||||
|
||||
// dd($staffMembers);
|
||||
// dd(\Auth::user()->designation);
|
||||
$data = [
|
||||
'staffMembers' => $staffMembers,
|
||||
'departments' => $departments,
|
||||
'allstaffMembers' => $allstaffMembers,
|
||||
'countries' => $countries,
|
||||
];
|
||||
|
||||
|
||||
return view('staff.index', $data);
|
||||
}
|
||||
|
||||
48
app/Http/Requests/StoreDailyReportRequest.php
Normal file
48
app/Http/Requests/StoreDailyReportRequest.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\ReportOverride;
|
||||
|
||||
class StoreDailyReportRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'report_date' => 'required|date|before_or_equal:today',
|
||||
'content' => 'required|string',
|
||||
];
|
||||
}
|
||||
|
||||
public function withValidator($validator)
|
||||
{
|
||||
$validator->after(function ($validator) {
|
||||
$reportDate = Carbon::parse($this->report_date)->startOfDay();
|
||||
|
||||
// Calculate standard deadline: 48 hours from the end of the report date
|
||||
$deadline = $reportDate->copy()->endOfDay()->addHours(48);
|
||||
|
||||
if (now()->greaterThan($deadline)) {
|
||||
// Check if a valid override exists
|
||||
$hasOverride = ReportOverride::where('user_id', auth()->id())
|
||||
->where('report_date', $this->report_date)
|
||||
->where('expires_at', '>', now())
|
||||
->exists();
|
||||
|
||||
if (!$hasOverride) {
|
||||
$validator->errors()->add(
|
||||
'report_date',
|
||||
'The 48-hour submission window for this date has expired. Please contact management for an override.'
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user