update tgl 7 mei2
This commit is contained in:
parent
a2c3a61a32
commit
0be2b98301
|
@ -5,6 +5,11 @@
|
||||||
use App\Models\NeracasaldoModel;
|
use App\Models\NeracasaldoModel;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Maatwebsite\Excel\Facades\Excel;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
|
use App\Exports\NeracaSaldoExport;
|
||||||
|
|
||||||
class NeracasaldoController extends Controller
|
class NeracasaldoController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -144,4 +149,275 @@ public function show($id)
|
||||||
$transaksi = NeracasaldoModel::findOrFail($id);
|
$transaksi = NeracasaldoModel::findOrFail($id);
|
||||||
return view('neracasaldo.show', compact('transaksi'));
|
return view('neracasaldo.show', compact('transaksi'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function exportExcel(Request $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Ambil parameter filter tanggal jika ada
|
||||||
|
$startDate = $request->input('start_date', Carbon::now()->startOfMonth()->format('Y-m-d'));
|
||||||
|
$endDate = $request->input('end_date', Carbon::now()->endOfMonth()->format('Y-m-d'));
|
||||||
|
|
||||||
|
$rawTransaksis = NeracasaldoModel::whereBetween('Tanggal', [$startDate, $endDate])
|
||||||
|
->orderBy('kode', 'asc')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$processedData = [];
|
||||||
|
$totalsPerAkun = [];
|
||||||
|
$totalDebit = 0;
|
||||||
|
$totalKredit = 0;
|
||||||
|
|
||||||
|
// Proses data seperti di fungsi index
|
||||||
|
foreach ($rawTransaksis as $transaksi) {
|
||||||
|
$processAkun = function($kode, $kategori, $debit, $kredit) use (&$totalsPerAkun) {
|
||||||
|
if (!empty($kode) && !empty($kategori)) {
|
||||||
|
if (!isset($totalsPerAkun[$kategori])) {
|
||||||
|
$totalsPerAkun[$kategori] = [
|
||||||
|
'kode' => $kode,
|
||||||
|
'kategori' => $kategori,
|
||||||
|
'debit' => 0,
|
||||||
|
'kredit' => 0
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$totalsPerAkun[$kategori]['debit'] += floatval($debit ?? 0);
|
||||||
|
$totalsPerAkun[$kategori]['kredit'] += floatval($kredit ?? 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$processAkun($transaksi->kode, $transaksi->kategori, $transaksi->uang_masuk, $transaksi->uang_keluar);
|
||||||
|
$processAkun($transaksi->kode2, $transaksi->kategori2, $transaksi->uang_masuk2, $transaksi->uang_keluar2);
|
||||||
|
$processAkun($transaksi->kode3, $transaksi->kategori3, $transaksi->uang_masuk3, $transaksi->uang_keluar3);
|
||||||
|
$processAkun($transaksi->kode4, $transaksi->kategori4, $transaksi->uang_masuk4, $transaksi->uang_keluar4);
|
||||||
|
$processAkun($transaksi->kode5, $transaksi->kategori5, $transaksi->uang_masuk5, $transaksi->uang_keluar5);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($totalsPerAkun as $kategori => $data) {
|
||||||
|
$kodeAwal = substr($data['kode'], 0, 3);
|
||||||
|
$saldo = $data['debit'] - $data['kredit'];
|
||||||
|
|
||||||
|
if (in_array($kodeAwal, ['111', '112']) || in_array($kodeAwal, ['251', '252'])) {
|
||||||
|
if ($saldo != 0) {
|
||||||
|
$processedData[] = [
|
||||||
|
'kode' => $data['kode'],
|
||||||
|
'kategori' => $kategori,
|
||||||
|
'debit' => $saldo > 0 ? abs($saldo) : 0,
|
||||||
|
'kredit' => $saldo < 0 ? abs($saldo) : 0
|
||||||
|
];
|
||||||
|
$totalDebit += $saldo > 0 ? abs($saldo) : 0;
|
||||||
|
$totalKredit += $saldo < 0 ? abs($saldo) : 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($saldo != 0) {
|
||||||
|
$processedData[] = [
|
||||||
|
'kode' => $data['kode'],
|
||||||
|
'kategori' => $kategori,
|
||||||
|
'debit' => $saldo < 0 ? abs($saldo) : 0,
|
||||||
|
'kredit' => $saldo > 0 ? abs($saldo) : 0
|
||||||
|
];
|
||||||
|
$totalDebit += $saldo < 0 ? abs($saldo) : 0;
|
||||||
|
$totalKredit += $saldo > 0 ? abs($saldo) : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tambahkan baris total
|
||||||
|
$processedData[] = [
|
||||||
|
'kode' => '',
|
||||||
|
'kategori' => 'Total',
|
||||||
|
'debit' => $totalDebit,
|
||||||
|
'kredit' => $totalKredit
|
||||||
|
];
|
||||||
|
|
||||||
|
// Buat class export inline
|
||||||
|
$export = new class($processedData) implements FromCollection, WithHeadings {
|
||||||
|
protected $data;
|
||||||
|
|
||||||
|
public function __construct($data)
|
||||||
|
{
|
||||||
|
$this->data = collect($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
return $this->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Kode',
|
||||||
|
'Nama Akun',
|
||||||
|
'Debit',
|
||||||
|
'Kredit'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return Excel::download($export, 'neraca-saldo-'.date('Y-m-d').'.xlsx');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return redirect()->back()->with('error', 'Gagal mengekspor Excel: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exportPDF(Request $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Ambil parameter filter tanggal jika ada
|
||||||
|
$startDate = $request->input('start_date', Carbon::now()->startOfMonth()->format('Y-m-d'));
|
||||||
|
$endDate = $request->input('end_date', Carbon::now()->endOfMonth()->format('Y-m-d'));
|
||||||
|
|
||||||
|
$rawTransaksis = NeracasaldoModel::whereBetween('Tanggal', [$startDate, $endDate])
|
||||||
|
->orderBy('kode', 'asc')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$processedData = [];
|
||||||
|
$totalsPerAkun = [];
|
||||||
|
$totalDebit = 0;
|
||||||
|
$totalKredit = 0;
|
||||||
|
|
||||||
|
// Proses data seperti di fungsi index
|
||||||
|
foreach ($rawTransaksis as $transaksi) {
|
||||||
|
$processAkun = function($kode, $kategori, $debit, $kredit) use (&$totalsPerAkun) {
|
||||||
|
if (!empty($kode) && !empty($kategori)) {
|
||||||
|
if (!isset($totalsPerAkun[$kategori])) {
|
||||||
|
$totalsPerAkun[$kategori] = [
|
||||||
|
'kode' => $kode,
|
||||||
|
'kategori' => $kategori,
|
||||||
|
'debit' => 0,
|
||||||
|
'kredit' => 0
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$totalsPerAkun[$kategori]['debit'] += floatval($debit ?? 0);
|
||||||
|
$totalsPerAkun[$kategori]['kredit'] += floatval($kredit ?? 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$processAkun($transaksi->kode, $transaksi->kategori, $transaksi->uang_masuk, $transaksi->uang_keluar);
|
||||||
|
$processAkun($transaksi->kode2, $transaksi->kategori2, $transaksi->uang_masuk2, $transaksi->uang_keluar2);
|
||||||
|
$processAkun($transaksi->kode3, $transaksi->kategori3, $transaksi->uang_masuk3, $transaksi->uang_keluar3);
|
||||||
|
$processAkun($transaksi->kode4, $transaksi->kategori4, $transaksi->uang_masuk4, $transaksi->uang_keluar4);
|
||||||
|
$processAkun($transaksi->kode5, $transaksi->kategori5, $transaksi->uang_masuk5, $transaksi->uang_keluar5);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($totalsPerAkun as $kategori => $data) {
|
||||||
|
$kodeAwal = substr($data['kode'], 0, 3);
|
||||||
|
$saldo = $data['debit'] - $data['kredit'];
|
||||||
|
|
||||||
|
if (in_array($kodeAwal, ['111', '112']) || in_array($kodeAwal, ['251', '252'])) {
|
||||||
|
if ($saldo != 0) {
|
||||||
|
$processedData[] = [
|
||||||
|
'kode' => $data['kode'],
|
||||||
|
'kategori' => $kategori,
|
||||||
|
'debit' => $saldo > 0 ? abs($saldo) : 0,
|
||||||
|
'kredit' => $saldo < 0 ? abs($saldo) : 0
|
||||||
|
];
|
||||||
|
$totalDebit += $saldo > 0 ? abs($saldo) : 0;
|
||||||
|
$totalKredit += $saldo < 0 ? abs($saldo) : 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($saldo != 0) {
|
||||||
|
$processedData[] = [
|
||||||
|
'kode' => $data['kode'],
|
||||||
|
'kategori' => $kategori,
|
||||||
|
'debit' => $saldo < 0 ? abs($saldo) : 0,
|
||||||
|
'kredit' => $saldo > 0 ? abs($saldo) : 0
|
||||||
|
];
|
||||||
|
$totalDebit += $saldo < 0 ? abs($saldo) : 0;
|
||||||
|
$totalKredit += $saldo > 0 ? abs($saldo) : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate PDF
|
||||||
|
$html = '
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Neraca Saldo</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
p.periode {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
table, th, td {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
th, td {
|
||||||
|
padding: 6px;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.text-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
tfoot td {
|
||||||
|
font-weight: bold;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Neraca Saldo</h2>
|
||||||
|
<p class="periode">Periode: ' . date('F Y', strtotime($startDate)) . '</p>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Kode</th>
|
||||||
|
<th>Nama Akun</th>
|
||||||
|
<th class="text-right">Debit</th>
|
||||||
|
<th class="text-right">Kredit</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>';
|
||||||
|
|
||||||
|
foreach($processedData as $data) {
|
||||||
|
if ($data['kategori'] !== 'Total') {
|
||||||
|
$html .= '
|
||||||
|
<tr>
|
||||||
|
<td>'.$data['kode'].'</td>
|
||||||
|
<td>'.$data['kategori'].'</td>
|
||||||
|
<td class="text-right">'.($data['debit'] > 0 ? 'Rp '.number_format($data['debit'], 0, ',', '.') : '-').'</td>
|
||||||
|
<td class="text-right">'.($data['kredit'] > 0 ? 'Rp '.number_format($data['kredit'], 0, ',', '.') : '-').'</td>
|
||||||
|
</tr>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$html .= '
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="text-right">Total:</td>
|
||||||
|
<td class="text-right">Rp '.number_format($totalDebit, 0, ',', '.').'</td>
|
||||||
|
<td class="text-right">Rp '.number_format($totalKredit, 0, ',', '.').'</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>';
|
||||||
|
|
||||||
|
$pdf = PDF::loadHTML($html);
|
||||||
|
return $pdf->download('neraca-saldo-'.date('Y-m-d').'.pdf');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return redirect()->back()->with('error', 'Gagal mengekspor PDF: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use PDF;
|
use PDF;
|
||||||
use Excel;
|
use Excel;
|
||||||
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||||
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
|
|
||||||
class RekeningController extends Controller
|
class RekeningController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -17,6 +19,15 @@ public function index(Request $request)
|
||||||
$startDate = $request->input('start_date', Carbon::now()->startOfMonth()->format('Y-m-d'));
|
$startDate = $request->input('start_date', Carbon::now()->startOfMonth()->format('Y-m-d'));
|
||||||
$endDate = $request->input('end_date', Carbon::now()->endOfMonth()->format('Y-m-d'));
|
$endDate = $request->input('end_date', Carbon::now()->endOfMonth()->format('Y-m-d'));
|
||||||
|
|
||||||
|
// Pastikan tanggal valid
|
||||||
|
try {
|
||||||
|
$startDate = Carbon::parse($startDate)->format('Y-m-d');
|
||||||
|
$endDate = Carbon::parse($endDate)->format('Y-m-d');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$startDate = Carbon::now()->startOfMonth()->format('Y-m-d');
|
||||||
|
$endDate = Carbon::now()->endOfMonth()->format('Y-m-d');
|
||||||
|
}
|
||||||
|
|
||||||
$query = RekeningModel::whereBetween('Tanggal', [$startDate, $endDate]);
|
$query = RekeningModel::whereBetween('Tanggal', [$startDate, $endDate]);
|
||||||
|
|
||||||
// Filter berdasarkan nama akun jika ada
|
// Filter berdasarkan nama akun jika ada
|
||||||
|
@ -98,7 +109,9 @@ public function index(Request $request)
|
||||||
'totals' => $totals,
|
'totals' => $totals,
|
||||||
'totalDebit' => $totalDebit,
|
'totalDebit' => $totalDebit,
|
||||||
'totalKredit' => $totalKredit,
|
'totalKredit' => $totalKredit,
|
||||||
'saldo' => $saldo
|
'saldo' => $saldo,
|
||||||
|
'startDate' => $startDate,
|
||||||
|
'endDate' => $endDate
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,24 +322,299 @@ public function destroy($id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function exportExcel()
|
public function exportExcel(Request $request)
|
||||||
{
|
{
|
||||||
$laporan = RekeningModel::all();
|
try {
|
||||||
$groupedLaporan = $laporan->groupBy('kategori');
|
// Ambil parameter filter tanggal jika ada
|
||||||
|
$startDate = $request->input('start_date', Carbon::now()->startOfMonth()->format('Y-m-d'));
|
||||||
|
$endDate = $request->input('end_date', Carbon::now()->endOfMonth()->format('Y-m-d'));
|
||||||
|
|
||||||
return Excel::download(function($excel) use ($groupedLaporan) {
|
$laporan = RekeningModel::whereBetween('Tanggal', [$startDate, $endDate])->get();
|
||||||
$excel->sheet('Rekening', function($sheet) use ($groupedLaporan) {
|
$groupedLaporan = collect();
|
||||||
$sheet->loadView('exports.rekening-excel', compact('groupedLaporan'));
|
|
||||||
});
|
// Proses data seperti di fungsi index
|
||||||
}, 'rekening-' . Carbon::now()->format('Y-m-d') . '.xlsx');
|
foreach ($laporan as $item) {
|
||||||
|
if (!empty($item->kategori)) {
|
||||||
|
$kategori = $item->kategori;
|
||||||
|
if (!isset($groupedLaporan[$kategori])) {
|
||||||
|
$groupedLaporan[$kategori] = collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function exportPDF()
|
$groupedLaporan[$kategori]->push((object)[
|
||||||
{
|
'Tanggal' => $item->Tanggal,
|
||||||
$laporan = RekeningModel::all();
|
'keterangan' => $item->keterangan,
|
||||||
$groupedLaporan = $laporan->groupBy('kategori');
|
'kode' => $this->generateKode($kategori),
|
||||||
$pdf = PDF::loadView('exports.rekening-pdf', compact('groupedLaporan'));
|
'debit' => $item->uang_masuk ?? 0,
|
||||||
|
'kredit' => $item->uang_keluar ?? 0
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return $pdf->download('rekening-' . Carbon::now()->format('Y-m-d') . '.pdf');
|
// Proses untuk kategori tambahan (2-5)
|
||||||
|
for ($i = 2; $i <= 5; $i++) {
|
||||||
|
$kategoriField = "kategori{$i}";
|
||||||
|
$uangMasukField = "uang_masuk{$i}";
|
||||||
|
$uangKeluarField = "uang_keluar{$i}";
|
||||||
|
|
||||||
|
if (!empty($item->$kategoriField)) {
|
||||||
|
$kategori = $item->$kategoriField;
|
||||||
|
if (!isset($groupedLaporan[$kategori])) {
|
||||||
|
$groupedLaporan[$kategori] = collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$groupedLaporan[$kategori]->push((object)[
|
||||||
|
'Tanggal' => $item->Tanggal,
|
||||||
|
'keterangan' => $item->keterangan,
|
||||||
|
'kode' => $this->generateKode($kategori),
|
||||||
|
'debit' => $item->$uangMasukField ?? 0,
|
||||||
|
'kredit' => $item->$uangKeluarField ?? 0
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buat class export inline
|
||||||
|
$export = new class($groupedLaporan) implements FromCollection, WithHeadings {
|
||||||
|
protected $data;
|
||||||
|
|
||||||
|
public function __construct($data)
|
||||||
|
{
|
||||||
|
$this->data = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function collection()
|
||||||
|
{
|
||||||
|
$exportData = collect();
|
||||||
|
|
||||||
|
foreach ($this->data as $kategori => $items) {
|
||||||
|
// Tambahkan header untuk setiap kategori
|
||||||
|
$exportData->push([
|
||||||
|
'Nama Akun: ' . $kategori,
|
||||||
|
'Kode Akun: ' . ($items->first()->kode ?? '-'),
|
||||||
|
'', '', '', ''
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Tambahkan header kolom
|
||||||
|
$exportData->push([
|
||||||
|
'Tanggal',
|
||||||
|
'Keterangan',
|
||||||
|
'Ref',
|
||||||
|
'Debit',
|
||||||
|
'Kredit',
|
||||||
|
'Saldo'
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Tambahkan data transaksi
|
||||||
|
$runningBalance = 0;
|
||||||
|
foreach ($items->sortBy('Tanggal') as $item) {
|
||||||
|
$accountType = substr($item->kode, 0, 3);
|
||||||
|
$runningBalance = $this->calculateBalance($runningBalance, $item->debit, $item->kredit, $accountType);
|
||||||
|
|
||||||
|
$exportData->push([
|
||||||
|
Carbon::parse($item->Tanggal)->format('d/m/Y'),
|
||||||
|
$item->keterangan,
|
||||||
|
'-',
|
||||||
|
$item->debit > 0 ? number_format($item->debit, 0, ',', '.') : '-',
|
||||||
|
$item->kredit > 0 ? number_format($item->kredit, 0, ',', '.') : '-',
|
||||||
|
number_format($runningBalance, 0, ',', '.')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tambahkan baris kosong setelah setiap kategori
|
||||||
|
$exportData->push(['', '', '', '', '', '']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $exportData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function headings(): array
|
||||||
|
{
|
||||||
|
return []; // Header akan ditangani di dalam collection
|
||||||
|
}
|
||||||
|
|
||||||
|
private function calculateBalance($previousBalance, $debit, $kredit, $accountType) {
|
||||||
|
$balance = $previousBalance;
|
||||||
|
|
||||||
|
if (in_array($accountType, ['111', '112']) || in_array($accountType, ['251', '252'])) {
|
||||||
|
$balance = $balance + $debit - $kredit;
|
||||||
|
} else {
|
||||||
|
$balance = $balance - $debit + $kredit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $balance;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return Excel::download($export, 'buku-besar-'.date('Y-m-d').'.xlsx');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return redirect()->back()->with('error', 'Gagal mengekspor Excel: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exportPDF(Request $request)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Ambil parameter filter tanggal jika ada
|
||||||
|
$startDate = $request->input('start_date', Carbon::now()->startOfMonth()->format('Y-m-d'));
|
||||||
|
$endDate = $request->input('end_date', Carbon::now()->endOfMonth()->format('Y-m-d'));
|
||||||
|
|
||||||
|
$laporan = RekeningModel::whereBetween('Tanggal', [$startDate, $endDate])->get();
|
||||||
|
$groupedLaporan = collect();
|
||||||
|
|
||||||
|
// Proses data seperti di fungsi index
|
||||||
|
foreach ($laporan as $item) {
|
||||||
|
if (!empty($item->kategori)) {
|
||||||
|
$kategori = $item->kategori;
|
||||||
|
if (!isset($groupedLaporan[$kategori])) {
|
||||||
|
$groupedLaporan[$kategori] = collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$groupedLaporan[$kategori]->push((object)[
|
||||||
|
'Tanggal' => $item->Tanggal,
|
||||||
|
'keterangan' => $item->keterangan,
|
||||||
|
'kode' => $this->generateKode($kategori),
|
||||||
|
'debit' => $item->uang_masuk ?? 0,
|
||||||
|
'kredit' => $item->uang_keluar ?? 0
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proses untuk kategori tambahan (2-5)
|
||||||
|
for ($i = 2; $i <= 5; $i++) {
|
||||||
|
$kategoriField = "kategori{$i}";
|
||||||
|
$uangMasukField = "uang_masuk{$i}";
|
||||||
|
$uangKeluarField = "uang_keluar{$i}";
|
||||||
|
|
||||||
|
if (!empty($item->$kategoriField)) {
|
||||||
|
$kategori = $item->$kategoriField;
|
||||||
|
if (!isset($groupedLaporan[$kategori])) {
|
||||||
|
$groupedLaporan[$kategori] = collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
$groupedLaporan[$kategori]->push((object)[
|
||||||
|
'Tanggal' => $item->Tanggal,
|
||||||
|
'keterangan' => $item->keterangan,
|
||||||
|
'kode' => $this->generateKode($kategori),
|
||||||
|
'debit' => $item->$uangMasukField ?? 0,
|
||||||
|
'kredit' => $item->$uangKeluarField ?? 0
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate PDF
|
||||||
|
$html = '
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Buku Besar</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
p.periode {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
.account-info {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
padding: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
page-break-inside: avoid;
|
||||||
|
}
|
||||||
|
table, th, td {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
th, td {
|
||||||
|
padding: 6px;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.text-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.text-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.page-break {
|
||||||
|
page-break-after: always;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Buku Besar</h2>
|
||||||
|
<p class="periode">Periode: ' . date('F Y', strtotime($startDate)) . '</p>';
|
||||||
|
|
||||||
|
foreach($groupedLaporan as $kategori => $items) {
|
||||||
|
$kodeAkun = $items->first()->kode ?? '-';
|
||||||
|
$html .= '
|
||||||
|
<div class="account-info">
|
||||||
|
<strong>Nama Akun:</strong> ' . $kategori . '
|
||||||
|
<span style="float: right;"><strong>Kode Akun:</strong> ' . $kodeAkun . '</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Tanggal</th>
|
||||||
|
<th>Keterangan</th>
|
||||||
|
<th class="text-center">Ref</th>
|
||||||
|
<th class="text-right">Debit</th>
|
||||||
|
<th class="text-right">Kredit</th>
|
||||||
|
<th class="text-right">Saldo</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>';
|
||||||
|
|
||||||
|
$runningBalance = 0;
|
||||||
|
$accountType = substr($kodeAkun, 0, 3);
|
||||||
|
|
||||||
|
foreach($items->sortBy('Tanggal') as $item) {
|
||||||
|
if (in_array($accountType, ['111', '112']) || in_array($accountType, ['251', '252'])) {
|
||||||
|
$runningBalance = $runningBalance + $item->debit - $item->kredit;
|
||||||
|
} else {
|
||||||
|
$runningBalance = $runningBalance - $item->debit + $item->kredit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$html .= '
|
||||||
|
<tr>
|
||||||
|
<td>' . date('d/m/Y', strtotime($item->Tanggal)) . '</td>
|
||||||
|
<td>' . $item->keterangan . '</td>
|
||||||
|
<td class="text-center">-</td>
|
||||||
|
<td class="text-right">' . ($item->debit > 0 ? number_format($item->debit, 0, ',', '.') : '-') . '</td>
|
||||||
|
<td class="text-right">' . ($item->kredit > 0 ? number_format($item->kredit, 0, ',', '.') : '-') . '</td>
|
||||||
|
<td class="text-right">' . number_format($runningBalance, 0, ',', '.') . '</td>
|
||||||
|
</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$html .= '
|
||||||
|
</tbody>
|
||||||
|
</table>';
|
||||||
|
}
|
||||||
|
|
||||||
|
$html .= '
|
||||||
|
</body>
|
||||||
|
</html>';
|
||||||
|
|
||||||
|
$pdf = PDF::loadHTML($html);
|
||||||
|
return $pdf->download('buku-besar-'.date('Y-m-d').'.pdf');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return redirect()->back()->with('error', 'Gagal mengekspor PDF: ' . $e->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,41 @@ class UserController extends Controller
|
||||||
{
|
{
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$users = User::all();
|
return view('User');
|
||||||
return view('User', compact('users'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getData()
|
public function getData(Request $request)
|
||||||
{
|
{
|
||||||
$users = User::all();
|
$query = User::select('id', 'nama', 'email', 'tipe_pengguna');
|
||||||
|
|
||||||
|
// Apply type filter
|
||||||
|
if ($request->has('type') && !empty($request->type)) {
|
||||||
|
$query->where('tipe_pengguna', $request->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply search filter
|
||||||
|
if ($request->has('search') && !empty($request->search)) {
|
||||||
|
$search = $request->search;
|
||||||
|
$query->where(function($q) use ($search) {
|
||||||
|
$q->where('nama', 'like', "%{$search}%")
|
||||||
|
->orWhere('email', 'like', "%{$search}%");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$users = $query->get();
|
||||||
return response()->json($users);
|
return response()->json($users);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$user = User::findOrFail($id);
|
||||||
|
return response()->json($user);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return response()->json(['error' => 'User tidak ditemukan'], 404);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
return view('TambahAkun');
|
return view('TambahAkun');
|
||||||
|
@ -34,22 +59,13 @@ public function store(Request $request)
|
||||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:penggunas'],
|
'email' => ['required', 'string', 'email', 'max:255', 'unique:penggunas'],
|
||||||
'password' => ['required', Password::min(8)->mixedCase()->numbers()],
|
'password' => ['required', Password::min(8)->mixedCase()->numbers()],
|
||||||
'tipe_pengguna' => ['required', 'in:owner,karyawan']
|
'tipe_pengguna' => ['required', 'in:owner,karyawan']
|
||||||
], [
|
|
||||||
'nama.required' => 'Nama harus diisi',
|
|
||||||
'nama.max' => 'Nama maksimal 255 karakter',
|
|
||||||
'email.required' => 'Email harus diisi',
|
|
||||||
'email.email' => 'Format email tidak valid',
|
|
||||||
'email.unique' => 'Email sudah terdaftar',
|
|
||||||
'password.required' => 'Password harus diisi',
|
|
||||||
'password.min' => 'Password minimal 8 karakter',
|
|
||||||
'tipe_pengguna.required' => 'Tipe pengguna harus dipilih',
|
|
||||||
'tipe_pengguna.in' => 'Tipe pengguna tidak valid'
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
return redirect()->back()
|
return response()->json([
|
||||||
->withErrors($validator)
|
'success' => false,
|
||||||
->withInput();
|
'message' => $validator->errors()->first()
|
||||||
|
], 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -60,12 +76,15 @@ public function store(Request $request)
|
||||||
'tipe_pengguna' => $request->tipe_pengguna
|
'tipe_pengguna' => $request->tipe_pengguna
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return redirect()->route('User.index')
|
return response()->json([
|
||||||
->with('success', 'Akun berhasil ditambahkan!');
|
'success' => true,
|
||||||
|
'message' => 'User berhasil ditambahkan'
|
||||||
|
]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return redirect()->back()
|
return response()->json([
|
||||||
->with('error', 'Gagal menambahkan akun. ' . $e->getMessage())
|
'success' => false,
|
||||||
->withInput();
|
'message' => 'Gagal menambahkan user: ' . $e->getMessage()
|
||||||
|
], 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,21 +101,13 @@ public function update(Request $request, $id)
|
||||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:penggunas,email,'.$id],
|
'email' => ['required', 'string', 'email', 'max:255', 'unique:penggunas,email,'.$id],
|
||||||
'password' => ['nullable', Password::min(8)->mixedCase()->numbers()],
|
'password' => ['nullable', Password::min(8)->mixedCase()->numbers()],
|
||||||
'tipe_pengguna' => ['required', 'in:owner,karyawan']
|
'tipe_pengguna' => ['required', 'in:owner,karyawan']
|
||||||
], [
|
|
||||||
'nama.required' => 'Nama harus diisi',
|
|
||||||
'nama.max' => 'Nama maksimal 255 karakter',
|
|
||||||
'email.required' => 'Email harus diisi',
|
|
||||||
'email.email' => 'Format email tidak valid',
|
|
||||||
'email.unique' => 'Email sudah terdaftar',
|
|
||||||
'password.min' => 'Password minimal 8 karakter',
|
|
||||||
'tipe_pengguna.required' => 'Tipe pengguna harus dipilih',
|
|
||||||
'tipe_pengguna.in' => 'Tipe pengguna tidak valid'
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
return redirect()->back()
|
return response()->json([
|
||||||
->withErrors($validator)
|
'success' => false,
|
||||||
->withInput();
|
'message' => $validator->errors()->first()
|
||||||
|
], 422);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -108,19 +119,21 @@ public function update(Request $request, $id)
|
||||||
'tipe_pengguna' => $request->tipe_pengguna
|
'tipe_pengguna' => $request->tipe_pengguna
|
||||||
];
|
];
|
||||||
|
|
||||||
// Update password hanya jika diisi
|
|
||||||
if ($request->filled('password')) {
|
if ($request->filled('password')) {
|
||||||
$data['password'] = Hash::make($request->password);
|
$data['password'] = Hash::make($request->password);
|
||||||
}
|
}
|
||||||
|
|
||||||
$user->update($data);
|
$user->update($data);
|
||||||
|
|
||||||
return redirect()->route('User.index')
|
return response()->json([
|
||||||
->with('success', 'Akun berhasil diperbarui!');
|
'success' => true,
|
||||||
|
'message' => 'User berhasil diperbarui'
|
||||||
|
]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return redirect()->back()
|
return response()->json([
|
||||||
->with('error', 'Gagal memperbarui akun. ' . $e->getMessage())
|
'success' => false,
|
||||||
->withInput();
|
'message' => 'Gagal memperbarui user: ' . $e->getMessage()
|
||||||
|
], 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,11 +143,15 @@ public function destroy($id)
|
||||||
$user = User::findOrFail($id);
|
$user = User::findOrFail($id);
|
||||||
$user->delete();
|
$user->delete();
|
||||||
|
|
||||||
return redirect()->route('User.index')
|
return response()->json([
|
||||||
->with('success', 'Akun berhasil dihapus!');
|
'success' => true,
|
||||||
|
'message' => 'User berhasil dihapus'
|
||||||
|
]);
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return redirect()->back()
|
return response()->json([
|
||||||
->with('error', 'Gagal menghapus akun. ' . $e->getMessage());
|
'success' => false,
|
||||||
|
'message' => 'Gagal menghapus user: ' . $e->getMessage()
|
||||||
|
], 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -357,10 +357,10 @@
|
||||||
<!-- Action Buttons -->
|
<!-- Action Buttons -->
|
||||||
<div class="flex justify-between items-center mt-4 mb-4">
|
<div class="flex justify-between items-center mt-4 mb-4">
|
||||||
<div class="flex space-x-2">
|
<div class="flex space-x-2">
|
||||||
<a href="{{ route('laporan.export-excel') }}" class="btn bg-green-500 text-white hover:bg-green-600">
|
<a href="{{ route('laporan.export-excel', ['start_date' => $startDate, 'end_date' => $endDate]) }}" class="btn bg-green-500 text-white hover:bg-green-600">
|
||||||
<i class="fas fa-file-excel mr-2"></i>Export Excel
|
<i class="fas fa-file-excel mr-2"></i>Export Excel
|
||||||
</a>
|
</a>
|
||||||
<a href="{{ route('laporan.export-pdf') }}" class="btn bg-red-500 text-white hover:bg-red-600">
|
<a href="{{ route('laporan.export-pdf', ['start_date' => $startDate, 'end_date' => $endDate]) }}" class="btn bg-red-500 text-white hover:bg-red-600">
|
||||||
<i class="fas fa-file-pdf mr-2"></i>Export PDF
|
<i class="fas fa-file-pdf mr-2"></i>Export PDF
|
||||||
</a>
|
</a>
|
||||||
<button onclick="window.print()" class="btn bg-gray-500 text-white hover:bg-gray-600">
|
<button onclick="window.print()" class="btn bg-gray-500 text-white hover:bg-gray-600">
|
||||||
|
@ -372,21 +372,86 @@
|
||||||
<!-- Style untuk print -->
|
<!-- Style untuk print -->
|
||||||
<style>
|
<style>
|
||||||
@media print {
|
@media print {
|
||||||
.btn, header, footer, .no-print {
|
.btn, header, footer, .no-print, nav, .aside, #prevPage, #nextPage, #rowsPerPage {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
font-size: 14px;
|
font-size: 12px;
|
||||||
|
background-color: white !important;
|
||||||
|
}
|
||||||
|
.box, .p-4, .intro-y {
|
||||||
|
padding: 0 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
background-color: white !important;
|
||||||
|
}
|
||||||
|
.bg-gray-100 {
|
||||||
|
background-color: white !important;
|
||||||
|
}
|
||||||
|
h1.text-2xl {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
margin: 10px 0 5px 0;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
p.text-sm {
|
||||||
|
text-align: center;
|
||||||
|
margin: 5px 0 20px 0;
|
||||||
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
.print-table {
|
.print-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse !important;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
font-size: 10px !important;
|
||||||
}
|
}
|
||||||
.print-table th,
|
.print-table th,
|
||||||
.print-table td {
|
.print-table td,
|
||||||
border: 1px solid #000;
|
table th,
|
||||||
padding: 8px;
|
table td {
|
||||||
|
border: 1px solid #000 !important;
|
||||||
|
padding: 6px !important;
|
||||||
|
}
|
||||||
|
.print-table th,
|
||||||
|
table th {
|
||||||
|
text-align: left;
|
||||||
|
background-color: #f2f2f2 !important;
|
||||||
|
font-weight: bold;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
color-adjust: exact;
|
||||||
|
print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
.text-right,
|
||||||
|
table td:nth-child(6),
|
||||||
|
table td:nth-child(7),
|
||||||
|
table th:nth-child(6),
|
||||||
|
table th:nth-child(7) {
|
||||||
|
text-align: right !important;
|
||||||
|
}
|
||||||
|
.text-center,
|
||||||
|
table td:nth-child(1),
|
||||||
|
table th:nth-child(1) {
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
.py-3, .px-4 {
|
||||||
|
padding: 6px !important;
|
||||||
|
}
|
||||||
|
tfoot td,
|
||||||
|
table tr:last-child td {
|
||||||
|
font-weight: bold !important;
|
||||||
|
background-color: #f9f9f9 !important;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
color-adjust: exact;
|
||||||
|
print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
.bg-blue-600 {
|
||||||
|
background-color: white !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
.ml-8 {
|
||||||
|
margin-left: 8px !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -101,10 +101,10 @@
|
||||||
<!-- Action Buttons -->
|
<!-- Action Buttons -->
|
||||||
<div class="flex justify-between items-center mt-4 mb-4">
|
<div class="flex justify-between items-center mt-4 mb-4">
|
||||||
<div class="flex space-x-2">
|
<div class="flex space-x-2">
|
||||||
<a href="{{ route('laporan.export-excel') }}" class="btn bg-green-500 text-white hover:bg-green-600">
|
<a href="{{ route('neracasaldo.export-excel', ['start_date' => $startDate, 'end_date' => $endDate]) }}" class="btn bg-green-500 text-white hover:bg-green-600">
|
||||||
<i class="fas fa-file-excel mr-2"></i>Export Excel
|
<i class="fas fa-file-excel mr-2"></i>Export Excel
|
||||||
</a>
|
</a>
|
||||||
<a href="{{ route('laporan.export-pdf') }}" class="btn bg-red-500 text-white hover:bg-red-600">
|
<a href="{{ route('neracasaldo.export-pdf', ['start_date' => $startDate, 'end_date' => $endDate]) }}" class="btn bg-red-500 text-white hover:bg-red-600">
|
||||||
<i class="fas fa-file-pdf mr-2"></i>Export PDF
|
<i class="fas fa-file-pdf mr-2"></i>Export PDF
|
||||||
</a>
|
</a>
|
||||||
<button onclick="window.print()" class="btn bg-gray-500 text-white hover:bg-gray-600">
|
<button onclick="window.print()" class="btn bg-gray-500 text-white hover:bg-gray-600">
|
||||||
|
@ -112,4 +112,73 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Style untuk print -->
|
||||||
|
<style>
|
||||||
|
@media print {
|
||||||
|
.btn, header, footer, .no-print, nav, .aside, #prevPage, #nextPage, #rowsPerPage {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
padding: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
background-color: white !important;
|
||||||
|
}
|
||||||
|
.box, .p-4, .intro-y {
|
||||||
|
padding: 0 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
background-color: white !important;
|
||||||
|
}
|
||||||
|
.bg-gray-100 {
|
||||||
|
background-color: white !important;
|
||||||
|
}
|
||||||
|
h1.text-2xl {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
margin: 10px 0 5px 0;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
p.text-sm {
|
||||||
|
text-align: center;
|
||||||
|
margin: 5px 0 20px 0;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse !important;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 10px !important;
|
||||||
|
}
|
||||||
|
table th,
|
||||||
|
table td {
|
||||||
|
border: 1px solid #000 !important;
|
||||||
|
padding: 6px !important;
|
||||||
|
}
|
||||||
|
table th {
|
||||||
|
text-align: left;
|
||||||
|
background-color: #f2f2f2 !important;
|
||||||
|
font-weight: bold;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
color-adjust: exact;
|
||||||
|
print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
table td:nth-child(3),
|
||||||
|
table td:nth-child(4),
|
||||||
|
table th:nth-child(3),
|
||||||
|
table th:nth-child(4) {
|
||||||
|
text-align: right !important;
|
||||||
|
}
|
||||||
|
table tr:last-child td {
|
||||||
|
font-weight: bold !important;
|
||||||
|
background-color: #f9f9f9 !important;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
color-adjust: exact;
|
||||||
|
print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
.bg-blue-600 {
|
||||||
|
background-color: white !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@endsection
|
@endsection
|
|
@ -165,10 +165,10 @@ function calculateBalancePHP($previousBalance, $debit, $kredit, $accountType) {
|
||||||
<!-- Action Buttons -->
|
<!-- Action Buttons -->
|
||||||
<div class="flex justify-between items-center mt-4 mb-4">
|
<div class="flex justify-between items-center mt-4 mb-4">
|
||||||
<div class="flex space-x-2">
|
<div class="flex space-x-2">
|
||||||
<a href="{{ route('laporan.export-excel') }}" class="btn bg-green-500 text-white hover:bg-green-600 px-4 py-2 rounded-md">
|
<a href="{{ route('rekening.export-excel', ['start_date' => $startDate, 'end_date' => $endDate]) }}" class="btn bg-green-500 text-white hover:bg-green-600 px-4 py-2 rounded-md">
|
||||||
<i class="fas fa-file-excel mr-2"></i>Export Excel
|
<i class="fas fa-file-excel mr-2"></i>Export Excel
|
||||||
</a>
|
</a>
|
||||||
<a href="{{ route('laporan.export-pdf') }}" class="btn bg-red-500 text-white hover:bg-red-600 px-4 py-2 rounded-md">
|
<a href="{{ route('rekening.export-pdf', ['start_date' => $startDate, 'end_date' => $endDate]) }}" class="btn bg-red-500 text-white hover:bg-red-600 px-4 py-2 rounded-md">
|
||||||
<i class="fas fa-file-pdf mr-2"></i>Export PDF
|
<i class="fas fa-file-pdf mr-2"></i>Export PDF
|
||||||
</a>
|
</a>
|
||||||
<button onclick="window.print()" class="btn bg-gray-500 text-white hover:bg-gray-600 px-4 py-2 rounded-md">
|
<button onclick="window.print()" class="btn bg-gray-500 text-white hover:bg-gray-600 px-4 py-2 rounded-md">
|
||||||
|
@ -181,24 +181,71 @@ function calculateBalancePHP($previousBalance, $debit, $kredit, $accountType) {
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@media print {
|
@media print {
|
||||||
.btn, header, footer, .no-print {
|
.btn, header, footer, .no-print, nav, .aside {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
font-size: 14px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
.box {
|
.box {
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
h1.text-2xl {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
margin: 10px 0 5px 0;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
p.text-sm {
|
||||||
|
text-align: center;
|
||||||
|
margin: 5px 0 20px 0;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.account-info {
|
||||||
|
background-color: #f2f2f2 !important;
|
||||||
|
padding: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
print-color-adjust: exact;
|
||||||
}
|
}
|
||||||
table {
|
table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
margin-bottom: 20px;
|
||||||
page-break-inside: avoid;
|
page-break-inside: avoid;
|
||||||
|
font-size: 10px !important;
|
||||||
|
}
|
||||||
|
table, th, td {
|
||||||
|
border: 1px solid #000 !important;
|
||||||
}
|
}
|
||||||
th, td {
|
th, td {
|
||||||
border: 1px solid #000;
|
padding: 6px !important;
|
||||||
padding: 8px;
|
}
|
||||||
|
th {
|
||||||
|
background-color: #f2f2f2 !important;
|
||||||
|
font-weight: bold;
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
.text-right {
|
||||||
|
text-align: right !important;
|
||||||
|
}
|
||||||
|
.text-center {
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
.bg-blue-600 {
|
||||||
|
background-color: white !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
.mb-8 {
|
||||||
|
margin-bottom: 20px !important;
|
||||||
|
}
|
||||||
|
.page-break {
|
||||||
|
page-break-after: always;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css">
|
||||||
<!-- SweetAlert2 JS -->
|
<!-- SweetAlert2 JS -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
|
<!-- Font Awesome -->
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
/* Gradient Background */
|
/* Gradient Background */
|
||||||
body {
|
body {
|
||||||
|
@ -21,6 +24,7 @@
|
||||||
/* Table Styling */
|
/* Table Styling */
|
||||||
.print-table {
|
.print-table {
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.print-table th {
|
.print-table th {
|
||||||
|
@ -48,6 +52,9 @@
|
||||||
border-radius: 0.375rem;
|
border-radius: 0.375rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-primary {
|
.btn-primary {
|
||||||
|
@ -59,80 +66,46 @@
|
||||||
background-color: #2563eb;
|
background-color: #2563eb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Modal Styling */
|
/* Filter Controls */
|
||||||
.modal {
|
.filter-controls {
|
||||||
display: none;
|
display: flex;
|
||||||
position: fixed;
|
gap: 1rem;
|
||||||
top: 0;
|
margin-bottom: 1.5rem;
|
||||||
right: 0;
|
flex-wrap: wrap;
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 50;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal.show {
|
.filter-group {
|
||||||
display: block;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-slide-over {
|
.filter-input {
|
||||||
transform: translateX(100%);
|
border: 1px solid #e5e7eb;
|
||||||
transition: transform 0.3s ease-out;
|
border-radius: 0.375rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal.show .modal-slide-over {
|
.filter-input:focus {
|
||||||
transform: translateX(0);
|
outline: none;
|
||||||
}
|
border-color: #3b82f6;
|
||||||
|
ring: 2px;
|
||||||
/* Animation */
|
ring-color: #93c5fd;
|
||||||
.intro-y {
|
|
||||||
animation: fadeIn 0.5s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadeIn {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(10px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Custom Scrollbar */
|
|
||||||
.overflow-x-auto::-webkit-scrollbar {
|
|
||||||
height: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.overflow-x-auto::-webkit-scrollbar-track {
|
|
||||||
background: #f1f1f1;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.overflow-x-auto::-webkit-scrollbar-thumb {
|
|
||||||
background: #888;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.overflow-x-auto::-webkit-scrollbar-thumb:hover {
|
|
||||||
background: #555;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Responsive Design */
|
/* Responsive Design */
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
.box {
|
.filter-controls {
|
||||||
margin: 0.5rem;
|
flex-direction: column;
|
||||||
padding: 0.5rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.print-table {
|
.filter-group {
|
||||||
font-size: 0.875rem;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.print-table th,
|
.filter-input {
|
||||||
.print-table td {
|
width: 100%;
|
||||||
padding: 0.5rem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -144,158 +117,135 @@
|
||||||
<h1 class="text-2xl font-bold">Akun User</h1>
|
<h1 class="text-2xl font-bold">Akun User</h1>
|
||||||
<p class="text-sm mt-1">Halaman ini menampilkan dan mengelola akun user.</p>
|
<p class="text-sm mt-1">Halaman ini menampilkan dan mengelola akun user.</p>
|
||||||
</div>
|
</div>
|
||||||
<!-- Form Section for Creating User -->
|
|
||||||
<div class="flex flex-wrap gap-4 px-6 py-4 border-b border-gray-200">
|
<!-- Filter dan Tombol Tambah -->
|
||||||
<div class="flex items-center">
|
<div class="filter-controls">
|
||||||
<label class="mr-2 text-sm font-medium text-gray-600">Nama:</label>
|
<div class="filter-group">
|
||||||
<input type="text" id="userName" class="border rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Nama User">
|
<label for="userType" class="font-medium">Tipe User:</label>
|
||||||
</div>
|
<select id="userType" class="filter-input">
|
||||||
<div class="flex items-center">
|
<option value="">Semua</option>
|
||||||
<label class="mr-2 text-sm font-medium text-gray-600">Email:</label>
|
|
||||||
<input type="email" id="userEmail" class="border rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Email User">
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<label class="mr-2 text-sm font-medium text-gray-600">Password:</label>
|
|
||||||
<input type="password" id="userPassword" class="border rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Password User">
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<label class="mr-2 text-sm font-medium text-gray-600">Tipe Pengguna:</label>
|
|
||||||
<select id="userType" class="border rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
|
|
||||||
<option value="karyawan">Karyawan</option>
|
<option value="karyawan">Karyawan</option>
|
||||||
<option value="owner">Owner</option>
|
<option value="owner">Owner</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<button id="createUser" class="btn btn-primary">Buat Akun</button>
|
|
||||||
|
<div class="filter-group">
|
||||||
|
<label for="searchUser" class="font-medium">Cari:</label>
|
||||||
|
<input type="text" id="searchUser" class="filter-input" placeholder="Cari nama/email...">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="filter-group ml-auto">
|
||||||
|
<a href="{{ route('User.create') }}" id="createUser" class="btn btn-primary">
|
||||||
|
<i class="fas fa-plus"></i>
|
||||||
|
<span>Tambah User</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tabel User -->
|
||||||
<div class="overflow-x-auto">
|
<div class="overflow-x-auto">
|
||||||
<table class="w-full bg-white border border-gray-300 print-table">
|
<table class="print-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-gray-100 text-gray-600 uppercase text-sm leading-normal">
|
<tr>
|
||||||
<th class="py-3 px-4 text-left">No</th>
|
<th class="text-left">No</th>
|
||||||
<th class="py-3 px-4 text-left">Nama</th>
|
<th class="text-left">Nama</th>
|
||||||
<th class="py-3 px-4 text-left">Email</th>
|
<th class="text-left">Email</th>
|
||||||
<th class="py-3 px-4 text-left">Tipe Pengguna</th>
|
<th class="text-left">Tipe User</th>
|
||||||
<th class="py-3 px-4 text-center">Aksi</th>
|
<th class="text-center">Aksi</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="userTableBody">
|
<tbody id="userTableBody">
|
||||||
<!-- User data will be populated here -->
|
<!-- Data akan diisi melalui JavaScript -->
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Pagination -->
|
|
||||||
<div class="intro-y col-span-12 flex flex-wrap sm:flex-row sm:flex-nowrap items-center py-5 px-4">
|
|
||||||
<!-- ... existing pagination code ... -->
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- JavaScript for handling user CRUD operations -->
|
|
||||||
<script>
|
<script>
|
||||||
// Notifikasi SweetAlert2
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
@if(session('success'))
|
const userType = document.getElementById('userType');
|
||||||
Swal.fire({
|
const searchUser = document.getElementById('searchUser');
|
||||||
icon: 'success',
|
|
||||||
title: 'Berhasil!',
|
|
||||||
text: '{{ session('success') }}',
|
|
||||||
confirmButtonText: 'OK'
|
|
||||||
});
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if(session('error'))
|
// Load initial data
|
||||||
Swal.fire({
|
loadUsers();
|
||||||
icon: 'error',
|
|
||||||
title: 'Gagal!',
|
|
||||||
text: '{{ session('error') }}',
|
|
||||||
confirmButtonText: 'OK'
|
|
||||||
});
|
|
||||||
@endif
|
|
||||||
|
|
||||||
// Function to load users
|
// Event listeners for filters
|
||||||
function loadUsers() {
|
userType.addEventListener('change', () => {
|
||||||
fetch('/users/data')
|
loadUsers(userType.value, searchUser.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
searchUser.addEventListener('input', () => {
|
||||||
|
loadUsers(userType.value, searchUser.value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function loadUsers(typeFilter = '', searchFilter = '') {
|
||||||
|
fetch(`/users/data?type=${typeFilter}&search=${searchFilter}`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
const userTableBody = document.getElementById('userTableBody');
|
const tbody = document.getElementById('userTableBody');
|
||||||
userTableBody.innerHTML = '';
|
tbody.innerHTML = '';
|
||||||
|
|
||||||
data.forEach((user, index) => {
|
data.forEach((user, index) => {
|
||||||
userTableBody.innerHTML += `
|
const row = document.createElement('tr');
|
||||||
<tr class="border-b border-gray-200 hover:bg-gray-50">
|
row.innerHTML = `
|
||||||
<td class="py-3 px-4">${index + 1}</td>
|
<td>${index + 1}</td>
|
||||||
<td class="py-3 px-4">${user.nama}</td>
|
<td>${user.nama}</td>
|
||||||
<td class="py-3 px-4">${user.email}</td>
|
<td>${user.email}</td>
|
||||||
<td class="py-3 px-4">${user.tipe_pengguna}</td>
|
<td>${user.tipe_pengguna}</td>
|
||||||
<td class="py-3 px-4 text-center">
|
<td class="text-center">
|
||||||
<button onclick="editUser(${user.id})" class="text-blue-600 hover:text-blue-800">
|
<a href="/User/${user.id}/edit" class="text-blue-600 hover:text-blue-800 mx-1">
|
||||||
<i class="fas fa-edit"></i>
|
<i class="fas fa-edit"></i>
|
||||||
</button>
|
</a>
|
||||||
<button onclick="deleteUser(${user.id})" class="text-red-600 hover:text-red-800">
|
<button onclick="deleteUser(${user.id})" class="text-red-600 hover:text-red-800 mx-1">
|
||||||
<i class="fas fa-trash"></i>
|
<i class="fas fa-trash"></i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
|
||||||
`;
|
`;
|
||||||
|
tbody.appendChild(row);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => console.error("Error fetching data:", error));
|
.catch(error => {
|
||||||
}
|
console.error('Error loading users:', error);
|
||||||
|
Swal.fire('Error!', 'Gagal memuat data user', 'error');
|
||||||
// Function untuk mengedit user
|
|
||||||
function editUser(id) {
|
|
||||||
window.location.href = `/User/${id}/edit`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Event listener for creating a user
|
|
||||||
document.getElementById('createUser').addEventListener('click', () => {
|
|
||||||
const nama = document.getElementById('userName').value;
|
|
||||||
const email = document.getElementById('userEmail').value;
|
|
||||||
const password = document.getElementById('userPassword').value;
|
|
||||||
const tipe_pengguna = document.getElementById('userType').value;
|
|
||||||
|
|
||||||
// Redirect ke route User.create
|
|
||||||
window.location.href = "{{ route('User.create') }}";
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Function untuk menghapus user
|
|
||||||
function deleteUser(id) {
|
function deleteUser(id) {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'Apakah Anda yakin?',
|
title: 'Hapus User',
|
||||||
text: "Data yang dihapus tidak dapat dikembalikan!",
|
text: 'Apakah Anda yakin ingin menghapus user ini?',
|
||||||
icon: 'warning',
|
icon: 'warning',
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonText: 'Ya, Hapus',
|
||||||
cancelButtonColor: '#d33',
|
|
||||||
confirmButtonText: 'Ya, hapus!',
|
|
||||||
cancelButtonText: 'Batal'
|
cancelButtonText: 'Batal'
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
// Buat form untuk delete request
|
fetch(`/User/${id}`, {
|
||||||
const form = document.createElement('form');
|
method: 'DELETE',
|
||||||
form.method = 'POST';
|
headers: {
|
||||||
form.action = `/User/${id}`;
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
|
||||||
|
}
|
||||||
const csrfToken = document.createElement('input');
|
})
|
||||||
csrfToken.type = 'hidden';
|
.then(response => response.json())
|
||||||
csrfToken.name = '_token';
|
.then(data => {
|
||||||
csrfToken.value = '{{ csrf_token() }}';
|
if (data.success) {
|
||||||
|
loadUsers(
|
||||||
const methodField = document.createElement('input');
|
document.getElementById('userType').value,
|
||||||
methodField.type = 'hidden';
|
document.getElementById('searchUser').value
|
||||||
methodField.name = '_method';
|
);
|
||||||
methodField.value = 'DELETE';
|
Swal.fire('Berhasil!', 'User telah dihapus', 'success');
|
||||||
|
} else {
|
||||||
form.appendChild(csrfToken);
|
throw new Error(data.message || 'Gagal menghapus user');
|
||||||
form.appendChild(methodField);
|
}
|
||||||
document.body.appendChild(form);
|
})
|
||||||
form.submit();
|
.catch(error => {
|
||||||
|
console.error('Error deleting user:', error);
|
||||||
|
Swal.fire('Error!', 'Gagal menghapus user', 'error');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial load
|
|
||||||
loadUsers();
|
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
|
@ -77,6 +77,8 @@
|
||||||
|
|
||||||
// Routes untuk Neraca Saldo
|
// Routes untuk Neraca Saldo
|
||||||
Route::get('/neracasaldo/filter', [NeracasaldoController::class, 'filter'])->name('neracasaldo.filter');
|
Route::get('/neracasaldo/filter', [NeracasaldoController::class, 'filter'])->name('neracasaldo.filter');
|
||||||
|
Route::get('/neracasaldo/export-excel', [NeracasaldoController::class, 'exportExcel'])->name('neracasaldo.export-excel');
|
||||||
|
Route::get('/neracasaldo/export-pdf', [NeracasaldoController::class, 'exportPDF'])->name('neracasaldo.export-pdf');
|
||||||
Route::resource('neracasaldo', NeracasaldoController::class);
|
Route::resource('neracasaldo', NeracasaldoController::class);
|
||||||
|
|
||||||
// Routes untuk Laba Rugi
|
// Routes untuk Laba Rugi
|
||||||
|
|
Loading…
Reference in New Issue