추가된 문서: 1. 프로젝트_전체_분석.md - 시스템 아키텍처 분석 - 디렉토리 구조 정리 - 데이터베이스 설계 상세 - 주요 기능 및 비즈니스 로직 2. 보험코드_매핑_문제_분석.md - Excel 입고 시 보험코드 처리 문제 분석 - 앞자리 0 누락 문제 원인과 해결방안 - 영향 범위 및 수정 방법 3. 입고_프로세스_개선방안.md - 성분코드-보험코드 매핑 구조 설명 - 개선된 입고 프로세스 설계 - 성분코드 기준 재고 관리 방법 - 구현 우선순위 및 기대 효과 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
128 lines
3.9 KiB
Markdown
128 lines
3.9 KiB
Markdown
# Excel 입고 시 보험코드 매핑 문제 분석
|
|
|
|
## 현상
|
|
Excel 파일에서 입고 처리 시, 보험코드가 제대로 매핑되지 않는 문제 발생
|
|
|
|
## 문제 원인
|
|
|
|
### 1. 보험코드 형식
|
|
- **표준 보험코드**: 9자리 문자열 (예: `060600420`, `062401050`)
|
|
- 일부 코드는 0으로 시작함
|
|
|
|
### 2. Excel 읽기 문제
|
|
```python
|
|
# 현재 상황
|
|
Excel 파일의 제품코드 컬럼 → pandas가 int64로 자동 인식
|
|
060600420 → 60600420 (앞의 0이 사라짐)
|
|
062401050 → 62401050 (앞의 0이 사라짐)
|
|
```
|
|
|
|
### 3. DB 매핑 실패
|
|
- DB의 `herb_items.insurance_code`: `"060600420"` (9자리 문자열)
|
|
- Excel에서 읽은 값: `60600420` (8자리 숫자)
|
|
- **결과**: 매칭 실패 → 새로운 herb_item 생성
|
|
|
|
## 현재 코드 분석
|
|
|
|
### excel_processor.py (19번 줄)
|
|
```python
|
|
HANISARANG_MAPPING = {
|
|
'품목명': 'herb_name',
|
|
'제품코드': 'insurance_code', # 여기서 매핑은 되지만 타입 처리 안함
|
|
...
|
|
}
|
|
```
|
|
|
|
### app.py (577-589번 줄)
|
|
```python
|
|
# 약재 확인/생성
|
|
cursor.execute("""
|
|
SELECT herb_item_id FROM herb_items
|
|
WHERE insurance_code = ? OR herb_name = ?
|
|
""", (row.get('insurance_code'), row['herb_name'])) # insurance_code가 숫자로 들어옴
|
|
|
|
if not herb:
|
|
# 매칭 실패 시 새로 생성 (잘못된 코드로)
|
|
cursor.execute("""
|
|
INSERT INTO herb_items (insurance_code, herb_name)
|
|
VALUES (?, ?)
|
|
""", (row.get('insurance_code'), row['herb_name']))
|
|
```
|
|
|
|
## 해결 방안
|
|
|
|
### 방안 1: Excel 읽을 때 문자열로 처리 (권장)
|
|
```python
|
|
# excel_processor.py 수정
|
|
def read_excel(self, file_path):
|
|
try:
|
|
# 제품코드를 문자열로 읽도록 dtype 지정
|
|
self.df_original = pd.read_excel(
|
|
file_path,
|
|
dtype={'제품코드': str, 'insurance_code': str}
|
|
)
|
|
# 또는 converters 사용
|
|
# converters={'제품코드': lambda x: str(x).zfill(9)}
|
|
```
|
|
|
|
### 방안 2: 처리 시 9자리로 패딩
|
|
```python
|
|
# excel_processor.py의 process_hanisarang/process_haninfo 메소드에서
|
|
if 'insurance_code' in df_mapped.columns:
|
|
# 숫자로 읽힌 경우 9자리로 패딩
|
|
df_mapped['insurance_code'] = df_mapped['insurance_code'].apply(
|
|
lambda x: str(int(x)).zfill(9) if pd.notna(x) and str(x).isdigit() else x
|
|
)
|
|
```
|
|
|
|
### 방안 3: app.py에서 매핑 시 보정
|
|
```python
|
|
# app.py의 upload_purchase_excel 함수에서
|
|
insurance_code = row.get('insurance_code')
|
|
if insurance_code and str(insurance_code).isdigit():
|
|
# 숫자인 경우 9자리로 패딩
|
|
insurance_code = str(int(insurance_code)).zfill(9)
|
|
|
|
cursor.execute("""
|
|
SELECT herb_item_id FROM herb_items
|
|
WHERE insurance_code = ? OR herb_name = ?
|
|
""", (insurance_code, row['herb_name']))
|
|
```
|
|
|
|
## 영향 범위
|
|
|
|
### 이미 잘못 등록된 데이터
|
|
```sql
|
|
-- 잘못된 보험코드로 등록된 herb_items 확인
|
|
SELECT herb_item_id, herb_name, insurance_code
|
|
FROM herb_items
|
|
WHERE length(insurance_code) = 8
|
|
AND insurance_code NOT LIKE 'A%';
|
|
```
|
|
|
|
### 수정 필요 테이블
|
|
1. `herb_items` - insurance_code 수정
|
|
2. `purchase_receipt_lines` - 잘못된 herb_item_id 참조
|
|
3. `inventory_lots` - 잘못된 herb_item_id 참조
|
|
|
|
## 권장 해결 순서
|
|
|
|
1. **즉시 조치**: `excel_processor.py` 수정하여 제품코드를 문자열로 읽도록 처리
|
|
2. **데이터 정리**: 기존 잘못 등록된 herb_items 정리
|
|
3. **검증 로직 추가**: 보험코드 형식 검증 (9자리 또는 특정 패턴)
|
|
4. **테스트**: 샘플 파일로 입고 처리 테스트
|
|
|
|
## 추가 고려사항
|
|
|
|
1. **보험코드 형식 표준화**
|
|
- 9자리 숫자: `060600420`
|
|
- 영문+숫자: `A001100`
|
|
- 기타 형식 확인 필요
|
|
|
|
2. **Excel 파일 형식 가이드**
|
|
- 제품코드를 텍스트 형식으로 저장하도록 안내
|
|
- 또는 '060600420 형태로 입력 (앞에 ' 추가)
|
|
|
|
3. **중복 방지**
|
|
- 같은 약재가 다른 insurance_code로 중복 등록되는 것 방지
|
|
- 약재명 + 제조사로 추가 검증 |