2025-08-20 20:23:01 +09:00
|
|
|
<?php
|
2025-11-06 17:24:42 +09:00
|
|
|
|
2025-08-25 17:26:20 +09:00
|
|
|
/**
|
|
|
|
|
* 시스템/도메인 에러 메시지 (클라이언트 피드백용 고정 문자열)
|
|
|
|
|
* - DB 데이터 아님
|
|
|
|
|
* - 공통 핸들러/서비스에서 예외 메시지로 사용
|
|
|
|
|
* - 예: throw new NotFoundHttpException(__('error.not_found'));
|
|
|
|
|
*/
|
|
|
|
|
return [
|
2025-08-20 20:23:01 +09:00
|
|
|
|
2025-08-25 17:26:20 +09:00
|
|
|
// 4xx 공통
|
2025-11-06 17:24:42 +09:00
|
|
|
'not_found' => '존재하지 않는 URI 또는 데이터입니다.', // 404 일반
|
|
|
|
|
'tenant_id' => '활성 테넌트가 없습니다.', // 400 (Service::tenantId() 미설정)
|
2025-08-25 17:26:20 +09:00
|
|
|
'unauthenticated' => '인증에 실패했습니다.', // 401
|
2025-11-06 17:24:42 +09:00
|
|
|
'forbidden' => '요청에 대한 권한이 없습니다.', // 403
|
2025-08-25 17:26:20 +09:00
|
|
|
'bad_request' => '잘못된 요청입니다.', // 400 (검증 외 일반 케이스)
|
2025-11-10 11:17:32 +09:00
|
|
|
'token_expired' => '토큰이 만료되었습니다', // 401 (토큰 만료)
|
|
|
|
|
'refresh_token_required' => '리프레시 토큰이 필요합니다', // 422
|
|
|
|
|
'refresh_token_invalid' => '리프레시 토큰 형식이 올바르지 않습니다', // 422
|
|
|
|
|
'refresh_token_invalid_or_expired' => '리프레시 토큰이 유효하지 않거나 만료되었습니다', // 401
|
2025-08-20 20:23:01 +09:00
|
|
|
|
2025-08-25 17:26:20 +09:00
|
|
|
// 검증/파라미터
|
|
|
|
|
'validation_failed' => '요청 데이터 검증에 실패했습니다.', // 422
|
|
|
|
|
'missing_parameter' => '필수 파라미터가 누락되었습니다.', // 400
|
2026-01-14 20:29:00 +09:00
|
|
|
'email_already_exists' => '이미 사용 중인 이메일 주소입니다.', // 400
|
2025-11-06 17:24:42 +09:00
|
|
|
'business_num_format' => '사업자등록번호 형식이 올바르지 않습니다 (000-00-00000)',
|
|
|
|
|
'business_num_duplicate_active' => '이미 등록된 사업자등록번호입니다 (정식 서비스 업체)',
|
|
|
|
|
'user_id_format' => '아이디는 영문, 숫자, _, - 만 사용할 수 있습니다',
|
|
|
|
|
'phone_format' => '전화번호 형식이 올바르지 않습니다',
|
2025-08-25 17:26:20 +09:00
|
|
|
|
|
|
|
|
// 리소스별 (선택: :resource 자리표시자 사용)
|
|
|
|
|
'not_found_resource' => ':resource 정보를 찾을 수 없습니다.', // 예: __('error.not_found_resource', ['resource' => '제품'])
|
|
|
|
|
|
|
|
|
|
// 비즈니스 규칙
|
2025-11-06 17:24:42 +09:00
|
|
|
'duplicate' => '중복된 데이터가 존재합니다.',
|
|
|
|
|
'conflict' => '요청이 현재 상태와 충돌합니다.', // 409
|
2025-08-25 17:26:20 +09:00
|
|
|
'state_invalid' => '현재 상태에서는 처리할 수 없습니다.', // 409/400
|
|
|
|
|
|
|
|
|
|
// 서버 오류
|
|
|
|
|
'server_error' => '서버 처리 중 오류가 발생했습니다.', // 5xx 일반
|
2025-09-24 17:41:26 +09:00
|
|
|
|
|
|
|
|
// 견적 관련 에러
|
|
|
|
|
'estimate' => [
|
|
|
|
|
'cannot_delete_sent_or_approved' => '발송되었거나 승인된 견적은 삭제할 수 없습니다.',
|
|
|
|
|
'invalid_status_transition' => '현재 상태에서는 변경할 수 없습니다.',
|
|
|
|
|
],
|
|
|
|
|
|
2026-02-19 20:58:47 +09:00
|
|
|
// BOM 관련
|
|
|
|
|
'bom' => [
|
|
|
|
|
'line_not_found' => 'BOM 라인을 찾을 수 없습니다.',
|
|
|
|
|
'invalid_child_items' => '존재하지 않는 품목이 포함되어 있습니다. (ID: :ids)',
|
|
|
|
|
],
|
|
|
|
|
|
2025-09-24 17:41:26 +09:00
|
|
|
// BOM 템플릿 관련
|
|
|
|
|
'bom_template' => [
|
|
|
|
|
'not_found' => '적용 가능한 BOM 템플릿을 찾을 수 없습니다.',
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 모델셋 관련
|
|
|
|
|
'modelset' => [
|
|
|
|
|
'has_dependencies' => '연관된 제품 또는 하위 카테고리가 있어 삭제할 수 없습니다.',
|
|
|
|
|
],
|
2025-09-24 20:35:17 +09:00
|
|
|
|
|
|
|
|
// 설정 관리 관련
|
|
|
|
|
'settings' => [
|
|
|
|
|
'field_not_found' => '해당 필드 설정을 찾을 수 없습니다.',
|
|
|
|
|
'option_group_not_found' => '해당 옵션 그룹을 찾을 수 없습니다.',
|
|
|
|
|
'common_code_duplicate' => '중복된 공통 코드가 존재합니다.',
|
|
|
|
|
'invalid_field_type' => '유효하지 않은 필드 타입입니다.',
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 자재 관리 관련
|
|
|
|
|
'materials' => [
|
|
|
|
|
'not_found' => '자재 정보를 찾을 수 없습니다.',
|
|
|
|
|
'duplicate_code' => '중복된 자재 코드입니다.',
|
|
|
|
|
'in_use_cannot_delete' => '사용 중인 자재는 삭제할 수 없습니다.',
|
|
|
|
|
],
|
|
|
|
|
|
2025-12-26 15:48:37 +09:00
|
|
|
// 입고 관리 관련
|
|
|
|
|
'receiving' => [
|
|
|
|
|
'not_found' => '입고 정보를 찾을 수 없습니다.',
|
|
|
|
|
'cannot_edit' => '입고완료 상태에서는 수정할 수 없습니다.',
|
|
|
|
|
'cannot_delete' => '입고완료 상태에서는 삭제할 수 없습니다.',
|
|
|
|
|
'cannot_process' => '현재 상태에서는 입고처리할 수 없습니다.',
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 재고 관리 관련
|
|
|
|
|
'stock' => [
|
|
|
|
|
'not_found' => '재고 정보를 찾을 수 없습니다.',
|
2026-01-26 20:29:22 +09:00
|
|
|
'item_id_required' => '입고 정보에 품목 ID가 없습니다.',
|
|
|
|
|
'insufficient_qty' => '재고 수량이 부족합니다.',
|
|
|
|
|
'lot_not_available' => '가용 LOT가 없습니다.',
|
2025-12-26 15:48:37 +09:00
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 출하 관리 관련
|
|
|
|
|
'shipment' => [
|
|
|
|
|
'not_found' => '출하 정보를 찾을 수 없습니다.',
|
|
|
|
|
'cannot_edit' => '현재 상태에서는 수정할 수 없습니다.',
|
|
|
|
|
'cannot_delete' => '현재 상태에서는 삭제할 수 없습니다.',
|
|
|
|
|
'invalid_status' => '유효하지 않은 상태입니다.',
|
|
|
|
|
'cannot_ship' => '출하 가능 상태가 아닙니다.',
|
|
|
|
|
],
|
|
|
|
|
|
2025-09-24 20:35:17 +09:00
|
|
|
// 파일 관리 관련
|
|
|
|
|
'file' => [
|
|
|
|
|
'not_found' => '파일을 찾을 수 없습니다.',
|
|
|
|
|
'upload_failed' => '파일 업로드에 실패했습니다.',
|
|
|
|
|
'invalid_file_type' => '허용되지 않는 파일 형식입니다.',
|
|
|
|
|
'file_too_large' => '파일 크기가 너무 큽니다.',
|
|
|
|
|
],
|
2025-10-13 21:52:34 +09:00
|
|
|
|
feat: 파일 저장 시스템 DB 마이그레이션
- enhance_files_table: 이중 파일명 시스템 (display_name/stored_name), 폴더 관리, 문서 연결 지원
- create_folders_table: 동적 폴더 관리 시스템 (tenant별 커스터마이징 가능)
- 5개 stub 마이그레이션 생성 (file_share_links, file_deletion_logs, storage_usage_history, add_storage_columns_to_tenants)
- FolderSeeder stub 생성
- CURRENT_WORKS.md에 Phase 1 진행상황 문서화
fix: 파일 공유 및 삭제 기능 버그 수정
- ShareLinkRequest: PATH 파라미터 {id}를 file_id로 자동 병합
- routes/api.php: 공유 링크 다운로드를 auth.apikey 그룹 밖으로 이동 (인증 불필요)
- FileShareLink: File, Tenant 클래스 import 추가
- File 모델: softDeleteFile()에서 SoftDeletes의 delete() 메서드 사용
- FileStorageService: getTrash(), restoreFile(), permanentDelete()에서 onlyTrashed() 사용
- File 모델: Tenant 네임스페이스 수정 (App\Models\Tenants\Tenant)
refactor: Swagger 문서 정리 - File 태그를 Files로 통합
- FileApi.php의 모든 태그를 Files로 변경
- 구 파일 시스템 라우트 삭제 (prefix 'file')
- 구 FileController.php 삭제
- 신규 파일 저장소 시스템으로 완전 통합
fix: 모든 legacy 파일 컬럼 nullable 일괄 처리
- 5개 legacy 컬럼을 한 번에 nullable로 변경
* original_name, file_name, file_name_old (string)
* fileable_id, fileable_type (polymorphic)
- foreach 루프로 반복 작업 자동화
- 신규/기존 시스템 간 완전한 하위 호환성 확보
fix: legacy 파일 컬럼 nullable 처리 완료
- file_name, file_name_old 컬럼도 nullable로 변경
- 기존 시스템과 신규 시스템 간 완전한 하위 호환성 확보
- Legacy: original_name, file_name, file_name_old (nullable)
- New: display_name, stored_name (required)
fix: original_name 컬럼 nullable 처리
- original_name을 nullable로 변경하여 하위 호환성 유지
- 새 시스템에서는 display_name 사용, 기존 시스템은 original_name 사용 가능
fix: 파일 업로드 DB 컬럼 누락 및 메시지 구조 개선
- files 테이블에 감사 컬럼 추가 (created_by, updated_by, uploaded_by)
- ApiResponse::handle() 메시지 로직 개선 (접미사 제거)
- 다국어 지원을 위한 완성된 문장 구조 유지
- FileUploadRequest 파일 검증 규칙 수정
fix: 파일 저장소 버그 수정 및 신규 테넌트 폴더 자동 생성
- FolderSeeder 네임스페이스 수정 (App\Models\Tenant → App\Models\Tenants\Tenant)
- FileStorageController use 문 구문 오류 수정 (/ → \)
- TenantObserver에 신규 테넌트 기본 폴더 자동 생성 로직 추가
- 5개 기본 폴더 (생산관리, 품질관리, 회계, 인사, 일반)
- 에러 처리 및 로깅
- 회원가입 시 자동 실행
2025-11-10 19:08:56 +09:00
|
|
|
// 파일 저장소 관련
|
|
|
|
|
'file_not_found' => '파일을 찾을 수 없습니다.',
|
|
|
|
|
'file_ids_required' => '파일 ID 목록은 필수입니다.',
|
|
|
|
|
'file_ids_must_be_array' => '파일 ID는 배열이어야 합니다.',
|
|
|
|
|
'folder_not_found' => '폴더를 찾을 수 없습니다.',
|
|
|
|
|
'folder_id_required' => '폴더 ID는 필수입니다.',
|
|
|
|
|
'storage_quota_exceeded' => '저장소 용량이 부족합니다.',
|
|
|
|
|
'share_link_expired' => '공유 링크가 만료되었습니다.',
|
|
|
|
|
'share_link_not_found' => '공유 링크를 찾을 수 없습니다.',
|
|
|
|
|
|
|
|
|
|
// 폴더 관련
|
|
|
|
|
'folder_key_required' => '폴더 키는 필수입니다.',
|
|
|
|
|
'folder_key_duplicate' => '이미 존재하는 폴더 키입니다.',
|
|
|
|
|
'folder_key_format' => '폴더 키는 영문 소문자, 숫자, 하이픈, 언더스코어만 사용할 수 있습니다.',
|
|
|
|
|
'folder_name_required' => '폴더명은 필수입니다.',
|
|
|
|
|
'folder_has_files' => '폴더에 파일이 있어 삭제할 수 없습니다.',
|
|
|
|
|
'color_format' => '색상 코드는 #RRGGBB 형식이어야 합니다.',
|
|
|
|
|
'expiry_hours_min' => '만료 시간은 최소 1시간입니다.',
|
|
|
|
|
'expiry_hours_max' => '만료 시간은 최대 168시간(7일)입니다.',
|
|
|
|
|
|
2025-10-13 21:52:34 +09:00
|
|
|
// 가격 관리 관련
|
|
|
|
|
'price_not_found' => ':item_type ID :item_id 항목의 :date 기준 매출단가를 찾을 수 없습니다.',
|
2025-10-14 09:10:52 +09:00
|
|
|
|
|
|
|
|
// 고객 그룹 관련
|
|
|
|
|
'duplicate_code' => '중복된 그룹 코드입니다.',
|
|
|
|
|
'has_clients' => '해당 고객 그룹에 속한 고객이 있어 삭제할 수 없습니다.',
|
|
|
|
|
'code_exists_in_deleted' => '삭제된 데이터에 동일한 코드가 존재합니다. 먼저 해당 코드를 완전히 삭제하거나 다른 코드를 사용하세요.',
|
2025-11-26 14:09:31 +09:00
|
|
|
|
|
|
|
|
// 품목 기준 관리 관련
|
|
|
|
|
'page_not_found' => '페이지를 찾을 수 없습니다.',
|
|
|
|
|
'section_not_found' => '섹션을 찾을 수 없습니다.',
|
|
|
|
|
'field_not_found' => '필드를 찾을 수 없습니다.',
|
2025-12-09 14:06:35 +09:00
|
|
|
'field_key_reserved' => '":field_key"은(는) 시스템 예약어로 사용할 수 없습니다.',
|
feat: 근무/출퇴근 설정 및 현장 관리 API 구현
- 근무 설정 API (GET/PUT /settings/work)
- 근무유형, 소정근로시간, 연장근로시간, 근무요일, 출퇴근시간, 휴게시간
- 출퇴근 설정 API (GET/PUT /settings/attendance)
- GPS 출퇴근, 허용 반경, 본사 위치 설정
- 현장 관리 API (CRUD /sites)
- 현장 등록/수정/삭제, 활성화된 현장 목록(셀렉트박스용)
- GPS 좌표 기반 위치 관리
마이그레이션: work_settings, attendance_settings, sites 테이블
모델: WorkSetting, AttendanceSetting, Site (BelongsToTenant, SoftDeletes)
서비스: WorkSettingService, SiteService
Swagger 문서 및 i18n 메시지 키 추가
2025-12-17 20:46:37 +09:00
|
|
|
'field_key_system_readonly' => '시스템 필드의 field_key는 변경할 수 없습니다.',
|
|
|
|
|
'field_key_system_cannot_delete' => '시스템 필드는 삭제할 수 없습니다.',
|
2025-11-26 14:09:31 +09:00
|
|
|
'bom_not_found' => 'BOM 항목을 찾을 수 없습니다.',
|
2025-12-13 23:28:06 +09:00
|
|
|
'item_type_required' => '품목 유형(item_type)은 필수입니다.',
|
2025-12-15 14:47:04 +09:00
|
|
|
'item_type_or_group_required' => '품목 유형(item_type) 또는 그룹 ID(group_id)는 필수입니다.',
|
2025-12-13 23:28:06 +09:00
|
|
|
'invalid_item_type' => '유효하지 않은 품목 유형입니다.',
|
2025-12-15 14:47:04 +09:00
|
|
|
'invalid_group_id' => '유효하지 않은 그룹 ID이거나 해당 그룹에 품목 유형이 없습니다.',
|
2025-12-21 01:10:38 +09:00
|
|
|
'item_types_must_be_same_group' => '여러 품목 유형을 선택할 때는 같은 그룹에 속한 유형만 선택할 수 있습니다.',
|
2025-12-13 23:28:06 +09:00
|
|
|
'invalid_source_table' => '품목 유형에 대한 소스 테이블이 설정되지 않았습니다.',
|
2025-11-27 15:51:00 +09:00
|
|
|
|
2025-12-03 22:35:38 +09:00
|
|
|
// 품목 관리 관련
|
|
|
|
|
'item' => [
|
|
|
|
|
'not_found' => '품목 정보를 찾을 수 없습니다.',
|
|
|
|
|
'already_deleted' => '이미 삭제된 품목입니다.',
|
|
|
|
|
'in_use_as_bom_component' => '다른 제품의 BOM 구성품으로 사용 중이어서 삭제할 수 없습니다. (사용처: :count건)',
|
2025-12-11 19:01:07 +09:00
|
|
|
'in_use' => '사용 중인 품목은 삭제할 수 없습니다. (사용처: :usage)',
|
|
|
|
|
'batch_in_use' => '사용 중인 품목이 포함되어 있어 삭제할 수 없습니다. (품목: :codes, :count건)',
|
2025-12-03 22:35:38 +09:00
|
|
|
'invalid_item_type' => '유효하지 않은 품목 유형입니다.',
|
2025-12-11 11:07:33 +09:00
|
|
|
'duplicate_code' => '중복된 품목 코드입니다.',
|
2025-12-13 23:53:16 +09:00
|
|
|
'self_reference_bom' => 'BOM에 자기 자신을 포함할 수 없습니다.',
|
2025-12-03 22:35:38 +09:00
|
|
|
],
|
|
|
|
|
|
2025-12-17 20:57:38 +09:00
|
|
|
// 단가 관리 관련
|
|
|
|
|
'pricing' => [
|
|
|
|
|
'finalized_cannot_edit' => '확정된 단가는 수정할 수 없습니다.',
|
|
|
|
|
'finalized_cannot_delete' => '확정된 단가는 삭제할 수 없습니다.',
|
|
|
|
|
'cannot_finalize' => '확정할 수 없는 상태입니다.',
|
|
|
|
|
],
|
|
|
|
|
|
2025-11-27 15:51:00 +09:00
|
|
|
// 잠금 관련
|
|
|
|
|
'relationship_locked' => '잠금된 연결은 해제할 수 없습니다.',
|
|
|
|
|
'has_locked_relationships' => '잠금된 연결이 포함되어 있어 처리할 수 없습니다.',
|
|
|
|
|
'entity_protected_by_locked_relationship' => '잠금된 연결로 보호된 항목은 삭제할 수 없습니다.',
|
|
|
|
|
'page_has_locked_children' => '잠금된 자식 연결이 있어 페이지를 삭제할 수 없습니다.',
|
|
|
|
|
'section_has_locked_children' => '잠금된 자식 연결이 있어 섹션을 삭제할 수 없습니다.',
|
feat: [quote] 견적 API Phase 2-3 완료 (Service + Controller Layer)
Phase 2 - Service Layer:
- QuoteService: 견적 CRUD + 상태관리 (확정/전환)
- QuoteNumberService: 견적번호 채번 (KD-{PREFIX}-YYMMDD-SEQ)
- FormulaEvaluatorService: 수식 평가 엔진 (SUM, IF, ROUND 등)
- QuoteCalculationService: 자동산출 (스크린/철재 제품)
- QuoteDocumentService: PDF 생성 및 이메일/카카오 발송
Phase 3 - Controller Layer:
- QuoteController: 16개 엔드포인트
- FormRequest 7개: Index, Store, Update, BulkDelete, Calculate, SendEmail, SendKakao
- QuoteApi.php: Swagger 문서 (12개 스키마, 16개 엔드포인트)
- routes/api.php: 16개 라우트 등록
i18n 키 추가:
- error.php: quote_not_found, formula_* 등
- message.php: quote.* 성공 메시지
2025-12-04 22:03:40 +09:00
|
|
|
|
|
|
|
|
// 견적 관련 (Quote)
|
|
|
|
|
'quote_not_found' => '견적 정보를 찾을 수 없습니다.',
|
|
|
|
|
'quote_not_editable' => '현재 상태에서는 견적을 수정할 수 없습니다.',
|
|
|
|
|
'quote_not_deletable' => '현재 상태에서는 견적을 삭제할 수 없습니다.',
|
|
|
|
|
'quote_not_finalizable' => '현재 상태에서는 견적을 확정할 수 없습니다.',
|
2026-02-07 03:27:07 +09:00
|
|
|
'quote_finalize_missing_fields' => '견적확정을 위해 다음 항목을 입력해주세요: :fields',
|
feat: [quote] 견적 API Phase 2-3 완료 (Service + Controller Layer)
Phase 2 - Service Layer:
- QuoteService: 견적 CRUD + 상태관리 (확정/전환)
- QuoteNumberService: 견적번호 채번 (KD-{PREFIX}-YYMMDD-SEQ)
- FormulaEvaluatorService: 수식 평가 엔진 (SUM, IF, ROUND 등)
- QuoteCalculationService: 자동산출 (스크린/철재 제품)
- QuoteDocumentService: PDF 생성 및 이메일/카카오 발송
Phase 3 - Controller Layer:
- QuoteController: 16개 엔드포인트
- FormRequest 7개: Index, Store, Update, BulkDelete, Calculate, SendEmail, SendKakao
- QuoteApi.php: Swagger 문서 (12개 스키마, 16개 엔드포인트)
- routes/api.php: 16개 라우트 등록
i18n 키 추가:
- error.php: quote_not_found, formula_* 등
- message.php: quote.* 성공 메시지
2025-12-04 22:03:40 +09:00
|
|
|
'quote_not_finalized' => '확정되지 않은 견적입니다.',
|
|
|
|
|
'quote_already_converted' => '이미 수주 전환된 견적입니다.',
|
|
|
|
|
'quote_not_convertible' => '현재 상태에서는 수주 전환할 수 없습니다.',
|
|
|
|
|
'quote_email_not_found' => '수신자 이메일 정보가 없습니다.',
|
|
|
|
|
'quote_phone_not_found' => '수신자 연락처 정보가 없습니다.',
|
|
|
|
|
|
|
|
|
|
// 수식 평가 관련 (Formula)
|
|
|
|
|
'formula_empty' => '수식이 비어있습니다.',
|
|
|
|
|
'formula_parentheses_mismatch' => '괄호가 올바르게 닫히지 않았습니다.',
|
|
|
|
|
'formula_unsupported_function' => '지원하지 않는 함수입니다: :function',
|
|
|
|
|
'formula_calculation_error' => '계산 오류: :expression',
|
2025-12-17 20:13:48 +09:00
|
|
|
|
|
|
|
|
// 휴가 관리 관련
|
|
|
|
|
'leave' => [
|
|
|
|
|
'not_found' => '휴가 정보를 찾을 수 없습니다.',
|
|
|
|
|
'not_editable' => '대기 상태의 휴가만 수정할 수 있습니다.',
|
|
|
|
|
'not_approvable' => '대기 상태의 휴가만 승인/반려할 수 있습니다.',
|
|
|
|
|
'not_cancellable' => '승인된 휴가만 취소할 수 있습니다.',
|
|
|
|
|
'insufficient_balance' => '잔여 휴가일수가 부족합니다.',
|
|
|
|
|
'overlapping' => '해당 기간에 이미 신청된 휴가가 있습니다.',
|
|
|
|
|
'balance_not_found' => '휴가 잔여일수 정보를 찾을 수 없습니다.',
|
|
|
|
|
],
|
feat: 근무/출퇴근 설정 및 현장 관리 API 구현
- 근무 설정 API (GET/PUT /settings/work)
- 근무유형, 소정근로시간, 연장근로시간, 근무요일, 출퇴근시간, 휴게시간
- 출퇴근 설정 API (GET/PUT /settings/attendance)
- GPS 출퇴근, 허용 반경, 본사 위치 설정
- 현장 관리 API (CRUD /sites)
- 현장 등록/수정/삭제, 활성화된 현장 목록(셀렉트박스용)
- GPS 좌표 기반 위치 관리
마이그레이션: work_settings, attendance_settings, sites 테이블
모델: WorkSetting, AttendanceSetting, Site (BelongsToTenant, SoftDeletes)
서비스: WorkSettingService, SiteService
Swagger 문서 및 i18n 메시지 키 추가
2025-12-17 20:46:37 +09:00
|
|
|
|
2026-02-05 14:45:53 +09:00
|
|
|
// 문서 관리 관련
|
|
|
|
|
'document' => [
|
|
|
|
|
'not_found' => '문서를 찾을 수 없습니다.',
|
|
|
|
|
'template_not_found' => '해당 조건에 맞는 문서 양식을 찾을 수 없습니다.',
|
|
|
|
|
'invalid_category' => '유효하지 않은 문서 분류입니다.',
|
|
|
|
|
'not_editable' => '현재 상태에서는 문서를 수정할 수 없습니다.',
|
|
|
|
|
'not_deletable' => '임시저장 상태의 문서만 삭제할 수 있습니다.',
|
|
|
|
|
'not_submittable' => '결재 요청할 수 없는 상태입니다.',
|
|
|
|
|
'not_approvable' => '결재 처리할 수 없는 상태입니다.',
|
|
|
|
|
'not_cancellable' => '취소할 수 없는 상태입니다.',
|
|
|
|
|
'not_your_turn' => '현재 결재 순서가 아닙니다.',
|
|
|
|
|
'only_creator_can_cancel' => '작성자만 취소할 수 있습니다.',
|
|
|
|
|
'approvers_required' => '결재선이 필요합니다.',
|
2026-02-13 03:41:27 +09:00
|
|
|
'no_order_items' => '수주에 개소(품목)가 없습니다.',
|
|
|
|
|
'already_created' => '이미 모든 개소에 대해 문서가 생성되었습니다.',
|
2026-02-05 14:45:53 +09:00
|
|
|
],
|
|
|
|
|
|
feat: [approval] 전자결재 모듈 API 구현
- 마이그레이션 4개 (approval_forms, approval_lines, approvals, approval_steps)
- 모델 4개 (ApprovalForm, ApprovalLine, Approval, ApprovalStep)
- ApprovalService 비즈니스 로직 (양식/결재선 CRUD, 기안함/결재함/참조함, 결재 액션)
- 컨트롤러 3개 (ApprovalFormController, ApprovalLineController, ApprovalController)
- FormRequest 13개 (양식/결재선/문서 검증)
- Swagger 문서 3개 (26개 엔드포인트)
- i18n 메시지/에러 키 추가
- 라우트 26개 등록
2025-12-17 23:23:20 +09:00
|
|
|
// 전자결재 관련
|
|
|
|
|
'approval' => [
|
|
|
|
|
'not_found' => '결재 문서를 찾을 수 없습니다.',
|
|
|
|
|
'form_not_found' => '결재 양식을 찾을 수 없습니다.',
|
2025-12-28 02:49:46 +09:00
|
|
|
'form_required' => '결재 양식이 필요합니다.',
|
feat: [approval] 전자결재 모듈 API 구현
- 마이그레이션 4개 (approval_forms, approval_lines, approvals, approval_steps)
- 모델 4개 (ApprovalForm, ApprovalLine, Approval, ApprovalStep)
- ApprovalService 비즈니스 로직 (양식/결재선 CRUD, 기안함/결재함/참조함, 결재 액션)
- 컨트롤러 3개 (ApprovalFormController, ApprovalLineController, ApprovalController)
- FormRequest 13개 (양식/결재선/문서 검증)
- Swagger 문서 3개 (26개 엔드포인트)
- i18n 메시지/에러 키 추가
- 라우트 26개 등록
2025-12-17 23:23:20 +09:00
|
|
|
'form_code_exists' => '중복된 양식 코드입니다.',
|
|
|
|
|
'form_in_use' => '사용 중인 양식은 삭제할 수 없습니다.',
|
|
|
|
|
'line_not_found' => '결재선을 찾을 수 없습니다.',
|
|
|
|
|
'not_editable' => '임시저장 상태의 문서만 수정할 수 있습니다.',
|
|
|
|
|
'not_deletable' => '임시저장 상태의 문서만 삭제할 수 있습니다.',
|
|
|
|
|
'not_submittable' => '임시저장 상태의 문서만 상신할 수 있습니다.',
|
|
|
|
|
'not_actionable' => '진행중인 문서에서만 결재 가능합니다.',
|
|
|
|
|
'not_cancellable' => '진행중인 문서만 회수할 수 있습니다.',
|
|
|
|
|
'not_your_turn' => '현재 결재 순서가 아닙니다.',
|
|
|
|
|
'only_drafter_can_cancel' => '기안자만 회수할 수 있습니다.',
|
|
|
|
|
'steps_required' => '결재선은 필수입니다.',
|
|
|
|
|
'reject_comment_required' => '반려 사유는 필수입니다.',
|
|
|
|
|
'not_referee' => '참조자가 아닙니다.',
|
|
|
|
|
],
|
|
|
|
|
|
feat: 근무/출퇴근 설정 및 현장 관리 API 구현
- 근무 설정 API (GET/PUT /settings/work)
- 근무유형, 소정근로시간, 연장근로시간, 근무요일, 출퇴근시간, 휴게시간
- 출퇴근 설정 API (GET/PUT /settings/attendance)
- GPS 출퇴근, 허용 반경, 본사 위치 설정
- 현장 관리 API (CRUD /sites)
- 현장 등록/수정/삭제, 활성화된 현장 목록(셀렉트박스용)
- GPS 좌표 기반 위치 관리
마이그레이션: work_settings, attendance_settings, sites 테이블
모델: WorkSetting, AttendanceSetting, Site (BelongsToTenant, SoftDeletes)
서비스: WorkSettingService, SiteService
Swagger 문서 및 i18n 메시지 키 추가
2025-12-17 20:46:37 +09:00
|
|
|
// 근무 설정 관련
|
|
|
|
|
'work_setting' => [
|
|
|
|
|
'invalid_work_type' => '유효하지 않은 근무 유형입니다.',
|
|
|
|
|
'invalid_work_days' => '유효하지 않은 근무요일입니다.',
|
|
|
|
|
'invalid_time_range' => '출근시간은 퇴근시간보다 이전이어야 합니다.',
|
|
|
|
|
'break_time_invalid' => '휴게시간 설정이 올바르지 않습니다.',
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 출퇴근 설정 관련
|
|
|
|
|
'attendance_setting' => [
|
|
|
|
|
'invalid_radius' => '허용 반경이 유효하지 않습니다.',
|
|
|
|
|
'invalid_coordinates' => '좌표가 유효하지 않습니다.',
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 현장 관리 관련
|
|
|
|
|
'site' => [
|
|
|
|
|
'not_found' => '현장 정보를 찾을 수 없습니다.',
|
|
|
|
|
'name_required' => '현장명은 필수입니다.',
|
|
|
|
|
'name_too_long' => '현장명은 100자를 초과할 수 없습니다.',
|
|
|
|
|
'invalid_latitude' => '위도는 -90 ~ 90 사이여야 합니다.',
|
|
|
|
|
'invalid_longitude' => '경도는 -180 ~ 180 사이여야 합니다.',
|
|
|
|
|
'has_dependencies' => '연관된 데이터가 있어 삭제할 수 없습니다.',
|
|
|
|
|
],
|
2025-12-18 10:56:16 +09:00
|
|
|
|
|
|
|
|
// 급여 관리 관련
|
|
|
|
|
'payroll' => [
|
|
|
|
|
'not_found' => '급여 정보를 찾을 수 없습니다.',
|
|
|
|
|
'already_exists' => '해당 연월에 이미 급여가 등록되어 있습니다.',
|
|
|
|
|
'not_editable' => '작성중 상태의 급여만 수정할 수 있습니다.',
|
|
|
|
|
'not_deletable' => '작성중 상태의 급여만 삭제할 수 있습니다.',
|
|
|
|
|
'not_confirmable' => '작성중 상태의 급여만 확정할 수 있습니다.',
|
|
|
|
|
'not_payable' => '확정된 급여만 지급 처리할 수 있습니다.',
|
|
|
|
|
'invalid_withdrawal' => '유효하지 않은 출금 내역입니다.',
|
|
|
|
|
'user_not_found' => '직원 정보를 찾을 수 없습니다.',
|
|
|
|
|
'no_base_salary' => '기본급이 설정되지 않았습니다.',
|
|
|
|
|
],
|
2025-12-18 11:23:35 +09:00
|
|
|
|
2026-01-19 20:53:36 +09:00
|
|
|
// 세금계산서 관련
|
|
|
|
|
'tax_invoice' => [
|
|
|
|
|
'not_found' => '세금계산서 정보를 찾을 수 없습니다.',
|
|
|
|
|
'cannot_edit' => '발행된 세금계산서는 수정할 수 없습니다.',
|
|
|
|
|
'cannot_delete' => '발행된 세금계산서는 삭제할 수 없습니다.',
|
|
|
|
|
'already_issued' => '이미 발행된 세금계산서입니다.',
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 매출 관련
|
|
|
|
|
'sale' => [
|
|
|
|
|
'not_found' => '매출 정보를 찾을 수 없습니다.',
|
|
|
|
|
'cannot_edit' => '확정된 매출은 수정할 수 없습니다.',
|
|
|
|
|
'cannot_delete' => '확정된 매출은 삭제할 수 없습니다.',
|
|
|
|
|
'cannot_confirm' => '이미 확정된 매출입니다.',
|
|
|
|
|
'statement_requires_confirmed' => '확정된 매출만 거래명세서를 발행할 수 있습니다.',
|
|
|
|
|
'statement_already_issued' => '이미 발행된 거래명세서입니다.',
|
|
|
|
|
'recipient_email_required' => '수신자 이메일이 필요합니다.',
|
|
|
|
|
],
|
|
|
|
|
|
2025-12-18 11:23:35 +09:00
|
|
|
// 대시보드 관련
|
|
|
|
|
'dashboard' => [
|
|
|
|
|
'invalid_period' => '기간은 week, month, quarter 중 하나여야 합니다.',
|
|
|
|
|
],
|
2025-12-18 13:51:40 +09:00
|
|
|
|
|
|
|
|
// AI 리포트 관련
|
|
|
|
|
'ai_report' => [
|
|
|
|
|
'api_key_not_configured' => 'AI API 키가 설정되지 않았습니다.',
|
|
|
|
|
'api_call_failed' => 'AI API 호출에 실패했습니다.',
|
|
|
|
|
'connection_failed' => 'AI 서버 연결에 실패했습니다.',
|
|
|
|
|
],
|
|
|
|
|
|
2025-12-18 14:21:37 +09:00
|
|
|
// 가지급금 관리 관련
|
|
|
|
|
'loan' => [
|
|
|
|
|
'not_found' => '가지급금 정보를 찾을 수 없습니다.',
|
|
|
|
|
'not_editable' => '정산 완료된 가지급금은 수정할 수 없습니다.',
|
|
|
|
|
'not_deletable' => '정산 완료된 가지급금은 삭제할 수 없습니다.',
|
|
|
|
|
'not_settleable' => '이미 정산 완료된 가지급금입니다.',
|
|
|
|
|
'settlement_exceeds' => '정산금액이 가지급금액을 초과할 수 없습니다.',
|
|
|
|
|
'invalid_withdrawal' => '유효하지 않은 출금 내역입니다.',
|
|
|
|
|
'user_not_found' => '직원 정보를 찾을 수 없습니다.',
|
|
|
|
|
],
|
|
|
|
|
|
2025-12-18 13:51:40 +09:00
|
|
|
// 내부 서버간 통신 관련
|
|
|
|
|
'internal' => [
|
|
|
|
|
'secret_not_configured' => '내부 교환 비밀키가 설정되지 않았습니다.',
|
|
|
|
|
'signature_expired' => '서명이 만료되었습니다.',
|
|
|
|
|
'invalid_exp' => '만료 시간이 유효하지 않습니다.',
|
|
|
|
|
'invalid_signature' => '서명이 유효하지 않습니다.',
|
|
|
|
|
'token_issue_failed' => '토큰 발급에 실패했습니다.',
|
|
|
|
|
],
|
feat: Phase 5 API 개발 완료 (사용자 초대, 알림설정, 계정관리, 거래명세서)
5.1 사용자 초대 기능:
- UserInvitation 마이그레이션, 모델, 서비스, 컨트롤러, Swagger
- 초대 발송/수락/취소/재발송 API
5.2 알림설정 확장:
- NotificationSetting 마이그레이션, 모델, 서비스, 컨트롤러, Swagger
- 채널별/유형별 알림 설정 관리
5.3 계정정보 수정 API:
- 회원탈퇴, 사용중지, 약관동의 관리
- AccountService, AccountController, Swagger
5.4 매출 거래명세서 API:
- 거래명세서 조회/발행/이메일발송
- SaleService 확장, Swagger 문서화
2025-12-19 14:52:53 +09:00
|
|
|
|
|
|
|
|
// 사용자 초대 관련
|
|
|
|
|
'invitation' => [
|
|
|
|
|
'already_member' => '이미 테넌트에 등록된 사용자입니다.',
|
|
|
|
|
'already_pending' => '대기 중인 초대가 이미 존재합니다.',
|
|
|
|
|
'not_found' => '초대를 찾을 수 없습니다.',
|
|
|
|
|
'expired' => '만료된 초대입니다.',
|
|
|
|
|
'invalid_status' => '유효하지 않은 초대 상태입니다.',
|
|
|
|
|
'cannot_cancel' => '취소할 수 없는 초대입니다.',
|
|
|
|
|
'cannot_resend' => '재발송할 수 없는 초대입니다.',
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 알림 설정 관련
|
|
|
|
|
'notification_setting' => [
|
|
|
|
|
'not_found' => '알림 설정을 찾을 수 없습니다.',
|
|
|
|
|
'invalid_type' => '유효하지 않은 알림 유형입니다.',
|
|
|
|
|
'invalid_channel' => '유효하지 않은 알림 채널입니다.',
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 매출 관련
|
|
|
|
|
'sale' => [
|
|
|
|
|
'cannot_edit' => '확정된 매출은 수정할 수 없습니다.',
|
|
|
|
|
'cannot_delete' => '확정된 매출은 삭제할 수 없습니다.',
|
|
|
|
|
'cannot_confirm' => '확정할 수 없는 상태입니다.',
|
|
|
|
|
'statement_requires_confirmed' => '확정된 매출만 거래명세서를 발행할 수 있습니다.',
|
|
|
|
|
'recipient_email_required' => '수신자 이메일이 필요합니다.',
|
|
|
|
|
],
|
|
|
|
|
|
2025-12-24 19:41:33 +09:00
|
|
|
// 어음 관리 관련
|
|
|
|
|
'bill' => [
|
|
|
|
|
'duplicate_number' => '이미 존재하는 어음번호입니다.',
|
|
|
|
|
],
|
|
|
|
|
|
feat: Phase 5 API 개발 완료 (사용자 초대, 알림설정, 계정관리, 거래명세서)
5.1 사용자 초대 기능:
- UserInvitation 마이그레이션, 모델, 서비스, 컨트롤러, Swagger
- 초대 발송/수락/취소/재발송 API
5.2 알림설정 확장:
- NotificationSetting 마이그레이션, 모델, 서비스, 컨트롤러, Swagger
- 채널별/유형별 알림 설정 관리
5.3 계정정보 수정 API:
- 회원탈퇴, 사용중지, 약관동의 관리
- AccountService, AccountController, Swagger
5.4 매출 거래명세서 API:
- 거래명세서 조회/발행/이메일발송
- SaleService 확장, Swagger 문서화
2025-12-19 14:52:53 +09:00
|
|
|
// 계정 관리 관련
|
|
|
|
|
'account' => [
|
|
|
|
|
'invalid_password' => '비밀번호가 일치하지 않습니다.',
|
|
|
|
|
'tenant_membership_not_found' => '테넌트 멤버십 정보를 찾을 수 없습니다.',
|
|
|
|
|
'already_withdrawn' => '이미 탈퇴한 계정입니다.',
|
|
|
|
|
'cannot_withdraw' => '탈퇴할 수 없는 상태입니다.',
|
|
|
|
|
],
|
2025-12-19 16:53:49 +09:00
|
|
|
|
|
|
|
|
// 구독 관련
|
|
|
|
|
'subscription' => [
|
|
|
|
|
'already_active' => '이미 활성화된 구독이 있습니다.',
|
|
|
|
|
'not_cancellable' => '취소할 수 없는 상태입니다.',
|
|
|
|
|
'not_renewable' => '갱신할 수 없는 상태입니다.',
|
|
|
|
|
'not_suspendable' => '일시정지할 수 없는 상태입니다.',
|
|
|
|
|
'not_resumable' => '재개할 수 없는 상태입니다.',
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 데이터 내보내기 관련
|
|
|
|
|
'export' => [
|
|
|
|
|
'already_in_progress' => '이미 진행 중인 내보내기가 있습니다.',
|
|
|
|
|
'not_found' => '내보내기 요청을 찾을 수 없습니다.',
|
|
|
|
|
'failed' => '내보내기 처리 중 오류가 발생했습니다.',
|
|
|
|
|
],
|
2025-12-22 15:30:38 +09:00
|
|
|
|
|
|
|
|
// 회사 추가 신청 관련
|
|
|
|
|
'company' => [
|
|
|
|
|
'not_found' => '회사 추가 신청을 찾을 수 없습니다.',
|
|
|
|
|
'already_pending' => '이미 대기 중인 동일 사업자등록번호 신청이 있습니다.',
|
|
|
|
|
'already_processed' => '이미 처리된 신청입니다.',
|
|
|
|
|
'tenant_creation_failed' => '테넌트 생성에 실패했습니다.',
|
|
|
|
|
'invalid_business_number' => '유효하지 않은 사업자등록번호입니다.',
|
|
|
|
|
],
|
2025-12-23 12:45:28 +09:00
|
|
|
|
|
|
|
|
// FCM 푸시 알림 관련
|
|
|
|
|
'fcm' => [
|
|
|
|
|
'no_tokens' => '발송 대상 토큰이 없습니다.',
|
|
|
|
|
'send_failed' => 'FCM 발송 중 오류가 발생했습니다.',
|
|
|
|
|
'token_not_found' => 'FCM 토큰을 찾을 수 없습니다.',
|
|
|
|
|
],
|
2026-01-08 11:11:54 +09:00
|
|
|
|
|
|
|
|
// 수주 관련
|
|
|
|
|
'order' => [
|
|
|
|
|
'cannot_update_completed' => '완료 또는 취소된 수주는 수정할 수 없습니다.',
|
|
|
|
|
'cannot_delete_in_progress' => '진행 중이거나 완료된 수주는 삭제할 수 없습니다.',
|
2026-02-09 21:31:19 +09:00
|
|
|
'cannot_delete_has_work_orders' => '작업지시가 존재하는 수주는 삭제할 수 없습니다. 작업지시를 먼저 삭제해주세요.',
|
|
|
|
|
'cannot_delete_has_shipments' => '출하 정보가 존재하는 수주는 삭제할 수 없습니다. 출하를 먼저 삭제해주세요.',
|
2026-01-08 11:11:54 +09:00
|
|
|
'invalid_status_transition' => '유효하지 않은 상태 전환입니다.',
|
2026-01-08 20:17:40 +09:00
|
|
|
'already_created_from_quote' => '이미 해당 견적에서 수주가 생성되었습니다.',
|
|
|
|
|
'must_be_confirmed_for_production' => '확정 상태의 수주만 생산지시를 생성할 수 있습니다.',
|
|
|
|
|
'production_order_already_exists' => '이미 생산지시가 존재합니다.',
|
2026-01-16 21:58:57 +09:00
|
|
|
'cannot_revert_completed' => '완료된 수주의 생산지시는 되돌릴 수 없습니다.',
|
|
|
|
|
'cannot_revert_not_confirmed' => '수주확정 상태에서만 되돌리기가 가능합니다.',
|
2026-02-05 21:58:49 +09:00
|
|
|
'cannot_sync_after_production' => '생산지시 이후의 수주는 견적에서 자동 동기화할 수 없습니다.',
|
2026-01-08 20:17:40 +09:00
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 견적 관련
|
|
|
|
|
'quote' => [
|
|
|
|
|
'not_found' => '견적을 찾을 수 없습니다.',
|
2026-01-08 11:11:54 +09:00
|
|
|
],
|
2026-01-13 19:49:44 +09:00
|
|
|
|
|
|
|
|
// 작업지시 관련
|
|
|
|
|
'work_order' => [
|
|
|
|
|
'not_found' => '작업지시를 찾을 수 없습니다.',
|
|
|
|
|
'cannot_delete_in_progress' => '진행중이거나 완료된 작업지시는 삭제할 수 없습니다.',
|
|
|
|
|
'not_bending_process' => '벤딩 공정이 아닙니다.',
|
|
|
|
|
'invalid_transition' => "상태를 ':from'에서 ':to'(으)로 변경할 수 없습니다. 허용된 상태: :allowed",
|
2026-01-16 15:38:52 +09:00
|
|
|
'assignee_required_for_linked' => '수주 연동 등록 시 담당자를 선택해주세요.',
|
2026-02-10 08:35:57 +09:00
|
|
|
'no_inspection_template' => '검사용 문서 양식이 설정되지 않았습니다.',
|
2026-02-12 09:39:48 +09:00
|
|
|
'no_work_log_template' => '작업일지 양식이 설정되지 않았습니다.',
|
2026-01-13 19:49:44 +09:00
|
|
|
],
|
2026-01-14 17:08:59 +09:00
|
|
|
|
|
|
|
|
// 검사 관련
|
|
|
|
|
'inspection' => [
|
|
|
|
|
'not_found' => '검사를 찾을 수 없습니다.',
|
|
|
|
|
'cannot_delete_completed' => '완료된 검사는 삭제할 수 없습니다.',
|
|
|
|
|
'already_completed' => '이미 완료된 검사입니다.',
|
|
|
|
|
],
|
2026-01-19 20:23:30 +09:00
|
|
|
|
|
|
|
|
// 입찰 관련
|
|
|
|
|
'bidding' => [
|
|
|
|
|
'not_found' => '입찰을 찾을 수 없습니다.',
|
|
|
|
|
'already_converted' => '이미 입찰로 변환된 견적입니다.',
|
|
|
|
|
'already_registered' => '이미 입찰이 등록된 견적입니다. (입찰번호: :code)',
|
|
|
|
|
'cannot_delete' => '해당 입찰은 삭제할 수 없습니다.',
|
|
|
|
|
'invalid_status' => '유효하지 않은 입찰 상태입니다.',
|
|
|
|
|
],
|
2026-01-19 20:53:36 +09:00
|
|
|
|
feat:E-Sign 전자계약 i18n 메시지 키 추가
- message.esign: 12개 (created, cancelled, sent, reminded, fields_configured, otp_sent, otp_verified, signed, rejected, completed, verified, downloaded)
- error.esign: 16개 (invalid_token, token_expired, contract_not_signable, already_completed, already_cancelled, already_signed, invalid_status_for_send, no_sign_fields, cannot_remind, fields_only_in_draft, not_verified, otp_max_attempts, otp_not_sent, otp_expired, otp_invalid, file_not_found)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 07:15:42 +09:00
|
|
|
// 전자계약 (E-Sign)
|
|
|
|
|
'esign' => [
|
|
|
|
|
'invalid_token' => '유효하지 않은 서명 링크입니다.',
|
|
|
|
|
'token_expired' => '서명 링크가 만료되었습니다.',
|
|
|
|
|
'contract_not_signable' => '현재 서명할 수 없는 계약입니다.',
|
|
|
|
|
'already_completed' => '이미 완료된 계약입니다.',
|
|
|
|
|
'already_cancelled' => '이미 취소된 계약입니다.',
|
|
|
|
|
'already_signed' => '이미 서명이 완료되었습니다.',
|
|
|
|
|
'invalid_status_for_send' => '초안 상태의 계약만 발송할 수 있습니다.',
|
|
|
|
|
'no_sign_fields' => '서명 필드가 설정되지 않았습니다. 서명 위치를 먼저 설정해 주세요.',
|
|
|
|
|
'cannot_remind' => '현재 상태에서는 리마인더를 발송할 수 없습니다.',
|
|
|
|
|
'fields_only_in_draft' => '초안 상태에서만 서명 위치를 설정할 수 있습니다.',
|
|
|
|
|
'not_verified' => '본인인증을 먼저 완료해 주세요.',
|
|
|
|
|
'otp_max_attempts' => 'OTP 인증 시도 횟수를 초과했습니다. 새로운 인증 코드를 요청해 주세요.',
|
|
|
|
|
'otp_not_sent' => '인증 코드가 발송되지 않았습니다. 먼저 인증 코드를 요청해 주세요.',
|
|
|
|
|
'otp_expired' => '인증 코드가 만료되었습니다. 새로운 인증 코드를 요청해 주세요.',
|
|
|
|
|
'otp_invalid' => '인증 코드가 올바르지 않습니다.',
|
|
|
|
|
'file_not_found' => '계약 문서 파일을 찾을 수 없습니다.',
|
|
|
|
|
],
|
|
|
|
|
|
2026-01-19 20:53:36 +09:00
|
|
|
// 계약 관련
|
|
|
|
|
'contract' => [
|
|
|
|
|
'not_found' => '계약을 찾을 수 없습니다.',
|
|
|
|
|
'already_registered' => '이미 계약이 등록된 입찰입니다. (계약번호: :code)',
|
|
|
|
|
'bidding_not_awarded' => '낙찰 상태인 입찰만 계약으로 전환할 수 있습니다.',
|
|
|
|
|
'cannot_delete' => '해당 계약은 삭제할 수 없습니다.',
|
|
|
|
|
'invalid_status' => '유효하지 않은 계약 상태입니다.',
|
|
|
|
|
],
|
2025-08-20 20:23:01 +09:00
|
|
|
];
|