diff --git a/app/Http/Controllers/BuildingController.php b/app/Http/Controllers/BuildingController.php index e8dc00b..6712765 100644 --- a/app/Http/Controllers/BuildingController.php +++ b/app/Http/Controllers/BuildingController.php @@ -9,8 +9,11 @@ class BuildingController extends Controller { public function index() { - $buildings = Building::with('owner')->latest()->paginate(15); - return Inertia::render('Buildings/Index', ['buildings' => $buildings]); + $buildings = Building::with('owner') + ->when($request->search, fn($q) => $q->where('building_name', 'like', "%{$request->search}%")) + ->latest() + ->paginate(15); + return Inertia::render('Buildings/Index', ['buildings' => $buildings]); } public function create() diff --git a/app/Http/Controllers/OwnerContractController.php b/app/Http/Controllers/OwnerContractController.php index 25a80f3..4c3f3b5 100644 --- a/app/Http/Controllers/OwnerContractController.php +++ b/app/Http/Controllers/OwnerContractController.php @@ -3,6 +3,9 @@ namespace App\Http\Controllers; use App\Models\Contract; +use App\Models\Unit; +use App\Models\Owner; +use App\Models\Subunit; use Illuminate\Http\Request; use Inertia\Inertia; @@ -31,4 +34,75 @@ class OwnerContractController extends Controller $ownerContract->delete(); return redirect()->route('owner-contracts.index'); } + + + +// app/Http/Controllers/OwnerContractController.php - add these methods +public function create() +{ + $units = Unit::with('building')->get(); + $owners = Owner::all(); + $subunits = Subunit::all(); + + return Inertia::render('OwnerContracts/Create', [ + 'units' => $units, + 'owners' => $owners, + 'subunits' => $subunits + ]); +} + +public function store(Request $request) +{ + $validated = $request->validate([ + 'unit_id' => 'required|exists:units,id', + 'person_id' => 'required|exists:owners,id', + 'contract_type' => 'required', + 'contract_number' => 'required|unique:contracts', + 'ejari_no' => 'required', + 'start_date' => 'required|date', + 'end_date' => 'required|date', + 'duration_months' => 'required|integer', + 'total_amount' => 'required|numeric', + 'status' => 'required', + 'notes' => 'nullable', + 'subunit_ids' => 'nullable|array', + 'payments' => 'required|array' + ]); + + $contract = Contract::create($validated); + + if ($request->subunit_ids) { + $contract->subunits()->attach($request->subunit_ids); + } + + foreach ($request->payments as $payment) { + $contract->payments()->create($payment); + } + + return redirect()->route('owner-contracts.index'); +} + +public function renew(Contract $ownerContract) +{ + $units = Unit::with('building')->get(); + $owners = Owner::all(); + $subunits = Subunit::all(); + + $renewData = [ + 'unit_id' => $ownerContract->unit_id, + 'person_id' => $ownerContract->person_id, + 'ejari_no' => $ownerContract->ejari_no, + 'duration_months' => $ownerContract->duration_months, + 'total_amount' => $ownerContract->total_amount, + 'start_date' => $ownerContract->end_date->addDay()->format('Y-m-d'), + 'subunit_ids' => $ownerContract->subunits->pluck('id')->toArray() + ]; + + return Inertia::render('OwnerContracts/Create', [ + 'units' => $units, + 'owners' => $owners, + 'subunits' => $subunits, + 'renewData' => $renewData + ]); +} } diff --git a/app/Http/Controllers/OwnerController.php b/app/Http/Controllers/OwnerController.php index e2c6db7..1e22f47 100644 --- a/app/Http/Controllers/OwnerController.php +++ b/app/Http/Controllers/OwnerController.php @@ -6,11 +6,16 @@ use Inertia\Inertia; class OwnerController extends Controller { - public function index() - { - $owners = Owner::latest()->paginate(15); - return Inertia::render('Owners/Index', ['owners' => $owners]); - } +public function index(Request $request) +{ + $owners = Owner::when($request->search, fn($q) => + $q->where('name', 'like', "%{$request->search}%") + ->orWhere('phone', 'like', "%{$request->search}%") + ) + ->latest() + ->paginate(15); + return Inertia::render('Owners/Index', ['owners' => $owners]); +} public function create() { diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php index 15ee488..1305c61 100644 --- a/app/Http/Controllers/PaymentController.php +++ b/app/Http/Controllers/PaymentController.php @@ -6,14 +6,19 @@ use Inertia\Inertia; class PaymentController extends Controller { - public function index(Request $request) - { - $payments = Payment::with('contract.unit.building', 'contract.person') - ->when($request->status, fn($q) => $q->where('status', $request->status)) - ->when($request->type, fn($q) => $q->where('payment_type', $request->type)) - ->latest() - ->paginate(20); +public function index(Request $request) +{ + $payments = Payment::with('contract.unit.building', 'contract.person') + ->when($request->search, fn($q) => + $q->whereHas('contract', fn($q2) => + $q2->where('contract_number', 'like', "%{$request->search}%") + ) + ) + ->when($request->status, fn($q) => $q->where('status', $request->status)) + ->when($request->type, fn($q) => $q->where('payment_type', $request->type)) + ->latest() + ->paginate(20); - return Inertia::render('Payments/Index', ['payments' => $payments]); - } + return Inertia::render('Payments/Index', ['payments' => $payments]); +} } \ No newline at end of file diff --git a/app/Http/Controllers/SubunitController.php b/app/Http/Controllers/SubunitController.php index ed915e9..1b2bcc6 100644 --- a/app/Http/Controllers/SubunitController.php +++ b/app/Http/Controllers/SubunitController.php @@ -7,12 +7,18 @@ use Inertia\Inertia; class SubunitController extends Controller { - public function index() - { - $subunits = Subunit::with('unit.building')->latest()->paginate(15); - return Inertia::render('Subunits/Index', ['subunits' => $subunits]); - } - +public function index(Request $request) +{ + $subunits = Subunit::with('unit.building') + ->when($request->search, fn($q) => + $q->whereHas('unit.building', fn($q2) => + $q2->where('building_name', 'like', "%{$request->search}%") + ) + ) + ->latest() + ->paginate(15); + return Inertia::render('Subunits/Index', ['subunits' => $subunits]); +} public function create() { $units = Unit::with('building')->get(); diff --git a/app/Http/Controllers/TenantContractController.php b/app/Http/Controllers/TenantContractController.php index e916ca9..e05d73a 100644 --- a/app/Http/Controllers/TenantContractController.php +++ b/app/Http/Controllers/TenantContractController.php @@ -3,6 +3,9 @@ namespace App\Http\Controllers; use App\Models\Contract; +use App\Models\Unit; +use App\Models\Tenant; +use App\Models\Subunit; use Illuminate\Http\Request; use Inertia\Inertia; @@ -22,7 +25,7 @@ class TenantContractController extends Controller public function show(Contract $tenantContract) { - $tenantContract->load(['unit.building.owner', 'person', 'payments', 'subunits']); + $tenantContract->load(['unit.building.tenant', 'person', 'payments', 'subunits']); return Inertia::render('TenantContracts/Show', ['contract' => $tenantContract]); } @@ -31,4 +34,73 @@ class TenantContractController extends Controller $tenantContract->delete(); return redirect()->route('tenant-contracts.index'); } + +// app/Http/Controllers/tenantContractController.php - add these methods +public function create() +{ + $units = Unit::with('building')->get(); + $tenants = Tenant::all(); + $subunits = Subunit::all(); + + return Inertia::render('TenantContracts/Create', [ + 'units' => $units, + 'tenants' => $tenants, + 'subunits' => $subunits + ]); +} + +public function store(Request $request) +{ + $validated = $request->validate([ + 'unit_id' => 'required|exists:units,id', + 'person_id' => 'required|exists:tenants,id', + 'contract_type' => 'required', + 'contract_number' => 'required|unique:contracts', + 'ejari_no' => 'required', + 'start_date' => 'required|date', + 'end_date' => 'required|date', + 'duration_months' => 'required|integer', + 'total_amount' => 'required|numeric', + 'status' => 'required', + 'notes' => 'nullable', + 'subunit_ids' => 'nullable|array', + 'payments' => 'required|array' + ]); + + $contract = Contract::create($validated); + + if ($request->subunit_ids) { + $contract->subunits()->attach($request->subunit_ids); + } + + foreach ($request->payments as $payment) { + $contract->payments()->create($payment); + } + + return redirect()->route('tenant-contracts.index'); +} + +public function renew(Contract $tenantContract) +{ + $units = Unit::with('building')->get(); + $tenants = Tenant::all(); + $subunits = Subunit::all(); + + $renewData = [ + 'unit_id' => $tenantContract->unit_id, + 'person_id' => $tenantContract->person_id, + 'ejari_no' => $tenantContract->ejari_no, + 'duration_months' => $tenantContract->duration_months, + 'total_amount' => $tenantContract->total_amount, + 'start_date' => $tenantContract->end_date->addDay()->format('Y-m-d'), + 'subunit_ids' => $tenantContract->subunits->pluck('id')->toArray() + ]; + + return Inertia::render('TenantContracts/Create', [ + 'units' => $units, + 'tenants' => $tenants, + 'subunits' => $subunits, + 'renewData' => $renewData + ]); +} } \ No newline at end of file diff --git a/app/Http/Controllers/TenantController.php b/app/Http/Controllers/TenantController.php index dd04ab0..3896903 100644 --- a/app/Http/Controllers/TenantController.php +++ b/app/Http/Controllers/TenantController.php @@ -6,12 +6,16 @@ use Inertia\Inertia; class TenantController extends Controller { - public function index() - { - $tenants = Tenant::latest()->paginate(15); - return Inertia::render('Tenants/Index', ['tenants' => $tenants]); - } - +public function index(Request $request) +{ + $tenants = Tenant::when($request->search, fn($q) => + $q->where('name', 'like', "%{$request->search}%") + ->orWhere('phone', 'like', "%{$request->search}%") + ) + ->latest() + ->paginate(15); + return Inertia::render('Tenants/Index', ['tenants' => $tenants]); +} public function create() { return Inertia::render('Tenants/Create'); diff --git a/app/Http/Controllers/UnitController.php b/app/Http/Controllers/UnitController.php index 3c7175c..c7e8343 100644 --- a/app/Http/Controllers/UnitController.php +++ b/app/Http/Controllers/UnitController.php @@ -7,11 +7,18 @@ use Inertia\Inertia; class UnitController extends Controller { - public function index() - { - $units = Unit::with('building')->latest()->paginate(15); - return Inertia::render('Units/Index', ['units' => $units]); - } +public function index(Request $request) +{ + $units = Unit::with('building') + ->when($request->search, fn($q) => + $q->whereHas('building', fn($q2) => + $q2->where('building_name', 'like', "%{$request->search}%") + ) + ) + ->latest() + ->paginate(15); + return Inertia::render('Units/Index', ['units' => $units]); +} public function create() { diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index dfc0954..b679f8a 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -40,7 +40,7 @@ class DatabaseSeeder extends Seeder $building2 = Building::create(['owner_id' => $owner2->id, 'building_name' => 'Sky Tower', 'address' => 'Sheikh Zayed Road', 'city' => 'Dubai', 'status' => 'occupied']); // Units - $unit1 = Unit::create(['building_id' => $building1->id, 'unit_no' => '1205', 'floor_no' => '12', 'area_sqft' => 1200, 'assets' => ['AC', 'Fridge', 'Washing Machine'], 'status' => 'occupied']); + $unit1 = Unit::create(['building_id' => $building2->id, 'unit_no' => '1205', 'floor_no' => '12', 'area_sqft' => 1200, 'assets' => ['AC', 'Fridge', 'Washing Machine'], 'status' => 'occupied']); $unit2 = Unit::create(['building_id' => $building1->id, 'unit_no' => '805', 'floor_no' => '8', 'area_sqft' => 800, 'assets' => ['AC'], 'status' => 'occupied']); $unit3 = Unit::create(['building_id' => $building2->id, 'unit_no' => '305', 'floor_no' => '3', 'area_sqft' => 1500, 'assets' => ['AC', 'Fridge', 'Bed'], 'status' => 'vacant']); @@ -49,7 +49,7 @@ class DatabaseSeeder extends Seeder $sub2 = Subunit::create(['unit_id' => $unit1->id, 'subunit_no' => 'R2', 'subunit_type' => 'room', 'area_sqft' => 350, 'status' => 'vacant']); $sub3 = Subunit::create(['unit_id' => $unit2->id, 'subunit_no' => 'R1', 'subunit_type' => 'room', 'area_sqft' => 400, 'status' => 'occupied']); - // Owner Contracts + // Owner Contractss $ownerContract1 = Contract::create([ 'unit_id' => $unit1->id, 'person_id' => $owner1->id, diff --git a/resources/js/Layouts/AppLayout.vue b/resources/js/Layouts/AppLayout.vue index 90587a0..fd65877 100644 --- a/resources/js/Layouts/AppLayout.vue +++ b/resources/js/Layouts/AppLayout.vue @@ -1,24 +1,37 @@ + -
+ +
+
+

Owner Contracts

+ + Add Contract + +
View +
- +
+ +
@@ -30,8 +38,10 @@ @@ -48,4 +58,10 @@ defineProps({ owners: Object }) const destroy = (id) => { if (confirm('Delete this owner?')) router.delete(route('owners.destroy', id)) } + +const search = ref('') + +const filterResults = () => { + router.get(route('owners.index'), { search: search.value }, { preserveState: true }) +} diff --git a/resources/js/Pages/Payments/Index.vue b/resources/js/Pages/Payments/Index.vue index 399b489..82cbcfa 100644 --- a/resources/js/Pages/Payments/Index.vue +++ b/resources/js/Pages/Payments/Index.vue @@ -8,22 +8,40 @@

All Payments

- +
+ +
- - + + + +
@@ -101,4 +119,10 @@ const filter = () => { const formatDate = (date) => new Date(date).toLocaleDateString('en-GB') const formatMoney = (amount) => new Intl.NumberFormat('en-US').format(amount) + +const search = ref('') + +const filterResults = () => { + router.get(route('payments.index'), { search: search.value }, { preserveState: true }) +} \ No newline at end of file diff --git a/resources/js/Pages/Subunits/Index.vue b/resources/js/Pages/Subunits/Index.vue index 66e79f3..c6382d3 100644 --- a/resources/js/Pages/Subunits/Index.vue +++ b/resources/js/Pages/Subunits/Index.vue @@ -13,7 +13,15 @@ Add Subunit
- +
+ +
{{ owner.email }} {{ owner.nationality }} +
Edit +
@@ -35,10 +43,12 @@ - +
{{ subunit.subunit_type }} {{ subunit.area_sqft }} {{ subunit.status }} - Edit - - +
+ Edit + +
+
@@ -58,4 +68,10 @@ const destroy = (id) => { router.delete(route('subunits.destroy', id)) } } + +const search = ref('') + +const filterResults = () => { + router.get(route('subunits.index'), { search: search.value }, { preserveState: true }) +} \ No newline at end of file diff --git a/resources/js/Pages/TenantContracts/Create.vue b/resources/js/Pages/TenantContracts/Create.vue new file mode 100644 index 0000000..d88c52c --- /dev/null +++ b/resources/js/Pages/TenantContracts/Create.vue @@ -0,0 +1,230 @@ + + + \ No newline at end of file diff --git a/resources/js/Pages/TenantContracts/Index.vue b/resources/js/Pages/TenantContracts/Index.vue index 1ac91f7..bb8a32b 100644 --- a/resources/js/Pages/TenantContracts/Index.vue +++ b/resources/js/Pages/TenantContracts/Index.vue @@ -7,6 +7,13 @@
+
+

Tenant Contracts

+ + Add Contract + +
+
View +
- +
+ +
@@ -30,8 +38,10 @@ @@ -48,4 +58,10 @@ defineProps({ tenants: Object }) const destroy = (id) => { if (confirm('Delete this tenant?')) router.delete(route('tenants.destroy', id)) } + +const search = ref('') + +const filterResults = () => { + router.get(route('tenants.index'), { search: search.value }, { preserveState: true }) +} diff --git a/resources/js/Pages/Units/Index.vue b/resources/js/Pages/Units/Index.vue index 4db0da3..1ae4284 100644 --- a/resources/js/Pages/Units/Index.vue +++ b/resources/js/Pages/Units/Index.vue @@ -14,6 +14,16 @@ +
+ +
+
{{ tenant.email }} {{ tenant.nationality }} +
Edit +
@@ -34,8 +44,10 @@ @@ -56,4 +68,10 @@ const destroy = (id) => { router.delete(route('units.destroy', id)) } } + +const search = ref('') + +const filterResults = () => { + router.get(route('units.index'), { search: search.value }, { preserveState: true }) +} \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index cab1787..06c74ed 100644 --- a/routes/web.php +++ b/routes/web.php @@ -30,4 +30,8 @@ Route::middleware('auth')->group(function () { Route::resource('tenants', TenantController::class); Route::resource('payments', PaymentController::class); + + // routes/web.php - add these routes +Route::get('owner-contracts/{contract}/renew', [OwnerContractController::class, 'renew'])->name('owner-contracts.renew'); +Route::get('tenant-contracts/{contract}/renew', [TenantContractController::class, 'renew'])->name('tenant-contracts.renew'); }); \ No newline at end of file
{{ unit.area_sqft }} {{ unit.status }} +
Edit +