tenantId(); $userId = $this->apiUserId(); $today = Carbon::today(); return [ 'items' => [ $this->getOrdersStatus($tenantId, $today), $this->getBadDebtStatus($tenantId), $this->getSafetyStockStatus($tenantId), $this->getTaxDeadlineStatus($tenantId, $today), $this->getNewClientStatus($tenantId, $today), $this->getLeaveStatus($tenantId, $today), $this->getPurchaseStatus($tenantId), $this->getApprovalStatus($tenantId, $userId), ], ]; } /** * 수주 현황 (오늘 신규 수주 건수) */ private function getOrdersStatus(int $tenantId, Carbon $today): array { $count = Order::query() ->where('tenant_id', $tenantId) ->whereDate('created_at', $today) ->where('status_code', Order::STATUS_CONFIRMED) // 확정된 수주만 ->count(); return [ 'id' => 'orders', 'label' => __('message.status_board.orders'), 'count' => $count, 'path' => '/sales/order-management-sales', 'isHighlighted' => false, ]; } /** * 채권 추심 현황 (추심 진행 중인 건수) */ private function getBadDebtStatus(int $tenantId): array { $count = BadDebt::query() ->where('tenant_id', $tenantId) ->where('status', BadDebt::STATUS_COLLECTING) // 추심 진행 중 ->count(); return [ 'id' => 'bad_debts', 'label' => __('message.status_board.bad_debts'), 'count' => $count, 'path' => '/accounting/bad-debt-collection', 'isHighlighted' => false, ]; } /** * 안전 재고 현황 (안전재고 미달 품목 수) */ private function getSafetyStockStatus(int $tenantId): array { $count = Stock::query() ->where('tenant_id', $tenantId) ->where('safety_stock', '>', 0) // 안전재고 설정된 품목만 ->whereColumn('stock_qty', '<', 'safety_stock') ->count(); $isHighlighted = $count > 0; // 미달 품목 있으면 강조 return [ 'id' => 'safety_stock', 'label' => __('message.status_board.safety_stock'), 'count' => $count, 'path' => '/material/stock-status', 'isHighlighted' => $isHighlighted, ]; } /** * 세금 신고 현황 (부가세 신고 D-day) * * Schedule 테이블에서 type='tax'인 가장 가까운 일정 조회 * - 본사(tenant_id=NULL) 등록 글로벌 일정 + 테넌트 전용 일정 모두 포함 */ private function getTaxDeadlineStatus(int $tenantId, Carbon $today): array { // Schedule 테이블에서 가장 가까운 세금 신고 일정 조회 $nextTaxSchedule = Schedule::query() ->forTenant($tenantId) ->active() ->tax() ->upcoming($today->format('Y-m-d')) ->first(); if (! $nextTaxSchedule) { // 등록된 세금 일정이 없는 경우 return [ 'id' => 'tax_deadline', 'label' => __('message.status_board.tax_deadline'), 'count' => __('message.status_board.tax_no_schedule'), 'path' => '/accounting/tax', 'isHighlighted' => false, ]; } $deadline = $nextTaxSchedule->start_date; $daysUntil = $today->diffInDays($deadline, false); $countText = $daysUntil >= 0 ? __('message.status_board.tax_d_day', ['days' => $daysUntil]) : __('message.status_board.tax_overdue', ['days' => abs($daysUntil)]); return [ 'id' => 'tax_deadline', 'label' => __('message.status_board.tax_deadline'), 'count' => $countText, 'path' => '/accounting/tax', 'isHighlighted' => $daysUntil <= 7 && $daysUntil >= 0, ]; } /** * 신규 업체 등록 현황 (최근 7일 신규 거래처) */ private function getNewClientStatus(int $tenantId, Carbon $today): array { $count = Client::query() ->where('tenant_id', $tenantId) ->where('created_at', '>=', $today->copy()->subDays(7)) ->count(); return [ 'id' => 'new_clients', 'label' => __('message.status_board.new_clients'), 'count' => $count, 'path' => '/accounting/vendors', 'isHighlighted' => false, ]; } /** * 연차 현황 (오늘 휴가 중인 인원) */ private function getLeaveStatus(int $tenantId, Carbon $today): array { $count = Leave::query() ->where('tenant_id', $tenantId) ->where('status', 'approved') ->whereDate('start_date', '<=', $today) ->whereDate('end_date', '>=', $today) ->count(); return [ 'id' => 'leaves', 'label' => __('message.status_board.leaves'), 'count' => $count, 'path' => '/hr/vacation-management', 'isHighlighted' => false, ]; } /** * 발주 현황 (발주 대기 건수) */ private function getPurchaseStatus(int $tenantId): array { $count = Purchase::query() ->where('tenant_id', $tenantId) ->where('status', 'draft') // 대기 중인 발주 (임시저장 상태) ->count(); return [ 'id' => 'purchases', 'label' => __('message.status_board.purchases'), 'count' => $count, 'path' => '/construction/order/order-management', 'isHighlighted' => false, ]; } /** * 결재 요청 현황 (나의 결재 대기 건수) */ private function getApprovalStatus(int $tenantId, int $userId): array { $count = ApprovalStep::query() ->whereHas('approval', function ($query) use ($tenantId) { $query->where('tenant_id', $tenantId) ->where('status', 'pending'); }) ->where('approver_id', $userId) ->where('status', 'pending') ->count(); return [ 'id' => 'approvals', 'label' => __('message.status_board.approvals'), 'count' => $count, 'path' => '/approval/inbox', 'isHighlighted' => $count > 0, ]; } }