From 5c4285c77eb3677699268ab81ccaa2f869c5a169 Mon Sep 17 00:00:00 2001 From: Daeng Deni Mardaeni Date: Tue, 13 Aug 2024 11:50:40 +0700 Subject: [PATCH] Feature #7 : Module Debitur --- app/Exports/DebitureExport.php | 81 ++++++ app/Http/Controllers/DebitureController.php | 169 ++++++++++++ app/Http/Requests/DebitureRequest.php | 50 ++++ app/Models/Debiture.php | 60 +++++ ...24_08_12_022026_create_debitures_table.php | 54 ++++ module.json | 60 ++--- resources/views/debitur/create.blade.php | 242 ++++++++++++++++++ resources/views/debitur/index.blade.php | 201 +++++++++++++++ routes/breadcrumbs.php | 14 + routes/web.php | 10 + 10 files changed, 897 insertions(+), 44 deletions(-) create mode 100644 app/Exports/DebitureExport.php create mode 100644 app/Http/Controllers/DebitureController.php create mode 100644 app/Http/Requests/DebitureRequest.php create mode 100644 app/Models/Debiture.php create mode 100644 database/migrations/2024_08_12_022026_create_debitures_table.php create mode 100644 resources/views/debitur/create.blade.php create mode 100644 resources/views/debitur/index.blade.php diff --git a/app/Exports/DebitureExport.php b/app/Exports/DebitureExport.php new file mode 100644 index 0000000..37cbc8c --- /dev/null +++ b/app/Exports/DebitureExport.php @@ -0,0 +1,81 @@ +get(); + } + + public function map($row) + : array + { + return [ + $row->id, + $row->branch->name . + $row->cif, + $row->nomor_rekening, + $row->name, + $row->npwp, + $row->nomor_id, + $row->email, + $row->phone, + $row->province->name, + $row->city->name, + $row->district->name, + $row->village->name, + $row->postal_code, + $row->address, + $row->registered_at, + $row->created_at + ]; + } + + public function headings() + : array + { + return [ + 'ID', + 'Branch', + 'CIF', + 'Nomor Rekening', + 'Name', + 'NPWP', + 'Nomor ID', + 'Email', + 'Phone', + 'Province', + 'City', + 'District', + 'Village', + 'Postal Code', + 'Address', + 'Registered At', + 'Created At' + ]; + } + + public function columnFormats() + : array + { + return [ + 'A' => NumberFormat::FORMAT_NUMBER, + 'C' => NumberFormat::FORMAT_NUMBER, + 'D' => NumberFormat::FORMAT_NUMBER, + 'F' => NumberFormat::FORMAT_NUMBER, + 'G' => NumberFormat::FORMAT_NUMBER, + 'P' => NumberFormat::FORMAT_DATE_DATETIME, + 'Q' => NumberFormat::FORMAT_DATE_DATETIME + + ]; + } + } diff --git a/app/Http/Controllers/DebitureController.php b/app/Http/Controllers/DebitureController.php new file mode 100644 index 0000000..e1c5432 --- /dev/null +++ b/app/Http/Controllers/DebitureController.php @@ -0,0 +1,169 @@ +validated(); + + if ($validate) { + try { + // Save to database + Debiture::create($validate); + return redirect() + ->route('debitur.index') + ->with('success', 'Debitur created successfully'); + } catch (Exception $e) { + return redirect() + ->route('debitur.create') + ->with('error', 'Failed to create debitur'); + } + } + } + + public function create() + { + $branches = Branch::all(); + $provinces = Province::all(); + return view('lpj::debitur.create', compact('branches', 'provinces')); + } + + public function edit($id) + { + $debitur = Debiture::find($id); + $branches = Branch::all(); + $provinces = Province::all(); + $cities = City::where('province_code', $debitur->province_code)->get(); + $districts = District::where('city_code', $debitur->city_code)->get(); + $villages = Village::where('district_code', $debitur->district_code)->get(); + return view('lpj::debitur.create', compact('debitur', 'branches', 'provinces', 'cities', 'districts', 'villages')); + } + + public function update(DebitureRequest $request, $id) + { + $validate = $request->validated(); + + if ($validate) { + try { + // Update in database + $debitur = Debiture::find($id); + $debitur->update($validate); + return redirect() + ->route('debitur.index') + ->with('success', 'Debitur updated successfully'); + } catch (Exception $e) { + return redirect() + ->route('debitur.edit', $id) + ->with('error', 'Failed to update debitur'); + } + } + } + + public function destroy($id) + { + try { + // Delete from database + $debitur = Debiture::find($id); + $debitur->delete(); + + echo json_encode(['success' => true, 'message' => 'Debitur deleted successfully']); + } catch (Exception $e) { + echo json_encode(['success' => false, 'message' => 'Failed to delete debitur']); + } + } + + public function dataForDatatables(Request $request) + { + if (is_null($this->user) || !$this->user->can('debitur.view')) { + //abort(403, 'Sorry! You are not allowed to view users.'); + } + + // Retrieve data from the database + $query = Debiture::query(); + + // Apply search filter if provided + if ($request->has('search') && !empty($request->get('search'))) { + $search = $request->get('search'); + $query->where(function ($q) use ($search) { + $q->where('cif', 'LIKE', "%$search%"); + $q->orWhere('name', 'LIKE', "%$search%"); + $q->orWhereRelation('branch', 'name', 'LIKE', "%$search%"); + $q->orWhere('address', 'LIKE', "%$search%"); + $q->orWhere('npwp', 'LIKE', "%$search%"); + $q->orWhere('nomor_id', 'LIKE', "%$search%"); + $q->orWhere('email', 'LIKE', "%$search%"); + $q->orWhere('phone', 'LIKE', "%$search%"); + $q->orWhere('nomor_rekening', 'LIKE', "%$search%"); + }); + } + + // Apply sorting if provided + if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) { + $order = $request->get('sortOrder'); + $column = $request->get('sortField'); + $query->orderBy($column, $order); + } + + // Get the total count of records + $totalRecords = $query->count(); + + // Apply pagination if provided + if ($request->has('page') && $request->has('size')) { + $page = $request->get('page'); + $size = $request->get('size'); + $offset = ($page - 1) * $size; // Calculate the offset + + $query->skip($offset)->take($size); + } + + // Get the filtered count of records + $filteredRecords = $query->count(); + + // Get the data for the current page + $data = $query->with('branch')->get(); + + // Calculate the page count + $pageCount = ceil($totalRecords / $request->get('size')); + + // Calculate the current page number + $currentPage = 0 + 1; + + // Return the response data as a JSON object + return response()->json([ + 'draw' => $request->get('draw'), + 'recordsTotal' => $totalRecords, + 'recordsFiltered' => $filteredRecords, + 'pageCount' => $pageCount, + 'page' => $currentPage, + 'totalCount' => $totalRecords, + 'data' => $data, + ]); + } + + public function export() + { + return Excel::download(new DebitureExport, 'debitur.xlsx'); + } + } diff --git a/app/Http/Requests/DebitureRequest.php b/app/Http/Requests/DebitureRequest.php new file mode 100644 index 0000000..1a71510 --- /dev/null +++ b/app/Http/Requests/DebitureRequest.php @@ -0,0 +1,50 @@ + 'required|exists:branches,id', + 'province_code' => 'nullable|exists:provinces,code', + 'city_code' => 'nullable|exists:cities,code', + 'district_code' => 'nullable|exists:districts,code', + 'village_code' => 'nullable|exists:villages,code', + 'nomor_rekening' => 'nullable|string|max:50', + 'name' => 'required', + 'registered_at' => 'nullable|date', + 'npwp' => 'nullable|string|max:16', + 'nomor_id' => 'nullable|string|max:16', + 'email' => 'nullable|email', + 'phone' => 'nullable|string|max:15', + 'address' => 'nullable|string', + 'postal_code' => 'nullable|string|max:10', + 'status' => 'nullable|boolean' + ]; + + if ($this->method() == 'PUT') { + $rules['cif'] = 'required|unique:debitures,cif,' . $this->id; + } else { + $rules['cif'] = 'required|unique:debitures,cif'; + } + + return $rules; + } + + /** + * Determine if the user is authorized to make this request. + */ + public function authorize() + : bool + { + return true; + } + } diff --git a/app/Models/Debiture.php b/app/Models/Debiture.php new file mode 100644 index 0000000..39b13d9 --- /dev/null +++ b/app/Models/Debiture.php @@ -0,0 +1,60 @@ +belongsTo(Branch::class, 'branch_id', 'id'); + } + + public function province() + { + return $this->belongsTo(Province::class, 'province_code', 'code'); + } + + public function city() + { + return $this->belongsTo(City::class, 'city_code', 'code'); + } + + public function district() + { + return $this->belongsTo(District::class, 'district_code', 'code'); + } + + public function village() + { + return $this->belongsTo(Village::class, 'village_code', 'code'); + } + + } diff --git a/database/migrations/2024_08_12_022026_create_debitures_table.php b/database/migrations/2024_08_12_022026_create_debitures_table.php new file mode 100644 index 0000000..31537aa --- /dev/null +++ b/database/migrations/2024_08_12_022026_create_debitures_table.php @@ -0,0 +1,54 @@ +id(); + $table->foreignIdFor(Branch::class)->constrained()->onDelete('cascade'); + $table->string('cif', 10)->unique(); + $table->string('name'); + $table->date('registered_at')->nullable(); + $table->string('npwp', 16)->nullable(); + $table->string('nomor_id', 16)->nullable(); + $table->string('email', 100)->nullable(); + $table->string('phone', 15)->nullable(); + $table->string('nomor_rekening', 50)->nullable(); + $table->string('province_code')->index(); + $table->string('city_code')->index(); + $table->string('district_code')->index(); + $table->string('village_code')->index(); + $table->string('postal_code', 5)->nullable(); + $table->text('address')->nullable(); + + $table->boolean('status')->default(true)->nullable(); + $table->timestamps(); + $table->timestamp('authorized_at')->nullable(); + $table->char('authorized_status', 1)->nullable(); + $table->softDeletes(); + + $table->unsignedBigInteger('created_by')->nullable(); + $table->unsignedBigInteger('updated_by')->nullable(); + $table->unsignedBigInteger('deleted_by')->nullable(); + $table->unsignedBigInteger('authorized_by')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down() + : void + { + Schema::dropIfExists('debitures'); + } + }; diff --git a/module.json b/module.json index 192773a..1e2c068 100644 --- a/module.json +++ b/module.json @@ -35,47 +35,24 @@ }, { "title": "Data Debitur", - "path": "", + "path": "debitur", "icon": "ki-filled ki-people text-lg", "classes": "", "attributes": [], "permission": "", "roles": [ "Administrator" - ], - "sub": [ - { - "title": "Debitur", - "path": "", - "classes": "", - "attributes": [], - "permission": "", - "roles": [] - }, - { - "title": "Pemilik Jaminan", - "path": "", - "classes": "", - "attributes": [], - "permission": "", - "roles": [] - }, - { - "title": "Jaminan", - "path": "", - "classes": "", - "attributes": [], - "permission": "", - "roles": [] - }, - { - "title": "Dokumen Jaminan", - "path": "", - "classes": "", - "attributes": [], - "permission": "", - "roles": [] - } + ] + }, + { + "title": "Authorization", + "path": "", + "icon": "ki-filled ki-some-files text-lg", + "classes": "", + "attributes": [], + "permission": "", + "roles": [ + "Administrator" ] }, { @@ -109,21 +86,16 @@ "attributes": [], "permission": "", "roles": [] - }, { + }, + { "title": "Mata Uang", "path": "basicdata.currency", "classes": "", "attributes": [], "permission": "", "roles": [] - }, { - "title": "Debitur", - "path": "", - "classes": "", - "attributes": [], - "permission": "", - "roles": [] - },{ + }, + { "title": "Jenis Fasilitas Kredit", "path": "basicdata.jenis-fasilitas-kredit", "classes": "", diff --git a/resources/views/debitur/create.blade.php b/resources/views/debitur/create.blade.php new file mode 100644 index 0000000..915ad9e --- /dev/null +++ b/resources/views/debitur/create.blade.php @@ -0,0 +1,242 @@ +@extends('layouts.main') + +@section('breadcrumbs') + {{ Breadcrumbs::render(request()->route()->getName()) }} +@endsection + +@section('content') +
+ @if(isset($debitur->id)) +
+ + @method('PUT') + @else + + @endif + @csrf +
+
+

+ {{ isset($debitur->id) ? 'Edit' : 'Tambah' }} Debitur +

+
+ Back +
+
+
+
+ +
+ + @error('branch_id') + {{ $message }} + @enderror +
+
+
+ +
+ + @error('cif') + {{ $message }} + @enderror +
+
+
+ +
+ + @error('nomor_rekening') + {{ $message }} + @enderror +
+
+
+ +
+ + @error('name') + {{ $message }} + @enderror +
+
+
+ +
+ + @error('nomor_id') + {{ $message }} + @enderror +
+
+
+ +
+ + @error('npwp') + {{ $message }} + @enderror +
+
+
+ +
+ + @error('email') + {{ $message }} + @enderror +
+
+
+ +
+ + @error('phone') + {{ $message }} + @enderror +
+
+
+ +
+
+
+ + @error('province_code') + {{ $message }} + @enderror +
+
+ + @error('city_code') + {{ $message }} + @enderror +
+
+
+
+ + @error('district_code') + {{ $message }} + @enderror +
+
+ + @error('district_code') + {{ $message }} + @enderror +
+
+ + @error('postal_code') + {{ $message }} + @enderror +
+
+
+ + @error('address') + {{ $message }} + @enderror +
+
+
+
+ +
+
+
+
+
+@endsection diff --git a/resources/views/debitur/index.blade.php b/resources/views/debitur/index.blade.php new file mode 100644 index 0000000..8b0b357 --- /dev/null +++ b/resources/views/debitur/index.blade.php @@ -0,0 +1,201 @@ +@extends('layouts.main') + +@section('breadcrumbs') + {{ Breadcrumbs::render('debitur') }} +@endsection + +@section('content') +
+
+
+

+ Daftar Debitur +

+ +
+
+
+ + + + + + + + + + + + + + + + +
+ + + Cif + + + Nomor Rekening + + + Debitur + + + Cabang + + + Nomor ID + + + NPWP + + + Email + + + Phone + + + Alamat + + Action
+
+ +
+
+
+@endsection + +@push('scripts') + + + +@endpush + diff --git a/routes/breadcrumbs.php b/routes/breadcrumbs.php index f6fffdc..bdfac0a 100644 --- a/routes/breadcrumbs.php +++ b/routes/breadcrumbs.php @@ -98,3 +98,17 @@ $trail->push('Edit Cabang'); }); + Breadcrumbs::for('debitur', function (BreadcrumbTrail $trail) { + $trail->push('Debitur', route('debitur.index')); + }); + + Breadcrumbs::for('debitur.create', function (BreadcrumbTrail $trail) { + $trail->parent('debitur'); + $trail->push('Tambah Debitur', route('debitur.create')); + }); + + Breadcrumbs::for('debitur.edit', function (BreadcrumbTrail $trail) { + $trail->parent('basicdata.branch'); + $trail->push('Edit Debitur'); + }); + diff --git a/routes/web.php b/routes/web.php index b8f160d..d504278 100644 --- a/routes/web.php +++ b/routes/web.php @@ -3,6 +3,7 @@ use Illuminate\Support\Facades\Route; use Modules\Lpj\Http\Controllers\BranchController; use Modules\Lpj\Http\Controllers\CurrencyController; + use Modules\Lpj\Http\Controllers\DebitureController; use Modules\Lpj\Http\Controllers\JenisAsetController; use Modules\Lpj\Http\Controllers\JenisFasilitasKreditController; use Modules\Lpj\Http\Controllers\JenisJaminanController; @@ -91,4 +92,13 @@ ] ]); }); + + Route::name('debitur.')->prefix('debitur')->group(function () { + Route::get('restore/{id}', [DebitureController::class, 'restore'])->name('restore'); + Route::get('datatables', [DebitureController::class, 'dataForDatatables']) + ->name('datatables'); + Route::get('export', [DebitureController::class, 'export'])->name('export'); + }); + + Route::resource('debitur', DebitureController::class); });