diff --git a/backend/samples/README.md b/backend/samples/README.md new file mode 100644 index 0000000..1dae1a4 --- /dev/null +++ b/backend/samples/README.md @@ -0,0 +1,256 @@ +# 참고 코드 샘플 (Reference Code Samples) + +이 폴더는 QR 생성 및 라벨 프린터 출력 기능 개발을 위한 참고용 코드입니다. + +## 📁 파일 목록 + +### 1. 라벨 프린팅 관련 + +#### `product_label.py` (55KB) +- **용도**: 제품 라벨 생성 및 프린터 출력 (메인) +- **주요 기능**: + - PIL/Pillow를 사용한 라벨 이미지 생성 + - 약품명, 용법용량, 보관방법 등 텍스트 렌더링 + - Brother QL 시리즈 라벨 프린터 제어 + - `brother_ql` 라이브러리 사용 +- **핵심 클래스/함수**: + - `create_prescription_label()`: 처방전 라벨 생성 + - `print_to_brother_ql()`: 프린터로 전송 + - QR 코드 이미지 삽입 가능 + +#### `print_label.py` (41KB) +- **용도**: 라벨 프린팅 유틸리티 +- **주요 기능**: + - 프린터 드라이버 연동 + - 라벨 레이아웃 설정 + - 프린터 상태 확인 + +#### `barcode_print.py` (15KB) +- **용도**: 바코드 생성 및 프린팅 +- **주요 기능**: + - 1D 바코드 생성 (CODE128, EAN13 등) + - `python-barcode` 라이브러리 사용 + - 바코드 이미지를 라벨에 삽입 + +#### `printers.json` (706B) +- **용도**: 프린터 설정 파일 +- **내용**: + ```json + { + "default_printer": "Brother QL-800", + "label_size": "62", + "print_quality": "high" + } + ``` + +### 2. 바코드 리딩 관련 + +#### `barcode_reader_gui.py` (26KB) +- **용도**: 바코드 스캐너 GUI 애플리케이션 +- **주요 기능**: + - PyQt5 기반 GUI + - 실시간 바코드 스캔 처리 + - DB 조회 및 결과 표시 + - 버퍼 처리 및 중복 방지 +- **참고 포인트**: + - QThread를 사용한 백그라운드 처리 패턴 + - Signal/Slot 연결 방식 + - 에러 핸들링 방식 + +#### `barcode_reader.py` (4.5KB) +- **용도**: 바코드 리더 핵심 로직 +- **주요 기능**: + - USB HID 바코드 스캐너 연동 + - Raw 데이터 파싱 + - 바코드 유효성 검증 + +#### `barcode_reader_README.md` (3.6KB) +- **용도**: 바코드 리더 사용 가이드 +- **내용**: + - 하드웨어 설정 방법 + - USB 권한 설정 + - 트러블슈팅 + +## 🎯 QR 생성 및 라벨 프린팅 개발 가이드 + +### Phase 2-1: QR 코드 생성 + +**필요한 라이브러리**: +```bash +pip install qrcode[pil] pillow +``` + +**QR 생성 예시** (Python): +```python +import qrcode +from PIL import Image + +# QR 데이터: 토큰 URL +qr_data = "https://pharmacy.example.com/claim?t=abc123..." + +# QR 코드 생성 +qr = qrcode.QRCode( + version=1, + error_correction=qrcode.constants.ERROR_CORRECT_L, + box_size=10, + border=4, +) +qr.add_data(qr_data) +qr.make(fit=True) + +# 이미지로 변환 +qr_img = qr.make_image(fill_color="black", back_color="white") +qr_img.save("qr_label.png") +``` + +### Phase 2-2: 라벨에 QR 삽입 + +**참고 파일**: `product_label.py`의 `create_prescription_label()` 함수 + +**핵심 로직**: +```python +from PIL import Image, ImageDraw, ImageFont + +# 라벨 캔버스 생성 (Brother QL-800 기준: 62mm x 100mm) +label_width = 696 # px +label_height = 1109 # px +label = Image.new('RGB', (label_width, label_height), 'white') +draw = ImageDraw.Draw(label) + +# QR 코드 로드 +qr_img = Image.open("qr_label.png") +qr_img = qr_img.resize((200, 200)) # 크기 조정 + +# QR 코드 삽입 (중앙 상단) +qr_x = (label_width - 200) // 2 +qr_y = 50 +label.paste(qr_img, (qr_x, qr_y)) + +# 텍스트 추가 (판매 정보) +font = ImageFont.truetype("malgun.ttf", 28) +draw.text((50, 300), "영수증 번호: 20260123000042", fill='black', font=font) +draw.text((50, 350), "판매 금액: 45,000원", fill='black', font=font) +draw.text((50, 400), "적립 포인트: 1,350P", fill='black', font=font) +draw.text((50, 450), "유효기간: 30일", fill='black', font=font) + +# 라벨 저장 +label.save("sales_qr_label.png") +``` + +### Phase 2-3: Brother QL 프린터 출력 + +**필요한 라이브러리**: +```bash +pip install brother_ql +``` + +**프린터 출력 예시**: +```python +from brother_ql.conversion import convert +from brother_ql.backends.helpers import send +from brother_ql.raster import BrotherQLRaster + +# 프린터 모델 및 라벨 크기 +printer_model = "QL-800" +label_size = "62" # 62mm + +# 이미지를 Brother QL 포맷으로 변환 +qlr = BrotherQLRaster(printer_model) +instructions = convert( + qlr=qlr, + images=["sales_qr_label.png"], + label=label_size, + rotate='0', + threshold=70.0, + dither=False, + compress=False, + red=False, + dpi_600=False, + hq=True, + cut=True +) + +# USB로 프린터에 전송 +printer_identifier = "usb://0x04f9:0x209b" # Brother QL-800 USB ID +send(instructions=instructions, printer_identifier=printer_identifier) +``` + +### Phase 2-4: POS GUI 통합 + +**`pos_sales_gui.py` 수정 계획**: + +1. **QR 생성 버튼 활성화** (line 236): + ```python + self.qr_btn.setEnabled(True) + self.qr_btn.clicked.connect(self.generate_qr_for_selected) + ``` + +2. **QR 생성 함수 추가**: + ```python + def generate_qr_for_selected(self): + """선택된 판매 건의 QR 라벨 생성 및 출력""" + current_row = self.sales_table.currentRow() + if current_row < 0: + QMessageBox.warning(self, '경고', '판매 내역을 선택하세요.') + return + + order_no = self.sales_table.item(current_row, 0).text() + amount = self.sales_data[current_row]['amount'] + + # 1. Flask API 호출: QR 토큰 생성 + response = requests.post('http://localhost:5000/api/claim/token/generate', json={ + 'transaction_id': order_no, + 'total_amount': amount, + 'pharmacy_id': 'YANGGU001' + }) + + if response.status_code == 200: + result = response.json() + qr_url = result['qr_url'] + points = result['claimable_points'] + + # 2. QR 라벨 생성 + label_img = create_sales_qr_label(order_no, amount, points, qr_url) + + # 3. 프린터 출력 + print_sales_qr_label(label_img) + + QMessageBox.information(self, '성공', 'QR 라벨이 출력되었습니다.') + else: + QMessageBox.critical(self, '오류', 'QR 생성 실패') + ``` + +## 🔧 필요한 하드웨어 + +- **프린터**: Brother QL-800 또는 QL-820NWB +- **라벨**: 62mm x 100mm (또는 29mm x 90mm) +- **케이블**: USB Type-B + +## 📦 의존성 패키지 + +```txt +# backend/api/requirements.txt에 추가 +qrcode[pil]==7.4.2 +Pillow==10.1.0 +brother_ql==0.9.4 +python-barcode==0.15.1 +``` + +## 🔗 관련 문서 + +- [Brother QL 파이썬 라이브러리](https://github.com/pklaus/brother_ql) +- [QRCode 라이브러리](https://github.com/lincolnloop/python-qrcode) +- [Pillow 문서](https://pillow.readthedocs.io/) + +## 💡 개발 팁 + +1. **테스트 모드**: 실제 프린터 없이도 PNG 이미지로 저장하여 레이아웃 확인 가능 +2. **QR 크기**: 최소 150x150px 이상 권장 (스마트폰 스캔 용이) +3. **에러 복구 레벨**: `ERROR_CORRECT_M` (15%) 또는 `ERROR_CORRECT_H` (30%) 권장 +4. **라벨 여백**: 상하좌우 최소 5mm 여백 확보 +5. **폰트**: Windows 환경에서는 `malgun.ttf` (맑은 고딕) 사용 + +--- + +**작성일**: 2026-01-23 +**용도**: pharmacy-pos-qr-system Phase 2 개발 참고용