239 lines
12 KiB
PHP
239 lines
12 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Middleware;
|
|
|
|
use Illuminate\Http\Request;
|
|
use Inertia\Middleware;
|
|
use Modules\ApprovalWorkflow\Models\ApprovalChain;
|
|
use Modules\ContractorManagement\Models\Contractor;
|
|
use Modules\MaterialLogistics\Models\MaterialRequisition;
|
|
use Modules\MaterialLogistics\Models\PurchaseOrder;
|
|
use Modules\ProjectManagement\Models\Project;
|
|
|
|
class HandleInertiaRequests extends Middleware
|
|
{
|
|
/**
|
|
* The root template that is loaded on the first page visit.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $rootView = 'app';
|
|
|
|
/**
|
|
* Determine the current asset version.
|
|
*/
|
|
public function version(Request $request): ?string
|
|
{
|
|
return parent::version($request);
|
|
}
|
|
|
|
/**
|
|
* Define the props that are shared by default.
|
|
*
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function share(Request $request): array
|
|
{
|
|
return [
|
|
...parent::share($request),
|
|
'auth' => [
|
|
'user' => $request->user()?->load(['contractor', 'employeeProfile', 'customerProfile']),
|
|
'roles' => $request->user()?->getRoleNames() ?? [],
|
|
'permissions' => $request->user()?->getAllPermissions()->pluck('name') ?? [],
|
|
],
|
|
'flash' => [
|
|
'success' => $request->session()->get('success'),
|
|
'error' => $request->session()->get('error'),
|
|
],
|
|
'sidebarBadges' => fn () => $request->user() ? (function () use ($request) {
|
|
$user = $request->user();
|
|
|
|
// Drafts belong to their creator. Submitted requests are
|
|
// relevant only when the current user is an assigned approver.
|
|
$ownDraftRequisitions = MaterialRequisition::where('status', 'draft')
|
|
->where('requested_by', $user->id)
|
|
->count();
|
|
|
|
$assignedRequisitionApprovals = ApprovalChain::where('status', 'pending')
|
|
->where('type', 'material_requisition')
|
|
->whereHas('steps', function ($query) use ($user) {
|
|
$query->where('approver_id', $user->id)
|
|
->where('status', 'pending');
|
|
})
|
|
->count();
|
|
|
|
$ownDraftPurchaseOrders = PurchaseOrder::where('status', 'draft')
|
|
->where('requested_by', $user->id)
|
|
->count();
|
|
|
|
$isAdmin = $user->user_type === 'admin' || $user->hasRole(['Super Admin', 'admin', 'Main Contractor Admin']);
|
|
|
|
$assignedApprovalsQuery = ApprovalChain::where('status', 'pending')
|
|
->whereHas('steps', function ($query) use ($user) {
|
|
$query->where('approver_id', $user->id)
|
|
->where('status', 'pending');
|
|
});
|
|
|
|
if ($user->hasRole('Project Manager') && !$isAdmin) {
|
|
$assignedApprovalsQuery->where(function ($q) {
|
|
$q->whereNull('type')
|
|
->orWhere('type', '!=', 'project_estimation');
|
|
})->where('approvable_type', '!=', Project::class);
|
|
}
|
|
|
|
$assignedApprovals = $assignedApprovalsQuery->count();
|
|
|
|
return [
|
|
'pending_requisitions' => $ownDraftRequisitions + $assignedRequisitionApprovals,
|
|
'pending_purchase_orders' => $ownDraftPurchaseOrders,
|
|
'pending_approvals' => $assignedApprovals,
|
|
];
|
|
})() : null,
|
|
'projectOptions' => fn () => $request->user()
|
|
? Project::where('current_wizard_step', '>=', 7)
|
|
->with('parentProject:id,ulid,name,code')
|
|
->get(['id', 'ulid', 'name', 'code', 'project_type', 'parent_project_id', 'status'])
|
|
: [],
|
|
'unconfirmed_payments' => fn () => $request->user() ? (function () use ($request) {
|
|
$user = $request->user();
|
|
$isSiteOps = $user->hasAnyRole([
|
|
'Site Technical',
|
|
'Construction Supervisor',
|
|
'Site Operations',
|
|
'Site Engineer',
|
|
'Site Supervisor',
|
|
]);
|
|
if ($isSiteOps) {
|
|
return ['count' => 0, 'total_amount' => 0, 'items' => []];
|
|
}
|
|
|
|
$userType = strtolower($user->user_type ?? '');
|
|
$roles = strtolower($user->getRoleNames()->implode(','));
|
|
$isExecutive = in_array($userType, ['admin', 'super_admin', 'project_manager'])
|
|
|| $user->hasAnyRole(['Super Admin', 'admin', 'Admin', 'Project Manager', 'Executive']);
|
|
|
|
$visibleProjectIds = Project::query()->pluck('projects.id')->all();
|
|
|
|
$pendingInvoices = \Modules\FinancialManagement\Models\FinancialInvoice::with('project:id,name,code')
|
|
->whereIn('project_id', $visibleProjectIds)
|
|
->where('status', 'payment_sent')
|
|
->get(['id', 'ulid', 'invoice_number', 'project_id', 'total_amount', 'retention_amount', 'status', 'payment_proof_path', 'payment_proof_name', 'payment_proof_submitted_at'])
|
|
->map(fn ($inv) => [
|
|
'id' => 'inv_' . $inv->id,
|
|
'ulid' => $inv->ulid,
|
|
'number' => $inv->invoice_number,
|
|
'project_name' => $inv->project?->name ?? 'Project',
|
|
'amount' => (float) $inv->total_amount,
|
|
'retention_amount' => (float) $inv->retention_amount,
|
|
'has_proof' => !empty($inv->payment_proof_path),
|
|
'proof_name' => $inv->payment_proof_name,
|
|
'type' => 'invoice',
|
|
'confirm_url' => route('finance.receive-payment', $inv->ulid),
|
|
'view_url' => route('finance.show', $inv->ulid),
|
|
]);
|
|
|
|
$pendingRetentions = \Modules\FinancialManagement\Models\RetentionEntry::with('project:id,name,code')
|
|
->whereIn('project_id', $visibleProjectIds)
|
|
->where('type', 'credit')
|
|
->whereIn('status', ['payment_sent', 'submitted'])
|
|
->get(['id', 'ulid', 'project_id', 'amount', 'status', 'description', 'media_path', 'media_original_name'])
|
|
->map(fn ($ret) => [
|
|
'id' => 'ret_' . $ret->id,
|
|
'ulid' => $ret->ulid,
|
|
'number' => 'Retention Release',
|
|
'project_name' => $ret->project?->name ?? 'Project',
|
|
'amount' => (float) $ret->amount,
|
|
'type' => 'retention',
|
|
'status' => $ret->status,
|
|
'confirm_url' => route('retention.confirm', $ret->ulid),
|
|
'view_url' => route('retention.index'),
|
|
]);
|
|
|
|
$merged = $pendingInvoices->concat($pendingRetentions);
|
|
return [
|
|
'count' => $merged->count(),
|
|
'total_amount' => (float) $merged->sum('amount'),
|
|
'items' => $merged->values()->all(),
|
|
];
|
|
})() : ['count' => 0, 'total_amount' => 0, 'items' => []],
|
|
'retention_reminders' => fn () => $request->user() ? (function () use ($request) {
|
|
$user = $request->user();
|
|
$isSiteOps = $user->hasAnyRole([
|
|
'Site Technical',
|
|
'Construction Supervisor',
|
|
'Site Operations',
|
|
'Site Engineer',
|
|
'Site Supervisor',
|
|
]);
|
|
if ($isSiteOps) {
|
|
return ['count' => 0, 'items' => []];
|
|
}
|
|
|
|
$userType = strtolower($user->user_type ?? '');
|
|
$roles = strtolower($user->getRoleNames()->implode(','));
|
|
$isExecutive = in_array($userType, ['admin', 'super_admin', 'project_manager'])
|
|
|| $user->hasAnyRole(['Super Admin', 'admin', 'Admin', 'Project Manager', 'Executive']);
|
|
|
|
$visibleProjectIds = Project::query()->pluck('projects.id')->all();
|
|
|
|
if ($isExecutive) {
|
|
// Remind Executive to check payment received when payment proof is submitted
|
|
$proofSubmittedInvoices = \Modules\FinancialManagement\Models\FinancialInvoice::with('project:id,name,code')
|
|
->whereIn('project_id', $visibleProjectIds)
|
|
->where('status', 'payment_sent')
|
|
->whereNotNull('payment_proof_submitted_at')
|
|
->get(['id', 'ulid', 'invoice_number', 'project_id', 'total_amount', 'retention_amount', 'penalty_amount', 'payment_proof_name', 'payment_proof_submitted_at'])
|
|
->map(fn ($inv) => [
|
|
'id' => 'inv_proof_' . $inv->id,
|
|
'ulid' => $inv->ulid,
|
|
'invoice_number' => $inv->invoice_number,
|
|
'project_name' => $inv->project?->name ?? 'Project',
|
|
'amount' => (float) $inv->total_amount,
|
|
'retention_amount' => (float) $inv->retention_amount + (float) $inv->penalty_amount,
|
|
'base_retention_amount' => (float) $inv->retention_amount,
|
|
'penalty_amount' => (float) $inv->penalty_amount,
|
|
'role_target' => 'executive',
|
|
'action_type' => 'check_payment_received',
|
|
'title' => 'Payment Received Check Needed',
|
|
'message' => "Contractor submitted payment proof for Invoice {$inv->invoice_number}. Please check and confirm receipt.",
|
|
'view_url' => route('finance.show', $inv->ulid),
|
|
]);
|
|
|
|
return [
|
|
'count' => $proofSubmittedInvoices->count(),
|
|
'items' => $proofSubmittedInvoices->values()->all(),
|
|
];
|
|
} else {
|
|
// Remind Contractor Admin to pay 10% and send payment proof for approved invoices
|
|
$awaitingProofInvoices = \Modules\FinancialManagement\Models\FinancialInvoice::with('project:id,name,code')
|
|
->whereIn('project_id', $visibleProjectIds)
|
|
->whereIn('status', ['approved', 'sent'])
|
|
->whereNull('payment_proof_submitted_at')
|
|
->get(['id', 'ulid', 'invoice_number', 'project_id', 'total_amount', 'retention_amount', 'penalty_amount', 'retention_rate'])
|
|
->map(fn ($inv) => [
|
|
'id' => 'inv_pay_' . $inv->id,
|
|
'ulid' => $inv->ulid,
|
|
'invoice_number' => $inv->invoice_number,
|
|
'project_name' => $inv->project?->name ?? 'Project',
|
|
'amount' => (float) $inv->total_amount,
|
|
'retention_amount' => (float) $inv->retention_amount + (float) $inv->penalty_amount,
|
|
'base_retention_amount' => (float) $inv->retention_amount,
|
|
'penalty_amount' => (float) $inv->penalty_amount,
|
|
'retention_rate' => (float) $inv->retention_rate,
|
|
'role_target' => 'contractor',
|
|
'action_type' => 'send_payment_proof',
|
|
'title' => '10% Payment & Proof Reminder',
|
|
'message' => "Invoice {$inv->invoice_number} is approved. Please remit the payment" . ((float) $inv->penalty_amount > 0 ? " (including penalty)" : "") . " and upload payment proof.",
|
|
'view_url' => route('finance.show', $inv->ulid),
|
|
]);
|
|
|
|
return [
|
|
'count' => $awaitingProofInvoices->count(),
|
|
'items' => $awaitingProofInvoices->values()->all(),
|
|
];
|
|
}
|
|
})() : ['count' => 0, 'items' => []],
|
|
];
|
|
}
|
|
}
|