service->getCodeMap(); }, __('message.fetched')); } /** * 드롭다운 선택 → 품목 매핑 조회 */ public function resolveItem(Request $request): JsonResponse { return ApiResponse::handle(function () use ($request) { $prodCode = $request->query('prod'); $specCode = $request->query('spec'); $lengthCode = $request->query('length'); if (! $prodCode || ! $specCode || ! $lengthCode) { return ['error' => 'MISSING_PARAMS', 'code' => 400, 'message' => 'prod, spec, length 파라미터가 필요합니다.']; } $expectedCode = "BD-{$prodCode}{$specCode}-{$lengthCode}"; $item = $this->service->resolveItem($prodCode, $specCode, $lengthCode); if (! $item) { return [ 'error' => 'NOT_MAPPED', 'code' => 404, 'message' => '해당 조합에 매핑된 품목이 없습니다.', 'expected_code' => $expectedCode, ]; } $item['expected_code'] = $expectedCode; return $item; }, __('message.fetched')); } /** * 원자재 LOT 목록 조회 (입고 + 수입검사 완료 기준) * * 재질(material) 키워드를 분해하여 유연 검색 * 예: "EGI 1.55T" → "EGI" AND "1.55" 로 검색 (공백/T 무관) */ public function materialLots(Request $request): JsonResponse { return ApiResponse::handle(function () use ($request) { $material = $request->query('material'); $query = Receiving::whereIn('status', ['completed', 'inspection_completed']) ->whereNotNull('lot_no') ->where('lot_no', '!=', ''); // 재질 키워드 분해 검색 (공백/T 접미사 무관) if ($material) { // "EGI 1.55T" → ["EGI", "1.55"], "SUS 1.2T" → ["SUS", "1.2"] $keywords = preg_split('/[\s]+/', preg_replace('/T$/i', '', trim($material))); $keywords = array_filter($keywords); $query->where(function ($q) use ($keywords) { foreach ($keywords as $kw) { $q->where(function ($sub) use ($kw) { $sub->where('item_name', 'LIKE', "%{$kw}%") ->orWhere('specification', 'LIKE', "%{$kw}%"); }); } }); } return $query->select([ 'id', 'lot_no', 'supplier_lot', 'item_name', 'specification', 'receiving_qty', 'receiving_date', 'supplier', 'options', ]) ->orderByDesc('receiving_date') ->limit(50) ->get(); }, __('message.fetched')); } /** * LOT 번호 생성 (일련번호 없음 — 같은 날 같은 조합은 동일 LOT) */ public function generateLotNumber(Request $request): JsonResponse { return ApiResponse::handle(function () use ($request) { $prodCode = $request->input('prod_code'); $specCode = $request->input('spec_code'); $lengthCode = $request->input('length_code'); $regDate = $request->input('reg_date', now()->toDateString()); if (! $prodCode || ! $specCode || ! $lengthCode) { return ['error' => 'MISSING_PARAMS', 'code' => 400, 'message' => 'prod_code, spec_code, length_code가 필요합니다.']; } $lotNumber = $this->service->generateLotNumber($prodCode, $specCode, $lengthCode, $regDate); $material = BendingCodeService::getMaterial($prodCode, $specCode); return [ 'lot_number' => $lotNumber, 'material' => $material, ]; }, __('message.fetched')); } }