180 lines
5.4 KiB
PHP
180 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Exports\AdherencePobDriveExport;
|
|
use App\Http\Requests\LambdaRequest;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
class AdherencepobdrivereportController extends Controller
|
|
{
|
|
private const REPORT_START = '2026-04-01';
|
|
|
|
public function __construct()
|
|
{
|
|
$this->_service = 'reports';
|
|
$this->_module = 'team2_reports';
|
|
$this->_viewname = 'adherencepobdrivereport';
|
|
$this->_title = 'Adherence Pack POB Drive';
|
|
$this->_base_url = '/adherencepobdrivereport';
|
|
}
|
|
|
|
public static function canDownload($user): bool
|
|
{
|
|
if (!$user || ($user->domain ?? '') !== 'team2') {
|
|
return false;
|
|
}
|
|
|
|
$permissions = json_decode($user->permissions ?? '[]');
|
|
if (is_array($permissions) && in_array('all_data_access', $permissions, true)) {
|
|
return true;
|
|
}
|
|
|
|
$designation = strtoupper(trim(self::tokenDesignation($user->access_token ?? '')));
|
|
|
|
return $designation === 'HO' || $designation === 'ADMIN';
|
|
}
|
|
|
|
public function list(Request $request)
|
|
{
|
|
return redirect($this->_base_url . '/report');
|
|
}
|
|
|
|
public function report(Request $request)
|
|
{
|
|
$this->assertCanDownload();
|
|
$months = $this->monthChoices();
|
|
$selected = trim((string) $request->query('month', ''));
|
|
if (!in_array($selected, $months, true)) {
|
|
$selected = $this->currentMonth();
|
|
}
|
|
|
|
$reportError = session('reportError');
|
|
$sections = [];
|
|
try {
|
|
$data = $this->fetchReport($selected);
|
|
$export = new AdherencePobDriveExport($data, $selected);
|
|
if (!method_exists($export, 'sections')) {
|
|
throw new \RuntimeException('The report view is out of date. Deploy app/Exports/AdherencePobDriveExport.php and reload PHP.');
|
|
}
|
|
$sections = $export->sections();
|
|
} catch (\Throwable $e) {
|
|
$reportError = $e->getMessage();
|
|
}
|
|
|
|
return $this->view('report')->with([
|
|
'title' => $this->_title,
|
|
'base_url' => $this->_base_url,
|
|
'months' => $months,
|
|
'selectedMonth' => $selected,
|
|
'reportError' => $reportError,
|
|
'sections' => $sections,
|
|
]);
|
|
}
|
|
|
|
public function export(Request $request)
|
|
{
|
|
$this->assertCanDownload();
|
|
$months = $this->monthChoices();
|
|
$month = trim((string) $request->query('month', ''));
|
|
if (!in_array($month, $months, true)) {
|
|
$month = $this->currentMonth();
|
|
}
|
|
|
|
try {
|
|
$data = $this->fetchReport($month);
|
|
} catch (\RuntimeException $e) {
|
|
return $this->backToReport($month, $e->getMessage());
|
|
}
|
|
|
|
return (new AdherencePobDriveExport($data, $month))->download();
|
|
}
|
|
|
|
/**
|
|
* @return object
|
|
*/
|
|
private function fetchReport(string $month)
|
|
{
|
|
$token = Auth::user()->access_token ?? '';
|
|
try {
|
|
$response = LambdaRequest::getrequest(
|
|
$this->_service,
|
|
$this->_module . '/adherence_report',
|
|
['month' => $month],
|
|
$token,
|
|
120
|
|
);
|
|
} catch (\Throwable $e) {
|
|
throw new \RuntimeException('Failed to load the adherence report.');
|
|
}
|
|
|
|
if (!is_object($response) || strtolower((string) ($response->status ?? '')) !== 'success' || !is_object($response->data ?? null)) {
|
|
$message = is_object($response) ? trim((string) ($response->message ?? '')) : '';
|
|
throw new \RuntimeException($message !== '' ? $message : 'Failed to load the adherence report.');
|
|
}
|
|
|
|
return $response->data;
|
|
}
|
|
|
|
/**
|
|
* @return array<int, string>
|
|
*/
|
|
private function monthChoices(): array
|
|
{
|
|
$cursor = new \DateTimeImmutable(self::REPORT_START);
|
|
$end = new \DateTimeImmutable('first day of this month');
|
|
$months = [];
|
|
while ($cursor <= $end) {
|
|
$months[] = $cursor->format('F Y');
|
|
$cursor = $cursor->modify('+1 month');
|
|
}
|
|
if ($months === []) {
|
|
$months[] = $this->currentMonth();
|
|
}
|
|
|
|
return $months;
|
|
}
|
|
|
|
private function currentMonth(): string
|
|
{
|
|
return date('F Y');
|
|
}
|
|
|
|
private function assertCanDownload(): void
|
|
{
|
|
if (!self::canDownload(Auth::user())) {
|
|
abort(403, 'You do not have access to this report.');
|
|
}
|
|
}
|
|
|
|
private function backToReport(string $month, string $message)
|
|
{
|
|
return redirect($this->_base_url . '/report?month=' . urlencode($month))->with('reportError', $message);
|
|
}
|
|
|
|
private static function tokenDesignation(string $token): string
|
|
{
|
|
$token = trim($token);
|
|
if (stripos($token, 'Bearer ') === 0) {
|
|
$token = trim(substr($token, 7));
|
|
}
|
|
$parts = explode('.', $token);
|
|
if (count($parts) < 2) {
|
|
return '';
|
|
}
|
|
$segment = strtr($parts[1], '-_', '+/');
|
|
$pad = strlen($segment) % 4;
|
|
if ($pad > 0) {
|
|
$segment .= str_repeat('=', 4 - $pad);
|
|
}
|
|
$payload = json_decode(base64_decode($segment));
|
|
$user = is_object($payload) ? ($payload->user ?? null) : null;
|
|
if (!is_object($user)) {
|
|
return '';
|
|
}
|
|
|
|
return (string) ($user->designation ?? '');
|
|
}
|
|
}
|