SOFTMOA TECHNOLOGY

제품 포장 라벨 재출력 승인 시스템 구축 방법

소프트모아가 정리한 기술 기록입니다.

Contents
작성일 2026. 10. 26.

포장 라벨이 찢어져 두 장을 다시 뽑아야 할 때, 원래 출력 파일을 열어 재인쇄하면 승인 수량과 실제 나온 수량을 대조하기 어렵습니다. 라벨 재출력 시스템은 원출력 이력에 교체 사유와 승인 수량을 연결하고, 출력 요청과 실물 확인을 나눠 관리하도록 구축합니다. 같은 승인 건을 두 번 누르는 경우와 프린터 응답이 끊긴 경우도 서로 다르게 처리해야 합니다.

손상된 두 장을 어떤 라벨로 바꿀지 먼저 정합니다

다음은 구축 범위를 설명하는 가상 포장 업무입니다. 최초 출력 작업 J100에서 나온 라벨 20장 중 두 장이 손상됐다고 가정합니다. 작업자는 재출력 신청 화면에서 J100, 대상 포장 ID 두 개, 손상 사유, 회수한 원라벨 사진을 입력합니다. 수량 단위는 제품 개수가 아니라 라벨 장수입니다. 품목 코드나 문구를 임의로 다시 입력하는 대신 원출력 당시의 데이터와 서식 버전을 불러옵니다.

승인 화면에는 원본 미리보기, 대상 포장 ID, 신청 장수, 원라벨 회수 여부를 나란히 표시합니다. 승인자는 두 장이 정말 교체 대상인지 확인합니다. 원라벨을 찾지 못했다면 별도 확인 대상으로 보류하고, 서식이 이후 개정됐다면 옛 서식을 그대로 쓸지 새 서식으로 전환할지 책임자가 결정하도록 합니다. 일련번호를 유지할지 새로 발급할지도 업무 규칙으로 정해야 하며 재출력 횟수만큼 새 번호를 자동 생성하지 않습니다.

  • 작업자는 신청과 실물 확인을 담당하고 자기 신청을 승인하지 못하게 설계합니다.
  • 승인자는 대상과 장수를 확정합니다. 승인 후 대상·수량·서식을 바꾸면 기존 승인을 무효화하고 재승인을 받습니다.
  • 출력 연동 계정만 승인 건의 처리 상태를 변경합니다. 화면 버튼을 숨기는 것과 별도로 서버에서 권한을 검사해야 합니다.

승인된 수량으로 한 번만 처리권을 잡는 예제

아래 Python 코드를 reprint_demo.py로 저장해 python3 reprint_demo.py로 실행할 수 있습니다. Python 3.14.8과 SQLite 3.53.4에서 메모리 DB로 확인했으며 프린터와 운영 자료는 사용하지 않았습니다. RETURNING에는 SQLite 3.35.0 이상이 필요합니다.[2] REQUESTED는 신청, APPROVED는 승인, CLAIMED는 연동 처리를 맡은 상태로 정한 예시 값입니다.

import sqlite3

con = sqlite3.connect(":memory:")
con.executescript("""
CREATE TABLE requests(
  id TEXT PRIMARY KEY,
  state TEXT NOT NULL,
  qty_ea INTEGER NOT NULL CHECK(qty_ea > 0)
);
INSERT INTO requests VALUES
  ('R1','APPROVED',2), ('R2','REQUESTED',1);
""")
claim = """
UPDATE requests SET state='CLAIMED'
WHERE id=? AND state='APPROVED' AND qty_ea=?
RETURNING id, qty_ea;
"""
for request_id, qty in [('R1',3), ('R1',2), ('R1',2), ('R2',1)]:
    rows = con.execute(claim, (request_id, qty)).fetchall()
    con.commit()
    print(request_id, qty, rows)
print(con.execute("SELECT * FROM requests ORDER BY id").fetchall())

실행 결과는 다음과 같습니다.

R1 3 []
R1 2 [('R1', 2)]
R1 2 []
R2 1 []
[('R1', 'CLAIMED', 2), ('R2', 'REQUESTED', 1)]

첫 R1 요청은 승인된 두 장 대신 세 장을 요구해 결과가 비어 있습니다. 이 거절은 승인을 소모하지 않으므로 두 장으로 고친 다음 요청은 한 행을 반환합니다. 이후 같은 R1을 다시 요청하면 이미 CLAIMED여서 거절되며, 아직 신청 상태인 R2도 처리권을 얻지 못합니다. UPDATE는 WHERE 조건에 맞는 행만 바꾸고, 맞는 행이 없어도 SQL 오류로 끝나지는 않습니다.[1] 따라서 예외 발생 여부만 보지 말고 반환 행도 확인해야 합니다.

입력 시도는 네 번이지만 변경된 요청은 한 건입니다. 반환값의 2는 그 요청에 묶인 라벨 장수이며 출력 성공 두 건을 뜻하지 않습니다. RETURNING 결과 자체도 커밋을 뜻하지 않으므로 코드에서는 결과를 읽은 뒤 commit을 호출합니다.[2] 이 시험이 만든 출력 대기열 작업은 0건이고 실물 라벨도 0장입니다. 인증, 입력 형식과 서식 검증, 동시 연결과 장비 연동까지 구현한 코드는 아닙니다.

응답이 없다고 같은 라벨을 곧바로 다시 보내면 안 됩니다

실제 구축에서는 처리권 확보와 출력 대기열 기록을 같은 DB 트랜잭션에 넣고, 신청 ID에 고유 제약을 둬 같은 신청이 여러 대기 작업을 만들지 않도록 설계합니다. 앞의 예제는 대기열 기록이 없으므로 CLAIMED 변경 직후 프로그램이 멈추면 후속 처리가 빠질 수 있습니다. 작업 ID, 전송 시각, 프린터, 응답 내용을 남기고 중단 지점을 찾을 수 있어야 합니다.

장비로 전송한 뒤 응답이 끊기면 실제로 두 장이 나왔을 수도 있습니다. 이때 자동으로 APPROVED로 돌려 다시 보내지 않고 '결과 확인 필요'로 보류합니다. 담당자가 장비 이력과 실물을 확인한 후 재시도 여부를 결정하게 합니다. 대기열 중복 방지가 물리적으로 정확히 한 번만 인쇄되는 것까지 보장하지는 않습니다. 프린터 자체의 재인쇄 기능을 허용할지도 운영 권한과 함께 정해야 합니다.

작업자는 인쇄된 두 장의 내용과 바코드를 확인하고 교체 대상 포장에 붙인 결과를 기록합니다. 한 장만 정상이라면 승인 두 장·정상 한 장·불량 한 장을 구분하고, 불량분 추가 출력은 새 신청으로 연결합니다. 원라벨 회수·폐기 기록도 남깁니다. 관리자 조회에서는 신청 장수, 승인 장수, 전송 상태, 정상·불량 장수, 교체 확인자를 따로 보여줘 '전송 완료'가 '교체 완료'로 읽히지 않게 합니다.

구축 상담 전에는 손상 한 건을 골라 원출력 데이터 보관 위치, 프린터의 작업 식별 방식, 원라벨 처리 책임자를 확인해 보세요. 기존 프로그램이 재출력 이력과 연동 기능을 제공한다면 그 범위를 먼저 확인하고, 별도 승인 화면과 미확인 결과 조회가 필요한 부분만 연결할 수 있습니다.

공식 확인 자료

소프트모아의 서비스는 softmoa.com에서 확인할 수 있습니다.

소프트모아는 해당 시스템을 구축합니다. 문의하기

Share this

Information

Have a questions?

견적 및 기술문의

mobile : 010-7931-4813

Contact Form