refactor: update AnalysisService and index.tsx to streamline stock calculations and remove unused values

This commit is contained in:
Yoga Pangestu 2026-08-14 06:07:47 +07:00
parent 5fd0ab135d
commit b954e3cb84
2 changed files with 42 additions and 47 deletions

View File

@ -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,

View File

@ -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') },
]}
/>
)}