diff --git a/app/Services/AnalysisService.php b/app/Services/AnalysisService.php index c3b6d73..ce27df9 100644 --- a/app/Services/AnalysisService.php +++ b/app/Services/AnalysisService.php @@ -18,9 +18,9 @@ use App\Models\LeaveRequest; use App\Models\Order; use App\Models\Payroll; +use App\Models\ProductVariant; use App\Models\Purchase; -use App\Models\PurchaseItem; -use App\Models\RestockItem; +use App\Models\RawMaterialPrice; use App\Models\User; use Carbon\Carbon; use Illuminate\Database\Eloquent\Builder; @@ -82,13 +82,19 @@ public function getAttendanceStats(?string $startDate, ?string $endDate, ?User $ ]; } - $employees = Employee::whereHas('user', fn ($q) => $q - ->where('is_active', true) - ->whereHas('roles', fn ($r) => $r - ->whereHas('permissions', fn ($p) => $p - ->where('name', 'attendances.create') + $employees = Employee::whereHas( + 'user', + fn($q) => $q + ->where('is_active', true) + ->whereHas( + 'roles', + fn($r) => $r + ->whereHas( + 'permissions', + fn($p) => $p + ->where('name', 'attendances.create') + ) ) - ) ) ->where('join_date', '<=', $end) ->where(function ($q) use ($start) { @@ -199,49 +205,42 @@ public function getCashOverview(?string $startDate, ?string $endDate): array public function getRawMaterialStock(): array { - $query = PurchaseItem::query() - ->join('purchases', 'purchase_items.purchase_id', '=', 'purchases.id') - ->leftJoin('raw_material_prices', 'purchase_items.raw_material_price_id', '=', 'raw_material_prices.id') - ->leftJoin('raw_materials', 'raw_material_prices.raw_material_id', '=', 'raw_materials.id'); - - $items = $query->select('purchase_items.*', 'raw_materials.unit') + $items = RawMaterialPrice::query() + ->join('raw_materials', 'raw_material_prices.raw_material_id', '=', 'raw_materials.id') + ->select('raw_material_prices.stock', 'raw_materials.unit') ->get(); - $totalQty = $items->sum('quantity'); - $totalValue = $items->sum('subtotal'); + $totalQty = $items->sum('stock'); $byUnit = [ - 'yard' => $items->filter(fn ($i) => $i->unit === RawMaterialUnit::YARD)->sum('quantity'), - 'meter' => $items->filter(fn ($i) => $i->unit === RawMaterialUnit::METER)->sum('quantity'), - 'kilogram' => $items->filter(fn ($i) => $i->unit === RawMaterialUnit::KG)->sum('quantity'), + 'yard' => $items->filter(fn ($i) => $i->unit === RawMaterialUnit::YARD->value)->sum('stock'), + 'meter' => $items->filter(fn ($i) => $i->unit === RawMaterialUnit::METER->value)->sum('stock'), + 'kilogram' => $items->filter(fn ($i) => $i->unit === RawMaterialUnit::KG->value)->sum('stock'), ]; return [ 'total_stock' => $totalQty, - 'total_value' => $totalValue, 'by_unit' => $byUnit, ]; } public function getProductStock(): array { - $query = RestockItem::query() - ->join('restocks', 'restock_items.restock_id', '=', 'restocks.id'); - - $items = $query->select('restock_items.*', 'restocks.stock_type') + $variants = ProductVariant::query() + ->select('stock', 'reject_stock', 'retail_stock') ->get(); - $totalQty = $items->sum('quantity'); - $totalValue = $items->sum('subtotal'); - - $byType = $items->groupBy(fn ($i) => $i->stock_type ?? 'unknown') - ->map(fn ($group) => $group->sum('quantity')) - ->toArray(); + $totalStock = $variants->sum('stock'); + $totalRejectStock = $variants->sum('reject_stock'); + $totalRetailStock = $variants->sum('retail_stock'); return [ - 'total_stock' => $totalQty, - 'total_value' => $totalValue, - 'by_type' => $byType, + 'total_stock' => $totalStock + $totalRejectStock + $totalRetailStock, + 'by_type' => [ + 'stock' => $totalStock, + 'reject_stock' => $totalRejectStock, + 'retail_stock' => $totalRetailStock, + ], ]; } @@ -382,7 +381,7 @@ public function getMonthlyRevenueByChannel(?string $startDate, ?string $endDate, ->groupBy(DB::raw("DATE_FORMAT(created_at, '%Y-%m')"), DB::raw("DATE_FORMAT(created_at, '%b %Y')")) ->orderBy(DB::raw("DATE_FORMAT(created_at, '%Y-%m')")) ->get() - ->map(fn ($item) => [ + ->map(fn($item) => [ 'month' => $item->month, 'store' => (int) $item->store, 'shopee' => (int) $item->shopee, @@ -406,7 +405,7 @@ public function getRevenueByPaymentType(?string $startDate, ?string $endDate, ?U ->selectRaw('COALESCE(SUM(total_amount), 0) as total') ->groupBy('payment_type') ->get() - ->map(fn ($item) => [ + ->map(fn($item) => [ 'payment_type' => $item->payment_type, 'label' => $item->payment_type->label(), 'total' => (int) $item->total, @@ -721,7 +720,7 @@ public function getRevenueTrend(?string $startDate, ?string $endDate, ?User $use ->groupBy(DB::raw('DATE(orders.created_at)')) ->orderBy(DB::raw('DATE(orders.created_at)')) ->get() - ->map(fn ($item) => [ + ->map(fn($item) => [ 'date' => $item->date, 'qty' => (int) $item->qty, ]) @@ -812,7 +811,7 @@ public function getOrderStats(?string $startDate, ?string $endDate, ?User $user ->groupBy('marketing_id') ->with('marketing:id') ->get() - ->map(fn ($item) => [ + ->map(fn($item) => [ 'name' => $item->marketing?->userProfile->full_name ?? '-', 'count' => $item->count, 'total' => (int) $item->total, diff --git a/resources/js/pages/admin/analysis/index.tsx b/resources/js/pages/admin/analysis/index.tsx index fbcd6bc..b844d59 100644 --- a/resources/js/pages/admin/analysis/index.tsx +++ b/resources/js/pages/admin/analysis/index.tsx @@ -67,7 +67,6 @@ type AnalysisProps = { }; rawMaterialStock: { total_stock: number; - total_value: number; by_unit: { yard: number; meter: number; @@ -76,11 +75,10 @@ type AnalysisProps = { }; productStock: { total_stock: number; - total_value: number; by_type: { - good?: number; - reject?: number; - retail?: number; + stock?: number; + reject_stock?: number; + retail_stock?: number; }; }; revenueSummary: { @@ -591,7 +589,6 @@ export default function Analysis({ icon={Package} mainLabel="Total Stok" mainValue={rawMaterialStock.total_stock.toLocaleString('id-ID')} - subLabel={`Rp${formatRupiah(rawMaterialStock.total_value)}`} description="Tidak terpengaruh filter tanggal" items={[ { label: 'Yard', value: rawMaterialStock.by_unit?.yard?.toLocaleString('id-ID') ?? '0' }, @@ -607,12 +604,11 @@ export default function Analysis({ icon={ShoppingCart} mainLabel="Total Stok" mainValue={productStock.total_stock.toLocaleString('id-ID')} - subLabel={`Rp${formatRupiah(productStock.total_value)}`} description="Tidak terpengaruh filter tanggal" items={[ - { label: 'Bagus', value: (productStock.by_type?.good ?? 0).toLocaleString('id-ID') }, - { label: 'Reject', value: (productStock.by_type?.reject ?? 0).toLocaleString('id-ID') }, - { label: 'Ecer', value: (productStock.by_type?.retail ?? 0).toLocaleString('id-ID') }, + { label: 'Bagus', value: (productStock.by_type?.stock ?? 0).toLocaleString('id-ID') }, + { label: 'Reject', value: (productStock.by_type?.reject_stock ?? 0).toLocaleString('id-ID') }, + { label: 'Ecer', value: (productStock.by_type?.retail_stock ?? 0).toLocaleString('id-ID') }, ]} /> )}