diff --git a/Modules/ApprovalWorkflow/app/Services/ApprovalService.php b/Modules/ApprovalWorkflow/app/Services/ApprovalService.php index 2c4fe93..13c28f9 100644 --- a/Modules/ApprovalWorkflow/app/Services/ApprovalService.php +++ b/Modules/ApprovalWorkflow/app/Services/ApprovalService.php @@ -123,7 +123,7 @@ class ApprovalService } $isAdminOrPm = $approver->user_type === 'admin' - || $approver->hasRole(['Super Admin', 'admin', 'Main Contractor Admin', 'Project Manager', 'project_manager']) + || $approver->hasRole(['Super Admin', 'admin', 'Project Manager', 'project_manager']) || $approver->hasPermissionTo('approve_mr'); if ($step->approver_id !== $approver->id && !$isAdminOrPm) { diff --git a/Modules/BiddingManagement/resources/js/Pages/Bids/Form.tsx b/Modules/BiddingManagement/resources/js/Pages/Bids/Form.tsx index 3e81abe..06e075d 100644 --- a/Modules/BiddingManagement/resources/js/Pages/Bids/Form.tsx +++ b/Modules/BiddingManagement/resources/js/Pages/Bids/Form.tsx @@ -97,13 +97,13 @@ export default function Form({ projects, package: pkg }: Props) { - { if (v) setData('project_id', v); }} items={projects.map(p => ({ value: p.ulid, label: `${p.name} (${p.code})` }))}> {data.project_id ? (() => { const p = projects.find(p => p.ulid === data.project_id); - return p ? `${p.name} (${p.code})` : data.project_id; + return p ? `${p.name} (${p.code})` : 'Selected project'; })() : null} diff --git a/Modules/FinancialManagement/app/Http/Controllers/FinanceController.php b/Modules/FinancialManagement/app/Http/Controllers/FinanceController.php index 275c091..8264765 100644 --- a/Modules/FinancialManagement/app/Http/Controllers/FinanceController.php +++ b/Modules/FinancialManagement/app/Http/Controllers/FinanceController.php @@ -334,6 +334,20 @@ class FinanceController extends Controller return back()->with('success', 'Cash advance request approved.'); } + public function rejectCashAdvance(string $cashAdvance) + { + $user = auth()->user(); + $cashAdvance = \Modules\FinancialManagement\Models\CashAdvance::withoutGlobalScopes() + ->where('ulid', $cashAdvance)->firstOrFail(); + + if (! $this->canApproveCashAdvance($user)) { + return back()->with('error', 'Unauthorized to reject cash advance requests.'); + } + + $cashAdvance->update(['status' => 'rejected', 'approved_by' => $user->id]); + return back()->with('success', 'Cash advance request rejected.'); + } + private function canApproveCashAdvance(User $user): bool { return $user->user_type === 'admin' diff --git a/Modules/FinancialManagement/resources/js/Pages/CashAdvances/Index.tsx b/Modules/FinancialManagement/resources/js/Pages/CashAdvances/Index.tsx index 2af6d9c..365bfa3 100644 --- a/Modules/FinancialManagement/resources/js/Pages/CashAdvances/Index.tsx +++ b/Modules/FinancialManagement/resources/js/Pages/CashAdvances/Index.tsx @@ -1,6 +1,7 @@ import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout'; import { Head, router, useForm, usePage } from '@inertiajs/react'; import { Button } from '@/Components/ui/button'; +import { formatCurrency } from '@/lib/utils'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/Components/ui/card'; import { Input } from '@/Components/ui/input'; import { Label } from '@/Components/ui/label'; @@ -11,7 +12,7 @@ import { Badge } from '@/Components/ui/badge'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/Components/ui/dialog'; import { PageProps } from '@/types'; import { FormEvent, useState } from 'react'; -import { Wallet, Plus, CheckCircle2, DollarSign, Clock, FileText } from 'lucide-react'; +import { Wallet, Plus, CheckCircle2, XCircle, DollarSign, Clock, FileText } from 'lucide-react'; interface ProjectRef { id: number; @@ -71,6 +72,13 @@ export default function CashAdvancesIndex({ cashAdvances, projects }: Props) { }); }; + const handleReject = () => { + if (!selectedItemToApprove || !confirm('Reject this cash advance request?')) return; + router.patch(route('cash-advances.reject', selectedItemToApprove.ulid), {}, { + onSuccess: () => setSelectedItemToApprove(null), + }); + }; + return ( Cash Advances & Site Petty Cash} @@ -95,8 +103,12 @@ export default function CashAdvancesIndex({ cashAdvances, projects }: Props) {
- setData('project_ulid', v || '')} items={projects.map(p => ({ value: p.ulid, label: `${p.name} (${p.code})` }))}> + + + {projects.find((p) => p.ulid === data.project_ulid)?.name || 'Select Project'} + + {projects.map((p) => ( @@ -109,7 +121,7 @@ export default function CashAdvancesIndex({ cashAdvances, projects }: Props) {
- +

Amount

- ${Number(selectedItemToApprove.amount).toLocaleString('en-US', { minimumFractionDigits: 2 })} + {formatCurrency(selectedItemToApprove.amount)}

@@ -187,7 +199,10 @@ export default function CashAdvancesIndex({ cashAdvances, projects }: Props) { - + @@ -227,12 +242,12 @@ export default function CashAdvancesIndex({ cashAdvances, projects }: Props) { {ca.reason} - ${Number(ca.amount).toLocaleString('en-US', { minimumFractionDigits: 2 })} + {formatCurrency(ca.amount)} {ca.status.toUpperCase()} diff --git a/Modules/FinancialManagement/routes/web.php b/Modules/FinancialManagement/routes/web.php index 06b51ce..cfc49e6 100644 --- a/Modules/FinancialManagement/routes/web.php +++ b/Modules/FinancialManagement/routes/web.php @@ -26,4 +26,5 @@ Route::middleware(['web', 'auth'])->group(function () { Route::get('cash-advances', [FinanceController::class, 'cashAdvances'])->name('cash-advances.index'); Route::post('cash-advances', [FinanceController::class, 'storeCashAdvance'])->name('cash-advances.store'); Route::patch('cash-advances/{cashAdvance:ulid}/approve', [FinanceController::class, 'approveCashAdvance'])->name('cash-advances.approve'); + Route::patch('cash-advances/{cashAdvance:ulid}/reject', [FinanceController::class, 'rejectCashAdvance'])->name('cash-advances.reject'); }); diff --git a/Modules/MaterialLogistics/app/Http/Controllers/PurchaseOrderController.php b/Modules/MaterialLogistics/app/Http/Controllers/PurchaseOrderController.php index f09dc2d..fc5d28b 100644 --- a/Modules/MaterialLogistics/app/Http/Controllers/PurchaseOrderController.php +++ b/Modules/MaterialLogistics/app/Http/Controllers/PurchaseOrderController.php @@ -89,13 +89,10 @@ class PurchaseOrderController extends Controller 'project_manager', 'Super Admin', 'admin', - 'Main Contractor Admin', ]); }) ->orWhere('user_type', 'admin') - ->orWhereHas('permissions', function ($permissionQuery) { - $permissionQuery->where('name', 'approve_po'); - }); + ; }) ->where('status', 'active') ->pluck('id') @@ -342,13 +339,10 @@ class PurchaseOrderController extends Controller 'project_manager', 'Super Admin', 'admin', - 'Main Contractor Admin', ]); }) ->orWhere('user_type', 'admin') - ->orWhereHas('permissions', function ($permissionQuery) { - $permissionQuery->where('name', 'approve_po'); - }); + ; }) ->where('status', 'active') ->pluck('id') diff --git a/Modules/MaterialLogistics/resources/js/Pages/PurchaseOrders/Show.tsx b/Modules/MaterialLogistics/resources/js/Pages/PurchaseOrders/Show.tsx index cdb3ad8..8346701 100644 --- a/Modules/MaterialLogistics/resources/js/Pages/PurchaseOrders/Show.tsx +++ b/Modules/MaterialLogistics/resources/js/Pages/PurchaseOrders/Show.tsx @@ -211,7 +211,7 @@ export default function Show({ purchaseOrder, warehouses, budgetAnalysis }: Prop )} - {purchaseOrder.status === 'submitted' && (auth.user.user_type === 'admin' || auth.user.roles?.some((r: any) => ['Super Admin', 'admin', 'Project Manager', 'Main Contractor Admin'].includes(r.name))) && ( + {purchaseOrder.status === 'submitted' && (auth.user.user_type === 'admin' || auth.user.roles?.some((r: any) => ['Super Admin', 'admin', 'Project Manager'].includes(r.name))) && (