Files
jongryangje/doc/봉투-LOT-바코드-코드체계.md
taekyoungc 8763876f19 사용자 매뉴얼·번호알기·gov-portal 대시보드와 메뉴 동선·수불 리포트를 보강한다.
- 사용자 매뉴얼: league/commonmark 기반 bag/manual(로그인 전용),
  ManualRenderer + Config\Manual manifest, 콘텐츠 8종, E2E
- 번호알기(봉투번호확인): bag/number-lookup, BagNumberLookup, E2E
- gov-portal 대시보드 시안(기본/strip)·기본코드관리 화면
- 메뉴 관리: 등록·수정 후 메뉴 화면 유지, 수정 버튼 클릭 시 상단 스크롤
- 수불/분석 리포트(LOT 수불·반품/파기·수급계획·추이) 표시 보강
- .gitignore: docs/ → /docs/ 앵커링(최상위 개발문서만 제외, app/Docs는 추적)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 00:46:51 +09:00

12 KiB

봉투·LOT·바코드 코드 체계

종량제 물류 시스템에서 사용하는 봉투번호(바코드), LOT 번호, 품목코드 등이 어디서 만들어지고 무엇을 의미하는지 정리한 문서입니다.
구현 기준: app/Controllers/Bag.php, app/Controllers/Admin/BagOrder.php, app/Libraries/BagLotFlowBuilder.php, writable/database/*.sql.


1. 계층 구조 (한눈에 보기)

[지자체] lg_code (예: 110204 남구)
    └── [발주] bag_order
            ├── bo_lot_no      … LOT 번호 (제작·추적 단위)
            ├── bo_uuid        … 발주 식별자 (버전 이력)
            └── bo_hash        … 발주 내용 무결성 (SHA-256)
                    └── [입고] bag_receiving (br_idx)
                            └── bag_receiving_pack_code
                                    ├── brpc_box_code   … 박스 바코드
                                    ├── brpc_pack_code  … 팩 바코드
                                    ├── brpc_sheet_start_code ~ end … 낱장 구간
                                    └── brpc_lot_no       … 발주 LOT 복사
                                            └── [판매/반품 스캔]
                                                    ├── bag_sale_scan_code.bssc_code
                                                    └── bag_return_scan_code.brsc_code
단위 예시 조회·스캔 용도
LOT OQXCKH 발주 단위, LOT 수불·디스켓 시드
박스 OQXCKH-000008-B001 박스 단위 입출고·LOT 수불
OQXCKH-000008-P299 팩 단위 (스캔 가능)
낱장 OQXCKH-000008-P299-S00125 장(매) 단위 판매·반품·LOT 수불

참고: 000008은 “8번째 봉투”가 아니라 입고 건 PK(br_idx)를 6자리로 채운 값입니다.


2. 발주 LOT 번호 (bo_lot_no)

생성 시점·위치

  • 화면: 관리자 발주 등록·수정 (Admin\BagOrder::store)
  • 테이블: bag_order.bo_lot_no

생성 규칙

  1. 신규 발주: generateLotNo6() — 영문 대문자+숫자 6자리 난수 (0-9, A-Z), DB 중복 시 최대 20회 재시도.
  2. 실패 시: 타임스탬프 기반 6자리 fallback (base_convert(time, 10, 36)).
  3. 발주 수정(재발주): 기존 건의 bo_lot_no유지 (새 LOT를 붙이지 않음).
  4. 입고 시 LOT 미지정: 주문에 LOT가 없으면 bag_code(품목코드)를 LOT 자리에 대체 사용 (createReceivingPackCodes).

의미

  • 제작업체·지자체가 한 번의 발주 묶음을 식별하는 번호.
  • 입고 후 bag_receiving_pack_code.brpc_lot_no에 복사되어 박스/팩/낱장 코드의 접두어가 됩니다.
  • LOT-No 디스켓 불출 (/bag/order/lot-seed)·바코드 시드 파일명에 사용.

예시

설명
OQXCKH 발주 시 부여된 6자리 LOT (시드 예: writable/barcode-seeds/OQXCKH_v1.seed.json)
3K9F2A 다른 발주 건의 LOT

3. 발주 UUID·버전·해시

필드 형식 의미
bo_uuid UUID v4 (xxxxxxxx-xxxx-4xxx-...) 동일 발주의 버전 묶음 식별자
bo_version 정수 (1부터 증가) 발주 개정 이력 (복합 PK: uuid + version)
bo_hash SHA-256 64자 hex 발주 헤더+품목 JSON의 무결성 검증
  • 수정·재발주 시 새 bo_version 행이 생기고, bo_hash가 갱신됩니다.
  • 블록체인 연동 시 SqlLedgerORDER_CREATE / ORDER_UPDATE와 함께 기록됩니다.

4. 바코드 시드 파일 (제작업체 연동)

생성 시점

  • 발주 저장 시: Admin\BagOrder::generateBarcodeSeedFile()
  • LOT 디스켓 불출 시: Bag::orderLotSeedGenerate() (동일 포맷)

저장 위치·파일명

  • 디렉터리: writable/barcode-seeds/
  • 파일명: {bo_lot_no}_v{bo_version}.seed.json
    예: OQXCKH_v1.seed.json

내용

  • 발주·품목 메타를 JSON으로 묶고 AES-256-CBC로 암호화.
  • AES 키는 RSA-2048 공개키로 래핑 (writable/keys/barcode_seed_*.pem).
  • 평문에는 lot_no, uuid, version, order, items, order_hash 등이 포함됩니다.

의미 (운영)

  • 레거시/요구사항상 제작업체 인쇄용 바코드 원시데이터를 지자체가 발주와 함께 넘기는 용도.
  • 현재 웹 입고 바코드(bag_receiving_pack_code)는 아래 5절처럼 입고 처리 시 서버가 별도 생성합니다.
    (README 「바코드 생성/사용 시점」 참고 — 발주 시점 생성 vs 입고 시점 생성 정책 검토 중)

5. 입고 시 박스·팩·낱장 바코드 (bag_receiving_pack_code)

생성 시점·함수

  • 함수: Bag::createReceivingPackCodes()
  • 호출: 입고 스캐너·일괄 입고 저장 시 (receiving/scanner/store, receiving/batch/store 등)
  • 조건: 해당 br_idx에 팩 코드가 아직 없을 때만 1회 생성

입력·포장 단위

  • packaging_unit (pu_pack_per_sheet, pu_total_per_box): 팩당 낱장 수, 박스당 총 낱장 수.
  • 입고 낱장 수 qtySheet필요 팩 개수 = ceil(qtySheet / pack_per_sheet).
  • 박스당 팩 수 = total_per_box / pack_per_sheet.

코드 포맷 (구현)

$lotNo = 발주 bo_lot_no (없으면 품목코드), $brIdx = bag_receiving.br_idx.

구분 sprintf 패턴 예 (lot=OQXCKH, br_idx=8)
박스 {lotNo}-%06d-B%03d OQXCKH-000008-B001
{lotNo}-%06d-P%03d OQXCKH-000008-P001P299
낱장 시작 {packCode}-S%05d OQXCKH-000008-P299-S00001
낱장 끝 {packCode}-S%05d OQXCKH-000008-P299-S00300 (팩당 300장 예)
  • %06dbr_idx 6자리 (000008 = 8번 입고 건).
  • %03d → 박스·팩 순번 (001~999).
  • %05d → 팩 내부 낱장 순번 (00001~).

DB 컬럼 의미

컬럼 설명
brpc_lot_no 발주 LOT
brpc_box_code 박스 바코드
brpc_pack_code 팩 바코드 (UNIQUE)
brpc_sheet_start_code / brpc_sheet_end_code 해당 팩에 속한 낱장 코드 구간
brpc_sheet_qty 그 팩의 낱장 매수
brpc_state in_stock / sold 등 재고 상태

LOT 수불 조회에서의 해석

  • 낱장 번호 입력 → 해당 장의 판매·반품만 + 소속 팩 입고 1건.
  • 팩 번호 (…-P299) → 팩·박스 코드 기준 이력.
  • LOT만 (lot_no 파라미터) → 동일 LOT 전체 팩·입고·발주 요약.

6. 봉투 품목코드 (code_detail, 종류 O)

등록

  • 종류: code_kind.ck_code = 'O' (봉투명/품목)
  • 테이블: code_detail.cd_code, cd_name
  • 지자체별 확장: cd_lg_idx (0이면 공통)

코드 구성 (5자리 숫자 관례)

대구 시드(code_master_init_daegu.sql) 기준:

자리 연계 종류
앞 2자리 E 봉투구분 (10=일반, 20=공공, 30=무료, 60=음식물…) 10
다음 2자리 G 용량 (15=20L, 13=10L…) 15
마지막 1자리 F 재질 등 2

예: 10152 = 일반용(10) + 20L(15) + … → 일반용 20L

  • 발주·입고·재고·판매 집계는 이 코드(bs_bag_code, br_bag_code, bi_bag_code 등)로 묶입니다.
  • 바코드(LOT·팩·낱장)와는 별개 — 품목 종류 식별용 마스터 코드입니다.

7. 지자체·행정 코드

코드 필드 의미
지자체 local_government.lg_code 110204 대구 남구 (6자리 관례)
발주 구·군 bag_order.bo_gugun_code 110204 발주 시 지자체 lg_code 복사
발주 동 bag_order.bo_dong_code (동 코드) 세부 행정 단위

8. 지정판매소 번호 (ds_shop_no)

자동 부여 (주소 기반)

Admin\DesignatedShop::resolveDesignatedShopNumberFromAddress():

판매소번호 = B코드 + C코드 + D코드 + 3자리 일련번호
  • B: 시·도 (code_kind = B, 주소 매칭)
  • C: 구·군 (C, B 접두 포함)
  • D: 동 (D, C 접두 포함)
  • 일련: 동일 지자체 내 기존 번호 끝 3자리 숫자 최댓값 + 1

시드·레거시

  • 초기 데이터에 DS-2024-001 형태가 있을 수 있음 (수동/이관 데이터).
  • 가상계좌: ds_va_number / ds_va_bank + ds_va_account

판매 스캔과의 관계

  • 판매·반품 시 bssc_ds_idx / brsc_ds_idx로 판매소 연결.
  • LOT 수불·판매 대장의 입출고처ds_name 표시.

9. 판매·반품 스캔 코드

저장 테이블

테이블 코드 컬럼 생성 시점
bag_sale_scan_code bssc_code 지정판매소 판매 (/bag/sale/designated)
bag_return_scan_code brsc_code 지정판매소 반품 (/bag/sale/designated-return)

규칙

  • 스캔·입력 값 = 입고 시 생성된 바코드 (보통 낱장 또는 팩).
  • bssc_state: in_stock → 판매 시 sold, 반품 시 다시 in_stock.
  • 낱장 판매 시 동일 팩의 다른 낱장을 위해 bag_receiving_pack_code 팩 상태는 유지할 수 있음 (코드 주석 참고).

주문·판매 집계 코드

  • bag_sale.bs_type: sale / return / cancel
  • shop_order / shop_order_item: 주문 접수용 (전화·웹 등), 판매소·품목·수량 — LOT 바코드와 별도 흐름.

10. 기타 코드

구분 설명
회원 mb_id 로그인 ID (시스템 부여·가입)
제작업체 company.cp_* 발주 bo_company_idx
판매 대행소 sales_agency.sa_* 발주·입고 bo_agency_idx
무료 불출 bag_issue 불출처·수량 (바코드 LOT 체계와 별도)
반품/파기 시드 RET-20260508-DS1-001 테스트용 반품 스캔 코드 (bag_dispose_tables.sql)
파기 bag_dispose 입고분 파기 이력 (반품/파기 현황 입고 탭)

11. 화면별 “어떤 코드를 넣나”

화면 입력·표시 코드 데이터 소스
LOT 수불 조회 봉투번호(바코드)·lot_no BagLotFlowBuilder
지정판매소 판매/반품 스캔 바코드 bag_sale_scan_code / bag_return_scan_code
반품/파기 현황 출고 (조회만) bag_return_scan_code
반품/파기 현황 입고 (조회만) bag_dispose
기간별 봉투 수불 품목코드 O 집계 (BagFlowReportBuilder)
발주·입고 LOT, 품목코드 bag_order, bag_receiving

12. 구현·스키마 참고 파일

주제 파일
입고 바코드 생성 app/Controllers/Bag.phpcreateReceivingPackCodes()
LOT 6자리 생성 app/Controllers/Admin/BagOrder.phpgenerateLotNo6()
LOT 수불 조회 app/Libraries/BagLotFlowBuilder.php
팩 코드 테이블 writable/database/receiving_pack_code_tables.sql
발주 테이블 writable/database/order_tables.sql
품목 마스터 writable/database/code_master_init_daegu.sql (종류 O)
바코드 시드 샘플 writable/barcode-seeds/*.seed.json

13. 자주 묻는 혼동

  1. OQXCKH-000008-P299P300이 비슷해 보이는데 수불이 같다?

    • 이전에는 팩·LOT 전체 이력을 함께 가져왔습니다.
    • 수정 후 낱장 단위…-P299-Sxxxxx 형태로 조회하거나, 팩 단위는 P299/P300 각각 조회해야 판매 이력이 갈립니다.
  2. LOT 6자리와 접두 OQXCKH가 다른 길이?

    • 발주 LOT는 6자리 규칙이지만, 시드·테스트 데이터에 6자 영문(OQXCKH)을 쓴 경우가 있습니다. DB VARCHAR(50)에 저장되며, 입고 코드 접두로 그대로 사용됩니다.
  3. 품목코드 10152와 바코드 OQXCKH-…의 관계?

    • 10152종류·용량 마스터.
    • OQXCKH-…물리 단위(팩/장) 추적용 바코드입니다. 같은 품목이라도 LOT·입고 건마다 바코드 접두가 달라집니다.

문서 갱신: 코드 변경 시 createReceivingPackCodes, generateLotNo6, BagLotFlowBuilder를 우선 확인하세요.