- WorkResult 모델 생성 (Production 네임스페이스)
- WorkResultService 서비스 구현 (CRUD + 통계 + 토글)
- WorkResultController 컨트롤러 생성 (8개 엔드포인트)
- FormRequest 검증 클래스 (Store/Update)
- Swagger 문서 작성 (WorkResultApi.php)
- 라우트 추가 (/api/v1/work-results)
- i18n 메시지 추가 (work_result 키)
API Endpoints:
- GET /work-results - 목록 조회 (페이징, 필터링)
- GET /work-results/stats - 통계 조회
- GET /work-results/{id} - 상세 조회
- POST /work-results - 등록
- PUT /work-results/{id} - 수정
- DELETE /work-results/{id} - 삭제
- PATCH /work-results/{id}/inspection - 검사 상태 토글
- PATCH /work-results/{id}/packaging - 포장 상태 토글
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
314 lines
14 KiB
PHP
314 lines
14 KiB
PHP
<?php
|
|
|
|
namespace App\Swagger\v1;
|
|
|
|
/**
|
|
* @OA\Tag(name="WorkResult", description="작업실적 관리")
|
|
*
|
|
* @OA\Schema(
|
|
* schema="WorkResult",
|
|
* type="object",
|
|
* required={"id","lot_no","work_date","work_order_id","process_type","product_name"},
|
|
*
|
|
* @OA\Property(property="id", type="integer", example=1),
|
|
* @OA\Property(property="tenant_id", type="integer", example=1),
|
|
* @OA\Property(property="work_order_id", type="integer", example=1),
|
|
* @OA\Property(property="work_order_item_id", type="integer", nullable=true, example=1),
|
|
* @OA\Property(property="lot_no", type="string", example="KD-TS-250212-01-01"),
|
|
* @OA\Property(property="work_date", type="string", format="date", example="2025-02-12"),
|
|
* @OA\Property(property="process_type", type="string", enum={"screen","slat","bending"}, example="screen"),
|
|
* @OA\Property(property="product_name", type="string", example="스크린 셔터 (프리미엄)"),
|
|
* @OA\Property(property="specification", type="string", nullable=true, example="8000x2800"),
|
|
* @OA\Property(property="production_qty", type="integer", example=10),
|
|
* @OA\Property(property="good_qty", type="integer", example=9),
|
|
* @OA\Property(property="defect_qty", type="integer", example=1),
|
|
* @OA\Property(property="defect_rate", type="number", format="float", example=10.0),
|
|
* @OA\Property(property="is_inspected", type="boolean", example=true),
|
|
* @OA\Property(property="is_packaged", type="boolean", example=false),
|
|
* @OA\Property(property="worker_id", type="integer", nullable=true, example=10),
|
|
* @OA\Property(property="memo", type="string", nullable=true),
|
|
* @OA\Property(property="created_at", type="string", example="2025-02-12T10:00:00Z"),
|
|
* @OA\Property(property="updated_at", type="string", example="2025-02-12T10:00:00Z"),
|
|
* @OA\Property(property="work_order", type="object", nullable=true, @OA\Property(property="id", type="integer"), @OA\Property(property="work_order_no", type="string")),
|
|
* @OA\Property(property="worker", type="object", nullable=true, @OA\Property(property="id", type="integer"), @OA\Property(property="name", type="string"))
|
|
* )
|
|
*
|
|
* @OA\Schema(
|
|
* schema="WorkResultStats",
|
|
* type="object",
|
|
*
|
|
* @OA\Property(property="total_production", type="integer", example=100, description="총 생산수량"),
|
|
* @OA\Property(property="total_good", type="integer", example=95, description="총 양품수량"),
|
|
* @OA\Property(property="total_defect", type="integer", example=5, description="총 불량수량"),
|
|
* @OA\Property(property="defect_rate", type="number", format="float", example=5.0, description="불량률 (%)")
|
|
* )
|
|
*
|
|
* @OA\Schema(
|
|
* schema="WorkResultPagination",
|
|
* type="object",
|
|
*
|
|
* @OA\Property(property="current_page", type="integer", example=1),
|
|
* @OA\Property(property="data", type="array", @OA\Items(ref="#/components/schemas/WorkResult")),
|
|
* @OA\Property(property="first_page_url", type="string"),
|
|
* @OA\Property(property="from", type="integer"),
|
|
* @OA\Property(property="last_page", type="integer"),
|
|
* @OA\Property(property="per_page", type="integer"),
|
|
* @OA\Property(property="total", type="integer")
|
|
* )
|
|
*
|
|
* @OA\Schema(
|
|
* schema="WorkResultCreateRequest",
|
|
* type="object",
|
|
* required={"work_order_id","lot_no","work_date","product_name","production_qty","defect_qty"},
|
|
*
|
|
* @OA\Property(property="work_order_id", type="integer", description="작업지시 ID"),
|
|
* @OA\Property(property="work_order_item_id", type="integer", nullable=true, description="작업지시 품목 ID"),
|
|
* @OA\Property(property="lot_no", type="string", maxLength=50, description="로트번호"),
|
|
* @OA\Property(property="work_date", type="string", format="date", description="작업일"),
|
|
* @OA\Property(property="process_type", type="string", enum={"screen","slat","bending"}, nullable=true, description="공정구분"),
|
|
* @OA\Property(property="product_name", type="string", maxLength=200, description="품목명"),
|
|
* @OA\Property(property="specification", type="string", maxLength=100, nullable=true, description="규격"),
|
|
* @OA\Property(property="production_qty", type="integer", minimum=0, description="생산수량"),
|
|
* @OA\Property(property="good_qty", type="integer", minimum=0, nullable=true, description="양품수량 (미입력 시 자동계산)"),
|
|
* @OA\Property(property="defect_qty", type="integer", minimum=0, description="불량수량"),
|
|
* @OA\Property(property="is_inspected", type="boolean", nullable=true, description="검사완료 여부"),
|
|
* @OA\Property(property="is_packaged", type="boolean", nullable=true, description="포장완료 여부"),
|
|
* @OA\Property(property="worker_id", type="integer", nullable=true, description="작업자 ID"),
|
|
* @OA\Property(property="memo", type="string", maxLength=2000, nullable=true, description="비고")
|
|
* )
|
|
*
|
|
* @OA\Schema(
|
|
* schema="WorkResultUpdateRequest",
|
|
* type="object",
|
|
*
|
|
* @OA\Property(property="work_order_id", type="integer", nullable=true),
|
|
* @OA\Property(property="work_order_item_id", type="integer", nullable=true),
|
|
* @OA\Property(property="lot_no", type="string", maxLength=50, nullable=true),
|
|
* @OA\Property(property="work_date", type="string", format="date", nullable=true),
|
|
* @OA\Property(property="process_type", type="string", enum={"screen","slat","bending"}, nullable=true),
|
|
* @OA\Property(property="product_name", type="string", maxLength=200, nullable=true),
|
|
* @OA\Property(property="specification", type="string", maxLength=100, nullable=true),
|
|
* @OA\Property(property="production_qty", type="integer", minimum=0, nullable=true),
|
|
* @OA\Property(property="good_qty", type="integer", minimum=0, nullable=true),
|
|
* @OA\Property(property="defect_qty", type="integer", minimum=0, nullable=true),
|
|
* @OA\Property(property="is_inspected", type="boolean", nullable=true),
|
|
* @OA\Property(property="is_packaged", type="boolean", nullable=true),
|
|
* @OA\Property(property="worker_id", type="integer", nullable=true),
|
|
* @OA\Property(property="memo", type="string", maxLength=2000, nullable=true)
|
|
* )
|
|
*/
|
|
class WorkResultApi
|
|
{
|
|
/**
|
|
* @OA\Get(
|
|
* path="/api/v1/work-results",
|
|
* tags={"WorkResult"},
|
|
* summary="작업실적 목록 조회",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\Parameter(name="page", in="query", required=false, @OA\Schema(type="integer", default=1)),
|
|
* @OA\Parameter(name="size", in="query", required=false, @OA\Schema(type="integer", default=20)),
|
|
* @OA\Parameter(name="q", in="query", required=false, @OA\Schema(type="string"), description="검색어 (로트번호, 품목명, 작업지시번호)"),
|
|
* @OA\Parameter(name="process_type", in="query", required=false, @OA\Schema(type="string", enum={"screen","slat","bending"})),
|
|
* @OA\Parameter(name="work_order_id", in="query", required=false, @OA\Schema(type="integer")),
|
|
* @OA\Parameter(name="worker_id", in="query", required=false, @OA\Schema(type="integer")),
|
|
* @OA\Parameter(name="work_date_from", in="query", required=false, @OA\Schema(type="string", format="date")),
|
|
* @OA\Parameter(name="work_date_to", in="query", required=false, @OA\Schema(type="string", format="date")),
|
|
* @OA\Parameter(name="is_inspected", in="query", required=false, @OA\Schema(type="boolean")),
|
|
* @OA\Parameter(name="is_packaged", in="query", required=false, @OA\Schema(type="boolean")),
|
|
*
|
|
* @OA\Response(response=200, description="조회 성공",
|
|
*
|
|
* @OA\JsonContent(
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string"),
|
|
* @OA\Property(property="data", ref="#/components/schemas/WorkResultPagination")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=401, description="인증 실패")
|
|
* )
|
|
*/
|
|
public function index() {}
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/api/v1/work-results/stats",
|
|
* tags={"WorkResult"},
|
|
* summary="작업실적 통계 조회",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\Parameter(name="work_date_from", in="query", required=false, @OA\Schema(type="string", format="date")),
|
|
* @OA\Parameter(name="work_date_to", in="query", required=false, @OA\Schema(type="string", format="date")),
|
|
* @OA\Parameter(name="process_type", in="query", required=false, @OA\Schema(type="string", enum={"screen","slat","bending"})),
|
|
*
|
|
* @OA\Response(response=200, description="조회 성공",
|
|
*
|
|
* @OA\JsonContent(
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string"),
|
|
* @OA\Property(property="data", ref="#/components/schemas/WorkResultStats")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=401, description="인증 실패")
|
|
* )
|
|
*/
|
|
public function stats() {}
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/api/v1/work-results/{id}",
|
|
* tags={"WorkResult"},
|
|
* summary="작업실적 상세 조회",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
|
*
|
|
* @OA\Response(response=200, description="조회 성공",
|
|
*
|
|
* @OA\JsonContent(
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string"),
|
|
* @OA\Property(property="data", ref="#/components/schemas/WorkResult")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=404, description="리소스 없음")
|
|
* )
|
|
*/
|
|
public function show() {}
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/api/v1/work-results",
|
|
* tags={"WorkResult"},
|
|
* summary="작업실적 등록",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\RequestBody(required=true,
|
|
*
|
|
* @OA\JsonContent(ref="#/components/schemas/WorkResultCreateRequest")
|
|
* ),
|
|
*
|
|
* @OA\Response(response=200, description="등록 성공",
|
|
*
|
|
* @OA\JsonContent(
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string"),
|
|
* @OA\Property(property="data", ref="#/components/schemas/WorkResult")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=422, description="유효성 검증 실패")
|
|
* )
|
|
*/
|
|
public function store() {}
|
|
|
|
/**
|
|
* @OA\Put(
|
|
* path="/api/v1/work-results/{id}",
|
|
* tags={"WorkResult"},
|
|
* summary="작업실적 수정",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
|
*
|
|
* @OA\RequestBody(required=true,
|
|
*
|
|
* @OA\JsonContent(ref="#/components/schemas/WorkResultUpdateRequest")
|
|
* ),
|
|
*
|
|
* @OA\Response(response=200, description="수정 성공",
|
|
*
|
|
* @OA\JsonContent(
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string"),
|
|
* @OA\Property(property="data", ref="#/components/schemas/WorkResult")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=404, description="리소스 없음"),
|
|
* @OA\Response(response=422, description="유효성 검증 실패")
|
|
* )
|
|
*/
|
|
public function update() {}
|
|
|
|
/**
|
|
* @OA\Delete(
|
|
* path="/api/v1/work-results/{id}",
|
|
* tags={"WorkResult"},
|
|
* summary="작업실적 삭제",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
|
*
|
|
* @OA\Response(response=200, description="삭제 성공",
|
|
*
|
|
* @OA\JsonContent(
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string"),
|
|
* @OA\Property(property="data", type="string", example="success")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=404, description="리소스 없음")
|
|
* )
|
|
*/
|
|
public function destroy() {}
|
|
|
|
/**
|
|
* @OA\Patch(
|
|
* path="/api/v1/work-results/{id}/inspection",
|
|
* tags={"WorkResult"},
|
|
* summary="검사 상태 토글",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
|
*
|
|
* @OA\Response(response=200, description="성공",
|
|
*
|
|
* @OA\JsonContent(
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string"),
|
|
* @OA\Property(property="data", ref="#/components/schemas/WorkResult")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=404, description="리소스 없음")
|
|
* )
|
|
*/
|
|
public function toggleInspection() {}
|
|
|
|
/**
|
|
* @OA\Patch(
|
|
* path="/api/v1/work-results/{id}/packaging",
|
|
* tags={"WorkResult"},
|
|
* summary="포장 상태 토글",
|
|
* security={{"ApiKeyAuth": {}}, {"BearerAuth": {}}},
|
|
*
|
|
* @OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),
|
|
*
|
|
* @OA\Response(response=200, description="성공",
|
|
*
|
|
* @OA\JsonContent(
|
|
*
|
|
* @OA\Property(property="success", type="boolean", example=true),
|
|
* @OA\Property(property="message", type="string"),
|
|
* @OA\Property(property="data", ref="#/components/schemas/WorkResult")
|
|
* )
|
|
* ),
|
|
*
|
|
* @OA\Response(response=404, description="리소스 없음")
|
|
* )
|
|
*/
|
|
public function togglePackaging() {}
|
|
}
|