feat: 구매신청 기능 완성 및 SUPPORT/SPECIAL 카테고리 개선

- 모든 카테고리 구매신청 기능 완성 (PIPE, FITTING, VALVE, FLANGE, GASKET, BOLT, SUPPORT, SPECIAL, UNKNOWN)
- 구매신청 완료 항목: 회색 배경, 체크박스 비활성화, '구매신청완료' 배지 표시
- 전체 선택/구매신청 시 이미 구매신청된 항목 자동 제외
- 구매신청 quantity 타입 에러 수정 (문자열 -> 정수 변환)

SUPPORT 카테고리 (구 U-BOLT):
- U-BOLT -> SUPPORT로 카테고리명 변경
- 클램프, 유볼트, 우레탄블럭슈 분류 개선
- 테이블 헤더: 선택-종류-타입-크기-디스크립션-추가요구-사용자요구-수량
- 크기 정보 main_nom 필드에서 가져오기 (배관 인치)
- 엑셀 내보내기 형식 조정

SPECIAL 카테고리:
- SPECIAL 키워드 자재 자동 분류 (SPECIFICATION 제외)
- 파일 업로드 시 SPECIAL 카테고리 처리 로직 추가
- 도면번호 필드 추가 (drawing_name, line_no)
- 타입 필드: 크기/스케줄/재질 제외한 핵심 정보 표시
- 엑셀 DWG_NAME, LINE_NUM 컬럼 파싱 및 저장

FITTING 카테고리:
- 테이블 컬럼 너비 조정 (선택 2%, 종류 8.5%, 수량 12%)

구매신청 관리:
- 엑셀 재다운로드 형식 개선 (BOM 페이지와 동일한 형식)
- 그룹화된 자재 정보 포함하여 저장 및 다운로드
This commit is contained in:
Hyungi Ahn
2025-10-14 12:39:25 +09:00
parent e468663386
commit e27020ae9b
44 changed files with 13102 additions and 176 deletions

View File

@@ -83,7 +83,8 @@ async def signup_request(
'position': signup_data.position,
'phone': signup_data.phone,
'role': 'user',
'is_active': False # 비활성 상태로 승인 대기 표시
'is_active': False, # 하위 호환성
'status': 'pending' # 새로운 status 체계: 승인 대기
})
# 가입 사유 저장 (notes 컬럼 활용)
@@ -130,13 +131,13 @@ async def get_signup_requests(
detail="관리자만 접근 가능합니다"
)
# 승인 대기 중인 사용자 조회 (is_active=False인 사용자)
# 승인 대기 중인 사용자 조회 (status='pending'인 사용자)
query = text("""
SELECT
user_id as id, username, name, email, department, position,
phone, notes, created_at
user_id, username, name, email, department, position,
phone, created_at, role, is_active, status
FROM users
WHERE is_active = FALSE
WHERE status = 'pending'
ORDER BY created_at DESC
""")
@@ -145,15 +146,18 @@ async def get_signup_requests(
pending_users = []
for row in results:
pending_users.append({
"id": row.id,
"user_id": row.user_id,
"id": row.user_id, # 호환성을 위해 둘 다 제공
"username": row.username,
"name": row.name,
"email": row.email,
"department": row.department,
"position": row.position,
"phone": row.phone,
"reason": row.notes,
"requested_at": row.created_at.isoformat() if row.created_at else None
"role": row.role,
"created_at": row.created_at.isoformat() if row.created_at else None,
"requested_at": row.created_at.isoformat() if row.created_at else None,
"is_active": row.is_active
})
return {
@@ -201,9 +205,10 @@ async def approve_signup(
update_query = text("""
UPDATE users
SET is_active = TRUE,
status = 'active',
access_level = :access_level,
updated_at = CURRENT_TIMESTAMP
WHERE user_id = :user_id AND is_active = FALSE
WHERE user_id = :user_id AND status = 'pending'
RETURNING user_id as id, username, name
""")