diff --git a/app/Http/Controllers/Admin/Finance/DebtController.php b/app/Http/Controllers/Admin/Finance/DebtController.php new file mode 100644 index 0000000..9bb5def --- /dev/null +++ b/app/Http/Controllers/Admin/Finance/DebtController.php @@ -0,0 +1,127 @@ + 'Kasbon', + 'debts' => Debt::with(['user', 'user.biography']) + ->when(auth()->user()->role_id === 4, function ($query) { + return $query->where('user_id', auth()->id()); + }) + ->latest() + ->get(), + 'employees' => User::with('biography')->barbershop()->latest()->get(), + ]); + } + + public function store(DebtRequest $request): RedirectResponse + { + $validatedData = $request->validated(); + $barbershopId = Auth::user()->barbershop_id; + $barbershop = Barbershop::findOrFail($barbershopId); + $user = User::findOrFail($validatedData['employee']); + $transaction = Transaction::where('user_id', $user->id)->where('is_paid', '0')->first(); + + $transactionAmount = $transaction ? $transaction->total : 0; + $maxDebt = $user->base_salary + (0.5 * $transactionAmount); + + if ($barbershop->cash < $validatedData['amount']) { + notify()->error('Kas tidak cukup untuk melakukan transaksi ini', 'Gagal'); + + return back()->withInput(); + } + + if ($validatedData['amount'] > $maxDebt) { + notify()->error('Jumlah utang tidak boleh lebih dari gaji pokok + 50% dari transaksi karyawan. Maksimal kasbon: '.formatToRupiah($maxDebt), 'Gagal'); + + return back()->withInput(); + } + + DB::transaction(function () use ($validatedData, $barbershop) { + Debt::create([ + 'user_id' => $validatedData['employee'], + 'amount' => $validatedData['amount'], + ]); + $barbershop->decrement('cash', $validatedData['amount']); + }); + + notify()->success('Data berhasil ditambahkan', 'Berhasil'); + + return back(); + } + + public function update(DebtRequest $request, Debt $debt): RedirectResponse + { + $validatedData = $request->validated(); + $barbershopId = Auth::user()->barbershop_id; + $barbershop = Barbershop::findOrFail($barbershopId); + $user = User::findOrFail($debt->user_id); + $transaction = Transaction::where('user_id', $user->id)->where('is_paid', '0')->first(); + + $transactionAmount = $transaction ? $transaction->total : 0; + $maxDebt = $user->base_salary + (0.5 * $transactionAmount); + + $amountDifference = $validatedData['amount'] - $debt->amount; + + if ($amountDifference > 0 && $barbershop->cash < $amountDifference) { + notify()->error('Kas tidak cukup untuk menambah jumlah utang', 'Gagal'); + + return back()->withInput(); + } + + if ($validatedData['amount'] > $maxDebt) { + notify()->error('Jumlah utang tidak boleh lebih dari gaji pokok + 50% dari transaksi karyawan. Maksimal utang: Rp '.number_format($maxDebt, 2), 'Gagal'); + + return back()->withInput(); + } + + DB::transaction(function () use ($validatedData, $debt, $barbershop, $amountDifference) { + $debt->update([ + 'user_id' => $validatedData['employee'], + 'amount' => $validatedData['amount'], + ]); + + if ($amountDifference !== 0) { + $barbershop->decrement('cash', $amountDifference); + } + }); + + notify()->success('Data berhasil diperbarui', 'Berhasil'); + + return back(); + } + + public function delete(Debt $debt): RedirectResponse + { + $barbershopId = Auth::user()->barbershop_id; + $barbershop = Barbershop::findOrFail($barbershopId); + + DB::transaction(function () use ($debt, $barbershop) { + $barbershop->increment('cash', $debt->amount); + + $debt->delete(); + }); + + notify()->success('Data berhasil dihapus', 'Berhasil'); + + return back(); + } +} diff --git a/app/Http/Requests/Admin/Finance/DebtRequest.php b/app/Http/Requests/Admin/Finance/DebtRequest.php new file mode 100644 index 0000000..df872dc --- /dev/null +++ b/app/Http/Requests/Admin/Finance/DebtRequest.php @@ -0,0 +1,39 @@ +merge([ + 'amount' => removeRupiahFormatting($this->amount), + ]); + } + + public function rules(): array + { + return [ + 'employee' => ['required', Rule::exists('users', 'id')], + 'amount' => ['required', 'numeric', 'min:0', 'max:99999999.99'], + ]; + } + + protected function failedValidation(Validator $validator): void + { + $this->handleValidationFailure($validator); + } +} diff --git a/app/Models/Debt.php b/app/Models/Debt.php new file mode 100644 index 0000000..e659152 --- /dev/null +++ b/app/Models/Debt.php @@ -0,0 +1,24 @@ +belongsTo(User::class); + } +} diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 12c50e6..663caf2 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -5,6 +5,7 @@ use App\Models\Barbershop; use App\Models\Cash; use App\Models\Customer; +use App\Models\Debt; use App\Models\Expense; use App\Models\Inventory; use App\Models\Payroll; @@ -37,6 +38,7 @@ public function boot(): void Route::bind('expense', fn (string $expense) => Expense::findOrFail(decryptId($expense))); Route::bind('payroll', fn (string $payroll) => Payroll::findOrFail(decryptId($payroll))); Route::bind('cash', fn (string $cash) => Cash::findOrFail(decryptId($cash))); + Route::bind('debt', fn (string $debt) => Debt::findOrFail(decryptId($debt))); Route::bind('inventory', fn (string $inventory) => Inventory::findOrFail(decryptId($inventory))); Route::bind('transaction', fn (string $transaction) => Transaction::findOrFail(decryptId($transaction))); Route::bind('application', fn (string $application) => Setting::findOrFail(decryptId($application))); diff --git a/database/migrations/2024_11_30_211848_create_debts_table.php b/database/migrations/2024_11_30_211848_create_debts_table.php new file mode 100644 index 0000000..6b79d2e --- /dev/null +++ b/database/migrations/2024_11_30_211848_create_debts_table.php @@ -0,0 +1,31 @@ +id(); + $table->foreignId('user_id')->constrained()->cascadeOnDelete(); + $table->decimal('amount', 10, 2); + $table->enum('is_paid', ['0', '1'])->comment('0:belum bayar 1:Sudah bayar')->default('0'); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('debts'); + } +}; diff --git a/public/assets/admin/js/custom/debt.js b/public/assets/admin/js/custom/debt.js new file mode 100644 index 0000000..7070e93 --- /dev/null +++ b/public/assets/admin/js/custom/debt.js @@ -0,0 +1,30 @@ +$(document).ready(function () { + $("#createModal").on("show.bs.modal", function (event) { + const button = $(event.relatedTarget); + const data = { + modalTitle: button.data("modal-title"), + url: button.data("url"), + method: button.data("method"), + + employee: button.data("employee"), + amount: button.data("amount"), + }; + + $(".modal-title").text(data.modalTitle); + $("#form").attr('action', data.url); + $("#form-method").val(data.method); + + if (data.method === 'put') { + $("#employee").val(data.employee).trigger('change'); + $("#amount").val(data.amount); + } + }); + + $('#createModal').on('hidden.bs.modal', function () { + const method = $("#form-method").val(); + if (method === 'put') { + $("#employee").val('').trigger('change'); + $("#amount").val(''); + } + }); +}); diff --git a/public/assets/admin/js/select2/select2-config.js b/public/assets/admin/js/select2/select2-config.js index aedc5c0..eb41b30 100644 --- a/public/assets/admin/js/select2/select2-config.js +++ b/public/assets/admin/js/select2/select2-config.js @@ -4,4 +4,11 @@ $(document).ready(function () { placeholder: '-- Pilih --', tags: true }); + + $('.select2-modal').select2({ + allowClear: true, + placeholder: '-- Pilih --', + tags: true, + dropdownParent: $('#form') + }); }) diff --git a/resources/views/pages/admin/finance/debts.blade.php b/resources/views/pages/admin/finance/debts.blade.php new file mode 100644 index 0000000..6501c23 --- /dev/null +++ b/resources/views/pages/admin/finance/debts.blade.php @@ -0,0 +1,152 @@ +@extends('layouts.admin') +@section('styles') + + +@endsection +@section('app') +
+
+
+ @if (in_array(auth()->user()->role_id, [1, 3, 4])) +
+
+ + Tambah + +
+
+ @endif +
+
+
+ + + + + + + + + @if (in_array(auth()->user()->role_id, [1, 3, 4])) + + @endif + + + + @foreach ($debts as $debt) + + + + + + + @if (in_array(auth()->user()->role_id, [1, 3, 4])) + + @endif + + @endforeach + +
NoPegawaiJumlahTanggalStatusAksi
{{ $loop->iteration }}{{ $debt->user->biography->full_name ?? '-deleted-' }}{{ formatToRupiah($debt->amount) ?? '-' }}{{ formatDateIndo($debt->created_at) }} + {!! $debt->is_paid === '1' + ? 'Lunas' + : 'Belum' !!} + +
    +
  • + + + +
  • + @if (auth()->user()->role_id === 1) +
  • +
    + @csrf + @method('delete') + + + +
    +
  • + @endif +
+
+
+
+
+
+
+ + +
+@endsection +@section('afterScripts') + + + + + + + + +@endsection diff --git a/resources/views/partials/admin/_sidebar.blade.php b/resources/views/partials/admin/_sidebar.blade.php index 0551a43..1063164 100644 --- a/resources/views/partials/admin/_sidebar.blade.php +++ b/resources/views/partials/admin/_sidebar.blade.php @@ -121,6 +121,13 @@ @endif +