Understand receipt printer feature#74
Conversation
Co-authored-by: wndtjr720 <wndtjr720@gmail.com>
|
Cursor Agent can help with this pull request. Just |
Co-authored-by: wndtjr720 <wndtjr720@gmail.com>
Co-authored-by: wndtjr720 <wndtjr720@gmail.com>
Co-authored-by: wndtjr720 <wndtjr720@gmail.com>
|
@codex 코드 리뷰해줘 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ccf29715b2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| <category android:name="android.intent.category.LAUNCHER"/> | ||
| </intent-filter> | ||
| <intent-filter data-generated="true"> | ||
| <action android:name="android.intent.action.android.hardware.usb.action.USB_DEVICE_ATTACHED"/> |
There was a problem hiding this comment.
Use the correct USB attach intent action
The USB attach intent action string is malformed here (android.intent.action.android.hardware.usb.action.USB_DEVICE_ATTACHED), so Android will not match real USB attach broadcasts. As a result, the app cannot be notified when the printer is plugged in, breaking the intended USB auto-detection flow on device.
Useful? React with 👍 / 👎.
| const granted = await PermissionsAndroid.request( | ||
| PermissionsAndroid.PERMISSIONS.USB_PERMISSION || 'android.permission.USB_PERMISSION', | ||
| { |
There was a problem hiding this comment.
Remove invalid runtime USB permission request
This requests USB_PERMISSION through PermissionsAndroid, but USB host access is not granted via Android runtime permissions, so this check can fail even when a USB printer is connected. Because connect() returns immediately on this false result, printer connection is blocked before device discovery and serial open are attempted.
Useful? React with 👍 / 👎.
| }); | ||
|
|
||
| // 프린터 서비스 인스턴스 (싱글톤 패턴) | ||
| const [printerService] = useState<PrinterService>(() => createPrinterService()); |
There was a problem hiding this comment.
Share printer connection state across screens
usePrinter() creates a new PrinterService instance per hook call, so connection state is isolated per screen. In practice, connecting from the printer test page does not carry over to History, and History's print actions are gated on isPrinterConnected, causing receipt printing to be rejected as disconnected in that screen.
Useful? React with 👍 / 👎.
| // 프린터가 특정되지 않으면 첫 번째 기기 사용 (테스트용) | ||
| if (deviceList.length > 0) { | ||
| console.log('Sewoo 프린터를 찾지 못했습니다. 첫 번째 기기를 사용합니다:', deviceList[0]); | ||
| return deviceList[0]; |
There was a problem hiding this comment.
Reject non-matching USB devices instead of defaulting to first
When no Sewoo match is found, this code falls back to deviceList[0], which can connect to an unrelated USB peripheral (for example, a scanner or another serial device) and then send ESC/POS bytes to it. That creates false-positive “connected” states and can break printing or interfere with other attached hardware whenever multiple USB devices are present.
Useful? React with 👍 / 👎.
| <intent-filter data-generated="true"> | ||
| <action android:name="android.intent.action.android.hardware.usb.action.USB_DEVICE_ATTACHED"/> | ||
| </intent-filter> |
There was a problem hiding this comment.
Add required USB device-filter metadata to activity
For USB_DEVICE_ATTACHED discovery, Android expects an <intent-filter> and matching <meta-data> pair that points to an XML device filter; declaring only the intent filter prevents the system from matching target devices and granting attach-time access flow. As written, USB attach auto-launch/auto-detect behavior will not work even after fixing the action string.
Useful? React with 👍 / 👎.
| name: item.menuItem.name, | ||
| quantity: item.quantity, | ||
| unitPrice: item.menuItem.price, | ||
| totalPrice: item.menuItem.price * item.quantity, |
There was a problem hiding this comment.
Compute receipt item totals from actual charged prices
The receipt conversion sets each item's totalPrice to menuItem.price * quantity, which ignores option surcharges, temperature surcharge logic, and discount rules used by the checkout calculator. For discounted/customized orders, printed line totals will not match what was actually charged, producing inaccurate receipts and inconsistent totals.
Useful? React with 👍 / 👎.
| <resources> | ||
| <!-- Sewoo SLK-TS100 프린터 디바이스 필터 --> | ||
| <usb-device | ||
| vendor-id="6656" | ||
| product-id="1" | ||
| class="7" | ||
| subclass="1" | ||
| protocol="2" /> |
There was a problem hiding this comment.
Package USB filter XML from Android resources
This device filter file is placed at repo root instead of android/app/src/main/res/xml, so it is not packaged as an Android XML resource and cannot be used by the manifest @xml/... USB attach flow. Even if intent metadata is added later, this file location prevents the filter from taking effect.
Useful? React with 👍 / 👎.
| discount: item.discount ? { | ||
| name: item.discount.name, | ||
| amount: item.discount.value, | ||
| } : undefined, |
There was a problem hiding this comment.
Preserve discount type when mapping receipt line discounts
Order discounts can be percentage-based or fixed-amount, but this mapping stores only value as a currency amount. Downstream receipt rendering formats that value as 원, so percentage discounts are printed as if they were fixed won discounts, yielding incorrect discount details on printed receipts.
Useful? React with 👍 / 👎.
| subtotal: transaction.totalAmount, | ||
| discountAmount: 0, // TODO: 할인 금액 계산 | ||
| finalAmount: transaction.totalAmount, |
There was a problem hiding this comment.
Calculate receipt summary discount instead of hardcoding zero
The receipt summary always sets discountAmount to 0 and subtotal equal to totalAmount, so any order with discounts will print a summary that claims no discount was applied. This creates accounting-visible mismatches between payment totals and printed receipt breakdowns.
Useful? React with 👍 / 👎.
작업내용
types/printer.ts: 프린터 관련 모든 타입(영수증 데이터, 설정, 상태 등)을 정의하여 타입 안전성을 확보했습니다.utils/SewooThermalPrinter.ts: Sewoo SLK-TS100 모델에 특화된 ESC/POS 기반 프린터 서비스 구현체를 작성했습니다.utils/printerService.ts: 프린터 서비스 팩토리 함수와 유틸리티를 제공하여 의존성 역전 원칙(DIP)을 따랐습니다.hooks/usePrinter.ts: 프린터 연결, 출력, 상태 관리 및 에러 처리를 담당하는 React 커스텀 훅을 구현했습니다.app/(tabs)/history.tsx:usePrinter훅을 연동하여 주문 영수증 및 현금 점검 영수증 출력 기능을 추가했습니다.app.json: Android USB OTG 연결을 위한 권한 및 인텐트 필터 설정을 추가했습니다.PRINTER_SETUP_GUIDE.md: Sewoo SLK-TS100 프린터 설정 및 사용에 대한 상세 가이드를 작성했습니다.고민하거나 궁금한 부분
SewooThermalPrinter.ts내requestUSBPermission(),findPrinterDevice(),sendRawData()메서드에 선택하신 USB 라이브러리(react-native-usb-serialport등)를 활용한 실제 통신 로직을 구현해야 합니다.utils/printerService.ts의DEFAULT_PRINTER_CONFIG및SewooThermalPrinter.ts생성자에 업데이트가 필요합니다.expo-dev-client를 통한 개발 빌드 또는 EAS Build 설정이 필요합니다.캡처 또는 영상 (optional)