2025-12-01 09:49:54 +07:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
|
|
|
|
|
|
use App\Exports\ArrayReportExport;
|
2025-12-01 09:56:42 +07:00
|
|
|
use App\Exports\AssetFullReportExport;
|
2025-12-01 12:46:30 +07:00
|
|
|
use App\Models\AssetAudit;
|
|
|
|
|
use App\Models\AssetMovement;
|
|
|
|
|
use App\Models\AssetDisposal;
|
2025-12-01 09:49:54 +07:00
|
|
|
use App\Models\Asset;
|
|
|
|
|
use App\Models\AssetAudit;
|
|
|
|
|
use App\Models\AssetCategory;
|
|
|
|
|
use App\Models\AssetClass;
|
|
|
|
|
use App\Models\AssetDisposal;
|
|
|
|
|
use App\Models\AssetLocation;
|
|
|
|
|
use App\Models\AssetMovement;
|
|
|
|
|
use App\Models\AssetStatus;
|
|
|
|
|
use App\Models\AssetUser;
|
|
|
|
|
use App\Models\Department;
|
|
|
|
|
use App\Models\PersonInCharge;
|
|
|
|
|
use App\Models\Warranty;
|
|
|
|
|
use Illuminate\Http\Request;
|
|
|
|
|
use Maatwebsite\Excel\Facades\Excel;
|
|
|
|
|
use Barryvdh\DomPDF\Facade\Pdf;
|
|
|
|
|
|
|
|
|
|
class ReportController extends Controller
|
|
|
|
|
{
|
|
|
|
|
public function assets(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$filters = $request->only([
|
|
|
|
|
'date_from','date_to','asset_status_id','asset_class_id','asset_category_id',
|
|
|
|
|
'asset_location_id','department_id','asset_user_id','person_in_charge_id','warranty_id'
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$query = Asset::with(['status','class','category','location','department','user','personInCharge','warranty'])
|
|
|
|
|
->when($filters['date_from'] ?? null, fn($q,$v)=>$q->whereDate('created_at','>=',$v))
|
|
|
|
|
->when($filters['date_to'] ?? null, fn($q,$v)=>$q->whereDate('created_at','<=',$v))
|
|
|
|
|
->when($filters['asset_status_id'] ?? null, fn($q,$v)=>$q->where('asset_status_id',$v))
|
|
|
|
|
->when($filters['asset_class_id'] ?? null, fn($q,$v)=>$q->where('asset_class_id',$v))
|
|
|
|
|
->when($filters['asset_category_id'] ?? null, fn($q,$v)=>$q->where('asset_category_id',$v))
|
|
|
|
|
->when($filters['asset_location_id'] ?? null, fn($q,$v)=>$q->where('asset_location_id',$v))
|
|
|
|
|
->when($filters['department_id'] ?? null, fn($q,$v)=>$q->where('department_id',$v))
|
|
|
|
|
->when($filters['asset_user_id'] ?? null, fn($q,$v)=>$q->where('asset_user_id',$v))
|
|
|
|
|
->when($filters['person_in_charge_id'] ?? null, fn($q,$v)=>$q->where('person_in_charge_id',$v))
|
|
|
|
|
->when($filters['warranty_id'] ?? null, fn($q,$v)=>$q->where('warranty_id',$v));
|
|
|
|
|
|
|
|
|
|
$assets = $query->paginate(20)->withQueryString();
|
|
|
|
|
|
|
|
|
|
if ($request->get('export') === 'excel') {
|
2025-12-01 09:56:42 +07:00
|
|
|
$assetsCollection = $query->get();
|
|
|
|
|
|
|
|
|
|
$assetRows = $assetsCollection->map(fn($a)=>[
|
2025-12-01 09:49:54 +07:00
|
|
|
$a->code,
|
|
|
|
|
$a->name,
|
|
|
|
|
$a->status?->name,
|
|
|
|
|
$a->category?->name,
|
|
|
|
|
$a->location?->name,
|
|
|
|
|
$a->department?->name,
|
|
|
|
|
$a->user?->name,
|
|
|
|
|
$a->personInCharge?->name,
|
|
|
|
|
$a->warranty?->name,
|
|
|
|
|
$a->created_at?->format('d/m/Y'),
|
|
|
|
|
])->toArray();
|
2025-12-01 09:56:42 +07:00
|
|
|
|
2025-12-01 12:46:30 +07:00
|
|
|
$movementsRaw = AssetMovement::with(['asset','fromLocation','toLocation','fromDepartment','toDepartment','fromUser','toUser'])
|
2025-12-01 09:56:42 +07:00
|
|
|
->whereIn('asset_id', $assetsCollection->pluck('id'))
|
2025-12-01 12:46:30 +07:00
|
|
|
->get();
|
|
|
|
|
|
|
|
|
|
$movements = $movementsRaw->values()->map(function ($m, $index) {
|
|
|
|
|
$rowNumber = $index + 2; // heading at row 1
|
|
|
|
|
$codeCell = "B{$rowNumber}";
|
|
|
|
|
$nameFormula = "=IFERROR(XLOOKUP({$codeCell},Assets!A:A,Assets!B:B,\"\"),\"\")";
|
|
|
|
|
return [
|
2025-12-01 09:56:42 +07:00
|
|
|
$m->performed_at?->format('d/m/Y H:i'),
|
|
|
|
|
$m->asset?->code,
|
2025-12-01 12:46:30 +07:00
|
|
|
$nameFormula,
|
2025-12-01 09:56:42 +07:00
|
|
|
$m->fromLocation?->name,
|
|
|
|
|
$m->toLocation?->name,
|
|
|
|
|
$m->fromDepartment?->name,
|
|
|
|
|
$m->toDepartment?->name,
|
|
|
|
|
$m->fromUser?->name,
|
|
|
|
|
$m->toUser?->name,
|
|
|
|
|
$m->notes,
|
2025-12-01 12:46:30 +07:00
|
|
|
];
|
|
|
|
|
})->toArray();
|
2025-12-01 09:56:42 +07:00
|
|
|
|
2025-12-01 12:46:30 +07:00
|
|
|
$disposalsRaw = AssetDisposal::with('asset')
|
2025-12-01 09:56:42 +07:00
|
|
|
->whereIn('asset_id', $assetsCollection->pluck('id'))
|
2025-12-01 12:46:30 +07:00
|
|
|
->get();
|
|
|
|
|
|
|
|
|
|
$disposals = $disposalsRaw->values()->map(function ($d, $index) {
|
|
|
|
|
$rowNumber = $index + 2;
|
|
|
|
|
$codeCell = "B{$rowNumber}";
|
|
|
|
|
$nameFormula = "=IFERROR(XLOOKUP({$codeCell},Assets!A:A,Assets!B:B,\"\"),\"\")";
|
|
|
|
|
return [
|
2025-12-01 09:56:42 +07:00
|
|
|
$d->disposed_at?->format('d/m/Y H:i'),
|
|
|
|
|
$d->asset?->code,
|
2025-12-01 12:46:30 +07:00
|
|
|
$nameFormula,
|
2025-12-01 09:56:42 +07:00
|
|
|
$d->reason,
|
|
|
|
|
$d->notes,
|
|
|
|
|
$d->reversed_at ? 'Reversed' : 'Active',
|
2025-12-01 12:46:30 +07:00
|
|
|
];
|
|
|
|
|
})->toArray();
|
2025-12-01 09:56:42 +07:00
|
|
|
|
2025-12-01 12:46:30 +07:00
|
|
|
$auditsRaw = AssetAudit::with(['asset','location'])
|
2025-12-01 09:56:42 +07:00
|
|
|
->whereIn('asset_id', $assetsCollection->pluck('id'))
|
2025-12-01 12:46:30 +07:00
|
|
|
->get();
|
|
|
|
|
|
|
|
|
|
$audits = $auditsRaw->values()->map(function ($a, $index) {
|
|
|
|
|
$rowNumber = $index + 2;
|
|
|
|
|
$codeCell = "B{$rowNumber}";
|
|
|
|
|
$nameFormula = "=IFERROR(XLOOKUP({$codeCell},Assets!A:A,Assets!B:B,\"\"),\"\")";
|
|
|
|
|
return [
|
2025-12-01 09:56:42 +07:00
|
|
|
$a->audited_at?->format('d/m/Y H:i'),
|
|
|
|
|
$a->asset?->code,
|
2025-12-01 12:46:30 +07:00
|
|
|
$nameFormula,
|
2025-12-01 09:56:42 +07:00
|
|
|
$a->status,
|
|
|
|
|
$a->location?->name,
|
|
|
|
|
$a->notes,
|
2025-12-01 12:46:30 +07:00
|
|
|
];
|
|
|
|
|
})->toArray();
|
2025-12-01 09:56:42 +07:00
|
|
|
|
|
|
|
|
return Excel::download(new AssetFullReportExport($assetRows, $movements, $disposals, $audits), 'asset-report.xlsx');
|
2025-12-01 09:49:54 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($request->get('export') === 'pdf') {
|
|
|
|
|
$data = $query->get();
|
|
|
|
|
$pdf = Pdf::loadView('reports.exports.assets', compact('data'));
|
|
|
|
|
return $pdf->download('asset-report.pdf');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return view('reports.assets', [
|
|
|
|
|
'assets' => $assets,
|
|
|
|
|
'filters' => $filters,
|
|
|
|
|
'statuses' => AssetStatus::orderBy('name')->get(),
|
|
|
|
|
'classes' => AssetClass::orderBy('name')->get(),
|
|
|
|
|
'categories' => AssetCategory::orderBy('name')->get(),
|
|
|
|
|
'locations' => AssetLocation::orderBy('name')->get(),
|
|
|
|
|
'departments' => Department::orderBy('name')->get(),
|
|
|
|
|
'users' => AssetUser::orderBy('name')->get(),
|
|
|
|
|
'pics' => PersonInCharge::orderBy('name')->get(),
|
|
|
|
|
'warranties' => Warranty::orderBy('name')->get(),
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function movements(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$filters = $request->only(['date_from','date_to','asset_id','asset_location_id','department_id','asset_user_id']);
|
|
|
|
|
$query = AssetMovement::with(['asset','toLocation','toDepartment','toUser','fromLocation','fromDepartment','fromUser'])
|
|
|
|
|
->when($filters['date_from'] ?? null, fn($q,$v)=>$q->whereDate('performed_at','>=',$v))
|
|
|
|
|
->when($filters['date_to'] ?? null, fn($q,$v)=>$q->whereDate('performed_at','<=',$v))
|
|
|
|
|
->when($filters['asset_id'] ?? null, fn($q,$v)=>$q->where('asset_id',$v))
|
|
|
|
|
->when($filters['asset_location_id'] ?? null, fn($q,$v)=>$q->where('to_location_id',$v))
|
|
|
|
|
->when($filters['department_id'] ?? null, fn($q,$v)=>$q->where('to_department_id',$v))
|
|
|
|
|
->when($filters['asset_user_id'] ?? null, fn($q,$v)=>$q->where('to_asset_user_id',$v));
|
|
|
|
|
|
|
|
|
|
$items = $query->paginate(20)->withQueryString();
|
|
|
|
|
|
|
|
|
|
if ($request->get('export') === 'excel') {
|
|
|
|
|
$rows = $query->get()->map(fn($m)=>[
|
|
|
|
|
$m->performed_at?->format('d/m/Y H:i'),
|
|
|
|
|
$m->asset?->code,
|
|
|
|
|
$m->fromLocation?->name,
|
|
|
|
|
$m->toLocation?->name,
|
|
|
|
|
$m->fromDepartment?->name,
|
|
|
|
|
$m->toDepartment?->name,
|
|
|
|
|
$m->fromUser?->name,
|
|
|
|
|
$m->toUser?->name,
|
|
|
|
|
$m->notes,
|
|
|
|
|
])->toArray();
|
|
|
|
|
return Excel::download(new ArrayReportExport([
|
|
|
|
|
'Waktu','Aset','Dari Lokasi','Ke Lokasi','Dari Dept','Ke Dept','Dari User','Ke User','Catatan'
|
|
|
|
|
], $rows), 'asset-movement-report.xlsx');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($request->get('export') === 'pdf') {
|
|
|
|
|
$data = $query->get();
|
|
|
|
|
$pdf = Pdf::loadView('reports.exports.movements', compact('data'));
|
|
|
|
|
return $pdf->download('asset-movement-report.pdf');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return view('reports.movements', [
|
|
|
|
|
'items' => $items,
|
|
|
|
|
'filters' => $filters,
|
|
|
|
|
'assets' => Asset::orderBy('code')->get(),
|
|
|
|
|
'locations' => AssetLocation::orderBy('name')->get(),
|
|
|
|
|
'departments' => Department::orderBy('name')->get(),
|
|
|
|
|
'users' => AssetUser::orderBy('name')->get(),
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function disposals(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$filters = $request->only(['date_from','date_to','asset_id','status']);
|
|
|
|
|
$query = AssetDisposal::with('asset')
|
|
|
|
|
->when($filters['date_from'] ?? null, fn($q,$v)=>$q->whereDate('disposed_at','>=',$v))
|
|
|
|
|
->when($filters['date_to'] ?? null, fn($q,$v)=>$q->whereDate('disposed_at','<=',$v))
|
|
|
|
|
->when($filters['asset_id'] ?? null, fn($q,$v)=>$q->where('asset_id',$v))
|
|
|
|
|
->when($filters['status'] ?? null, function ($q, $v) {
|
|
|
|
|
$v === 'reversed' ? $q->whereNotNull('reversed_at') : $q->whereNull('reversed_at');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$items = $query->paginate(20)->withQueryString();
|
|
|
|
|
|
|
|
|
|
if ($request->get('export') === 'excel') {
|
|
|
|
|
$rows = $query->get()->map(fn($d)=>[
|
|
|
|
|
$d->disposed_at?->format('d/m/Y H:i'),
|
|
|
|
|
$d->asset?->code,
|
|
|
|
|
$d->reason,
|
|
|
|
|
$d->notes,
|
|
|
|
|
$d->reversed_at ? 'Reversed' : 'Active',
|
|
|
|
|
])->toArray();
|
|
|
|
|
return Excel::download(new ArrayReportExport([
|
|
|
|
|
'Waktu','Aset','Alasan','Catatan','Status'
|
|
|
|
|
], $rows), 'asset-disposal-report.xlsx');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($request->get('export') === 'pdf') {
|
|
|
|
|
$data = $query->get();
|
|
|
|
|
$pdf = Pdf::loadView('reports.exports.disposals', compact('data'));
|
|
|
|
|
return $pdf->download('asset-disposal-report.pdf');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return view('reports.disposals', [
|
|
|
|
|
'items' => $items,
|
|
|
|
|
'filters' => $filters,
|
|
|
|
|
'assets' => Asset::orderBy('code')->get(),
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function audits(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$filters = $request->only(['date_from','date_to','asset_id','status','location_id']);
|
|
|
|
|
$query = AssetAudit::with(['asset','location'])
|
|
|
|
|
->when($filters['date_from'] ?? null, fn($q,$v)=>$q->whereDate('audited_at','>=',$v))
|
|
|
|
|
->when($filters['date_to'] ?? null, fn($q,$v)=>$q->whereDate('audited_at','<=',$v))
|
|
|
|
|
->when($filters['asset_id'] ?? null, fn($q,$v)=>$q->where('asset_id',$v))
|
|
|
|
|
->when($filters['status'] ?? null, fn($q,$v)=>$q->where('status',$v))
|
|
|
|
|
->when($filters['location_id'] ?? null, fn($q,$v)=>$q->where('location_id',$v));
|
|
|
|
|
|
|
|
|
|
$items = $query->paginate(20)->withQueryString();
|
|
|
|
|
|
|
|
|
|
if ($request->get('export') === 'excel') {
|
|
|
|
|
$rows = $query->get()->map(fn($a)=>[
|
|
|
|
|
$a->audited_at?->format('d/m/Y H:i'),
|
|
|
|
|
$a->asset?->code,
|
|
|
|
|
$a->status,
|
|
|
|
|
$a->location?->name,
|
|
|
|
|
$a->notes,
|
|
|
|
|
])->toArray();
|
|
|
|
|
return Excel::download(new ArrayReportExport([
|
|
|
|
|
'Waktu','Aset','Status','Lokasi','Catatan'
|
|
|
|
|
], $rows), 'asset-audit-report.xlsx');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($request->get('export') === 'pdf') {
|
|
|
|
|
$data = $query->get();
|
|
|
|
|
$pdf = Pdf::loadView('reports.exports.audits', compact('data'));
|
|
|
|
|
return $pdf->download('asset-audit-report.pdf');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return view('reports.audits', [
|
|
|
|
|
'items' => $items,
|
|
|
|
|
'filters' => $filters,
|
|
|
|
|
'assets' => Asset::orderBy('code')->get(),
|
|
|
|
|
'locations' => AssetLocation::orderBy('name')->get(),
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
}
|