Files
sam-api/app/Http/Controllers/Api/V1/BendingController.php

133 lines
4.6 KiB
PHP
Raw Normal View History

<?php
namespace App\Http\Controllers\Api\V1;
use App\Helpers\ApiResponse;
use App\Http\Controllers\Controller;
use App\Models\Tenants\Receiving;
use App\Services\BendingCodeService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class BendingController extends Controller
{
public function __construct(
private readonly BendingCodeService $service
) {}
/**
* 절곡품 코드맵 조회 (캐스케이딩 드롭다운용)
*/
public function codeMap(): JsonResponse
{
return ApiResponse::handle(function () {
return $this->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'));
}
}