329 lines
15 KiB
PHP
329 lines
15 KiB
PHP
@extends('layouts.admin')
|
|
|
|
@section('title', 'Manajemen Biaya Operasional')
|
|
|
|
@section('content')
|
|
<style>
|
|
.page-header {
|
|
background: linear-gradient(90deg, #ff8a00 0%, #ff5e00 100%);
|
|
color: white;
|
|
padding: 30px;
|
|
border-radius: 15px;
|
|
margin-top: 20px;
|
|
margin-bottom: 30px;
|
|
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
|
|
}
|
|
.page-header h1 { font-weight: 700; font-size: 2rem; margin-bottom: 5px; display: flex; align-items: center; }
|
|
.page-header h1 i { margin-right: 15px; }
|
|
.page-header p { opacity: 0.9; margin-bottom: 0; }
|
|
.custom-card { border-radius: 15px; border: none; box-shadow: 0 4px 12px rgba(0,0,0,0.05); overflow: hidden; }
|
|
.btn-custom { border-radius: 10px; padding: 8px 20px; font-weight: 600; transition: all 0.3s; }
|
|
.header-btn { background: rgba(255,255,255,0.2); border: 1px solid rgba(255,255,255,0.4); color: white; }
|
|
.header-btn:hover { background: white; color: #ff5e00; }
|
|
@media (max-width: 768px) {
|
|
.page-header { padding: 20px; }
|
|
.page-header .d-flex.justify-content-between {
|
|
flex-direction: column;
|
|
align-items: flex-start !important;
|
|
gap: 15px;
|
|
}
|
|
.header-btn { width: 100%; text-align: center; }
|
|
}
|
|
</style>
|
|
|
|
<div class="container-fluid px-4">
|
|
<div class="page-header shadow">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h1><i class="fas fa-wallet"></i> Manajemen Biaya Operasional</h1>
|
|
<p>Input pengeluaran listrik, gaji, air, dan operasional cabang lainnya</p>
|
|
</div>
|
|
<button type="button" class="btn btn-custom header-btn" onclick="openAddModal()">
|
|
<i class="fas fa-plus mr-2"></i> Input Biaya Baru
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filter Section -->
|
|
<div class="card custom-card mb-4 mt-2">
|
|
<div class="card-body p-3 shadow-sm">
|
|
<form action="{{ url()->current() }}" method="GET" class="row align-items-end">
|
|
<div class="col-md-3">
|
|
<label class="small font-weight-bold text-muted"><i class="fas fa-calendar-alt mr-1"></i> Tahun</label>
|
|
<select name="year" class="form-control form-control-sm">
|
|
<option value="">Semua Tahun</option>
|
|
@for($y = date('Y'); $y >= 2020; $y--)
|
|
<option value="{{ $y }}" {{ request('year') == $y ? 'selected' : '' }}>{{ $y }}</option>
|
|
@endfor
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="small font-weight-bold text-muted"><i class="fas fa-moon mr-1"></i> Bulan</label>
|
|
<select name="month" class="form-control form-control-sm">
|
|
<option value="">Semua Bulan</option>
|
|
@php
|
|
$months = ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'];
|
|
@endphp
|
|
@foreach($months as $i => $m)
|
|
<option value="{{ $i + 1 }}" {{ request('month') == ($i + 1) ? 'selected' : '' }}>{{ $m }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="small font-weight-bold text-muted"><i class="fas fa-store mr-1"></i> Cabang</label>
|
|
<select name="branch" class="form-control form-control-sm">
|
|
<option value="Semua Cabang">Semua Cabang</option>
|
|
@foreach($branches as $b)
|
|
<option value="{{ $b->name }}" {{ request('branch') == $b->name ? 'selected' : '' }}>{{ $b->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="btn-group btn-group-sm w-100">
|
|
<button type="submit" class="btn btn-warning text-white">
|
|
<i class="fas fa-check-circle mr-1"></i> Filter
|
|
</button>
|
|
<a href="{{ url()->current() }}" class="btn btn-secondary">
|
|
<i class="fas fa-undo mr-1"></i> Reset
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Alert -->
|
|
@if(session('success'))
|
|
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
|
{{ session('success') }}
|
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
@endif
|
|
|
|
@if($errors->any())
|
|
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
|
<ul class="mb-0">
|
|
@foreach($errors->all() as $error)
|
|
<li>{{ $error }}</li>
|
|
@endforeach
|
|
</ul>
|
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
@endif
|
|
|
|
<!-- Tabel Data -->
|
|
<div class="card custom-card">
|
|
<div class="card-header bg-white p-3 border-0">
|
|
<h5 class="mb-0 font-weight-bold"><i class="fas fa-list mr-2 text-warning"></i> Riwayat Biaya Operasional</h5>
|
|
</div>
|
|
<div class="card-body table-responsive p-0">
|
|
<table class="table table-hover table-striped text-nowrap mb-0">
|
|
<thead class="bg-light text-muted">
|
|
<tr>
|
|
<th width="15%" class="pl-4">Tanggal</th>
|
|
<th width="20%">Cabang</th>
|
|
<th width="35%">Keterangan Biaya</th>
|
|
<th width="15%">Nominal</th>
|
|
<th width="15%" class="text-center pr-4">Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse($costs as $cost)
|
|
<tr>
|
|
<td class="pl-4 font-weight-bold">{{ \Carbon\Carbon::parse($cost->date)->format('d M Y') }}</td>
|
|
<td><span class="badge badge-info">{{ $cost->branch }}</span></td>
|
|
<td>{{ $cost->label }}</td>
|
|
<td class="font-weight-bold text-danger">-Rp{{ number_format($cost->amount, 0, ',', '.') }}</td>
|
|
<td class="text-center pr-4">
|
|
<button class="btn btn-sm btn-outline-primary rounded-circle" onclick='editCost(@json($cost))' title="Edit">
|
|
<i class="fas fa-edit"></i>
|
|
</button>
|
|
<form action="/biaya-operasional/{{ $cost->id }}" method="POST" class="d-inline">
|
|
@csrf
|
|
@method('DELETE')
|
|
<button type="submit" class="btn btn-sm btn-outline-danger rounded-circle" onclick="return confirm('Hapus pengeluaran operasional ini?')" title="Hapus">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="5" class="text-center py-4 text-muted">
|
|
<i class="fas fa-folder-open fa-3x mb-3 opacity-50"></i>
|
|
<p class="mb-0">Belum ada data biaya operasional yang tercatat.</p>
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal Form -->
|
|
<div class="modal fade" id="modalCost" tabindex="-1" role="dialog" aria-labelledby="modalCostLabel" aria-hidden="true">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content custom-card">
|
|
<div class="modal-header text-white" style="background: linear-gradient(90deg, #ff8a00 0%, #ff5e00 100%); border: none;">
|
|
<h5 class="modal-title font-weight-bold" id="modalCostLabel">
|
|
<i class="fas fa-wallet mr-2"></i> Form Biaya Operasional
|
|
</h5>
|
|
<button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<form id="costForm" method="POST">
|
|
@csrf
|
|
<div class="modal-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="tanggal">📅 Tanggal</label>
|
|
<input type="date" class="form-control" name="date" id="tanggal" required>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="branch">🏢 Cabang</label>
|
|
<select class="form-control" name="branch" id="branch" required>
|
|
@foreach($branches as $b)
|
|
<option value="{{ $b->name }}">{{ $b->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="label_select">📝 Keterangan Pengeluaran</label>
|
|
<select class="form-control" id="label_select" name="label" onchange="handleLabelChange()" required>
|
|
<option value="" disabled selected>-- Pilih Keterangan --</option>
|
|
@foreach($labels as $lbl)
|
|
<option value="{{ $lbl }}">{{ $lbl }}</option>
|
|
@endforeach
|
|
<option value="lainnya">+ Lainnya (Input Manual)...</option>
|
|
</select>
|
|
<input type="text" class="form-control mt-2" id="label_input" style="display:none;" placeholder="Contoh: Gaji Karyawan, Pembayaran Listrik" disabled required>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="amount">💰 Nominal (Rp)</label>
|
|
<input type="number" class="form-control" name="amount" id="amount" required placeholder="1000" min="1000" oninput="if(this.value.startsWith('0')) this.value = this.value.replace(/^0+/, '');" onkeypress="if(this.value.length == 0 && event.key == '0') return false;">
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer border-0">
|
|
<button type="button" class="btn btn-custom btn-secondary" data-dismiss="modal">Batal</button>
|
|
<button type="submit" class="btn btn-custom text-white" style="background-color: #ff5e00;" id="saveButton">Simpan</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@push('scripts')
|
|
<script>
|
|
const form = document.getElementById('costForm');
|
|
|
|
form.addEventListener('submit', function(e) {
|
|
const amountInput = document.getElementById('amount');
|
|
const amountValue = amountInput.value.toString();
|
|
|
|
if (amountValue && parseInt(amountValue) < 1000) {
|
|
e.preventDefault();
|
|
alert('Nominal minimal adalah Rp 1.000!');
|
|
amountInput.focus();
|
|
return false;
|
|
}
|
|
|
|
if (amountValue && amountValue.startsWith('0')) {
|
|
e.preventDefault();
|
|
alert('Nominal tidak boleh diawali dengan angka 0!');
|
|
amountInput.focus();
|
|
return false;
|
|
}
|
|
});
|
|
|
|
window.openAddModal = function() {
|
|
form.reset();
|
|
form.action = '/biaya-operasional';
|
|
|
|
const methodInput = form.querySelector('input[name="_method"]');
|
|
if (methodInput) methodInput.remove();
|
|
|
|
document.getElementById('modalCostLabel').innerHTML = '<i class="fas fa-plus-circle mr-2"></i> Tambah Pengeluaran Baru';
|
|
document.getElementById('saveButton').innerText = 'Simpan';
|
|
document.getElementById('tanggal').value = new Date().toISOString().split('T')[0];
|
|
|
|
document.getElementById('label_select').value = '';
|
|
handleLabelChange();
|
|
|
|
$('#modalCost').modal('show');
|
|
}
|
|
|
|
function handleLabelChange() {
|
|
const select = document.getElementById('label_select');
|
|
const input = document.getElementById('label_input');
|
|
|
|
if (select.value === 'lainnya') {
|
|
select.removeAttribute('name');
|
|
input.setAttribute('name', 'label');
|
|
input.style.display = 'block';
|
|
input.disabled = false;
|
|
input.focus();
|
|
} else {
|
|
input.removeAttribute('name');
|
|
select.setAttribute('name', 'label');
|
|
input.style.display = 'none';
|
|
input.disabled = true;
|
|
}
|
|
}
|
|
|
|
window.editCost = function(cost) {
|
|
form.action = '/biaya-operasional/' + cost.id;
|
|
|
|
if (!form.querySelector('input[name="_method"]')) {
|
|
const input = document.createElement('input');
|
|
input.type = 'hidden';
|
|
input.name = '_method';
|
|
input.value = 'PUT';
|
|
form.appendChild(input);
|
|
}
|
|
|
|
document.getElementById('tanggal').value = cost.date;
|
|
document.getElementById('branch').value = cost.branch;
|
|
|
|
const select = document.getElementById('label_select');
|
|
const input = document.getElementById('label_input');
|
|
|
|
let optionExists = false;
|
|
for (let i = 0; i < select.options.length; i++) {
|
|
if (select.options[i].value === cost.label) {
|
|
optionExists = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (optionExists) {
|
|
select.value = cost.label;
|
|
handleLabelChange();
|
|
} else {
|
|
select.value = 'lainnya';
|
|
handleLabelChange();
|
|
input.value = cost.label;
|
|
}
|
|
|
|
document.getElementById('amount').value = cost.amount;
|
|
|
|
document.getElementById('modalCostLabel').innerHTML = '<i class="fas fa-edit mr-2"></i> Edit Pengeluaran';
|
|
document.getElementById('saveButton').innerText = 'Update Data';
|
|
$('#modalCost').modal('show');
|
|
}
|
|
</script>
|
|
@endpush
|
|
@endsection
|