> ## Documentation Index
> Fetch the complete documentation index at: https://docs.alforse.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 인쇄 및 라벨

> ZPL 및 PDF 라벨을 실제 프린터로 보냅니다. 프린터 라우트와 위치별 배정을 설정하고, 입고, 출하, 분할, 작업 시작 시 자동 인쇄를 제어하며, 모든 라벨을 인쇄 작업 대기열에서 추적합니다.

인쇄는 부품, 배치, 선반, 칸반 빈에 실제 라벨을 붙입니다. 관리자가 프린터를 연결하고 각 스테이션에 어떤 프린터를 사용할지 결정하며, 이후 창고 및 현장 직원은 입고를 전기하거나, 배치를 분할하거나, 작업의 첫 공정작업을 마칠 때 자동으로 라벨을 받습니다.

## 개요

인쇄 시스템은 세 부분으로 구성됩니다.

| 부분 | 역할 |
| - | - |
| **프린터 라우트** | 물리적 프린터마다 하나의 레코드로, 어디에 어떤 형식으로 전달할지를 나타냅니다. |
| **배정** | 각 위치와 컨텍스트에서 어떤 프린터를 사용하며 자동으로 인쇄할지 여부. |
| **인쇄 작업 대기열** | 자동이든 수동이든 모든 인쇄를 렌더링부터 전달까지 추적합니다. |

이는 송장, 발주서, 견적, 작업 트래블러 같이 파일로 전달되는 생성 문서와는 다릅니다. 인쇄는 출력을 **실제 프린터**로 보내며, 기본적으로 그 출력은 열전사 ZPL 라벨입니다.

### 형식

작업이 라우팅되는 프린터가 렌더링 방식을 결정합니다.

* **ZPL**은 열전사 라벨 프린터의 명령 언어이며 부품 및 보관 라벨의 기본값입니다. ZPL 라벨은 용지 크기에 ZPL 치수가 있는 경우에만 렌더링됩니다.
* **PDF**는 송장과 트래블러를 생성하는 것과 같은 React-PDF 엔진으로 그려지는 전체 문서입니다. 칸반 카드는 **PDF 전용**이므로 템플릿이 다루지 않는 한 ZPL 전용 프린터로 보내면 실패합니다.

### 문서 유형

세 가지 라벨 유형이 정의되어 있습니다(`packages/web/printing/src/registry.ts`의 `documentTypeRegistry`).

FieldType

<details>
  <summary>**productLabel**`zpl 기본값`</summary>

  추적 대상(일련번호 또는 배치 번호)의 라벨입니다. `Receipt`, `Shipment`, `Operation`, `Entity`, `Job`, `Split`, `StockTransfer`에서 인쇄됩니다.
</details>

<details>
  <summary>**storageUnitLabel**`zpl 기본값`</summary>

  선반, 빈 또는 기타 보관 위치의 라벨입니다. `StorageUnit`에서 인쇄됩니다.
</details>

<details>
  <summary>**kanbanCard**`pdf 전용`</summary>

  칸반 빈의 보충 카드입니다. `Kanban`에서 인쇄됩니다.
</details>

소스 문서가 인쇄할 수 있는 유형을 결정합니다. 출하를 전기하면 제품 라벨이 생성되고, 보관 단위를 스캔하면 보관 라벨이 생성됩니다. 조회는 `getDocumentTypesForSource`가 수행합니다.

## 인쇄 설정

### 1. 프린터 라우트 추가

**프린터 라우트**는 하나의 물리적 프린터를 나타냅니다. **설정 → 인쇄 → 프린터**로 이동하여 **프린터 추가**를 선택합니다.

FieldType

<details>
  <summary>**name**required`text`</summary>

  프린터의 이름입니다. 예: "Zebra 2x1". 위치 내에서 고유해야 합니다.
</details>

<details>
  <summary>**format**required`"zpl" | "pdf"`</summary>

  "ZPL (Thermal Label)" 또는 "PDF (Document)".
</details>

<details>
  <summary>**mediaSizeId**required`text`</summary>

  프린터에 장착된 라벨 크기입니다. ZPL 프린터는 열전사(ZPL 지원) 크기만 제공하며 PDF 프린터는 모든 크기를 제공합니다.
</details>

<details>
  <summary>**printerUrl**required`url`</summary>

  렌더링된 라벨을 POST로 받는 HTTP 엔드포인트입니다. 유효한 URL이어야 합니다.
</details>

<details>
  <summary>**apiKey**`text`</summary>

  선택 사항. 전송마다 `X-API-Key` 헤더로 전송되며 암호화되어 저장됩니다.
</details>

<details>
  <summary>**templateId**`text`</summary>

  선택 사항. "Leave blank for built-in"(기본 제공 항목을 사용하려면 비워 두십시오): 비어 있으면 Alforse의 기본 제공 렌더러를 사용합니다.
</details>

<details>
  <summary>**locationId**`text`</summary>

  선택 사항. 프린터의 위치이며, 없으면 라우트는 회사 전체에 적용됩니다.
</details>

NOTE

Alforse는 프린터의 raw 포트를 절대 열지 않습니다. 렌더링된 바이트를 `printerUrl`로 HTTP POST하여 전달합니다. 따라서 현장 프린터에는 Alforse가 접근할 수 있는 HTTP 엔드포인트가 필요합니다. 인쇄 게이트웨이나 프린터 자체의 HTTP 인터페이스가 그 예입니다. 대상은 회사에서 승인된 프린터 출처여야 하며 Alforse는 그 외의 곳으로는 전송을 거부합니다.

### 2. 프린터 테스트

모든 라우트에는 작은 ZPL 라벨을 `printerUrl`로 바로 보내는 **테스트** 작업이 있어, 프린터에 의존하기 전에 연결 가능한지 확인할 수 있습니다. 테스트는 용지 크기가 있는 ZPL 라우트에서만 작동하며 성공하면 `"Test label sent to printer"`(테스트 라벨이 프린터로 전송되었습니다)가 표시됩니다.

### 3. 컨텍스트에 프린터 배정

라우트는 프린터이고 **배정**은 언제 사용할지를 결정합니다. **설정 → 인쇄 → 배정**을 열면 각 위치에 자체 블록이 있습니다. 그 안에서 각 **컨텍스트**에 프린터를 지정합니다(`packages/web/printing/src/assignments.ts`의 `printerContexts`).

FieldType

<details>
  <summary>**default**</summary>

  위치의 대체값입니다. 자체 프린터가 없는 모든 컨텍스트가 이것을 사용합니다.
</details>

<details>
  <summary>**shipping**</summary>

  유형이 `Shipment`인 소스 문서용.
</details>

<details>
  <summary>**receiving**</summary>

  유형이 `Receipt`인 소스 문서용.
</details>

<details>
  <summary>**inventory**</summary>

  `StockTransfer` 또는 `StorageUnit`용.
</details>

<details>
  <summary>**workCenter**</summary>

  작업장별로 설정되며 작업 공정작업에서 인쇄하는 라벨용입니다. 배정이 없는 작업장은 위치 기본값을 직접 사용합니다.
</details>

각 컨텍스트 행에는 **자동 인쇄** 스위치도 있습니다. 켜져 있으면 해당 비즈니스 이벤트가 누군가 클릭하지 않아도 인쇄됩니다. `getPrinterContextForSource`가 소스 문서의 컨텍스트를 찾고 `resolveContextAssignment`가 대체값을 적용하므로, 배정되지 않은 컨텍스트는 위치의 기본 프린터를 사용합니다.

HEADS UP

명시적인 행이 없는 컨텍스트는 위치의 기본 행에서 꺼져 있더라도 자동 인쇄가 **켜져** 있습니다. 예를 들어 출하처럼 스테이션을 조용하게 유지하려면 기본 행에 의존하지 말고 자동 인쇄가 꺼진 자체 행을 지정하십시오.

## 자동 인쇄

지원되는 비즈니스 이벤트가 끝나면 Alforse는 위치와 컨텍스트의 프린터를 찾고, `autoPrint`를 확인하여(설정되지 않으면 **켜짐**으로 취급) 작업을 대기열에 넣습니다. 인쇄 실패가 이를 유발한 입고, 출하, 작업을 막는 일은 없습니다.

| 이벤트 | 컨텍스트 | 인쇄되는 내용 |
| - | - | - |
| 입고가 전기됨 | receiving | 입고된 추적 대상의 제품 라벨. |
| 출하가 전기됨 | shipping | 제품 라벨과 배치 분할의 `Split` 라벨. |
| 재고 이동 라인이 분할됨 | inventory | `Split` 라벨과 원래 배치의 `Entity` 재출력. |
| MES에서 작업의 첫 번째 공정작업이 완료됨 | 작업장 | 작업의 제품 라벨. |

스테이션을 조용하게 하려면 해당 위치의 컨텍스트 행에서 **자동 인쇄**를 끄십시오.

HEADS UP

같은 소스 문서에 대한 자동 인쇄는 **30초 이내에 중복 제거**됩니다. 두 번째 이벤트는 재시도할 수 없는 오류로 폐기됩니다. 수동 인쇄와 재출력은 중복 제거되지 않습니다.

## 수동 인쇄

관련 화면에서 **인쇄**를 선택하거나 소스 문서를 수동 인쇄 라우트(`/x/print`)로 보내면 요청을 검증하고 같은 종류의 작업을 대기열에 넣습니다.

**인쇄**의 동작은 위치에 따라 다릅니다.

| 위치에 프린터 라우트가 있음 | 동작 |
| - | - |
| 예 | 확정된 기본값이 선택된 프린터 선택기가 열립니다. 확인하면 작업이 대기열에 들어갑니다. |
| 아니요 | **다운로드** 모달이 열려 라벨을 ZPL 또는 PDF로 저장할 수 있습니다. |

## 인쇄 작업 대기열

### 작업 상태

<details>
  <summary>**generating**</summary>

  작업이 존재하며 ZPL 텍스트 또는 base64 PDF로 내용이 렌더링되고 있습니다.
</details>

<details>
  <summary>**queued**</summary>

  렌더링되었습니다. 프린터로의 전달이 대기열에 있습니다.
</details>

<details>
  <summary>**printing**</summary>

  프린터 엔드포인트로 전송되었으며 전달이 진행 중입니다.
</details>

<details open>
  <summary>**completed**</summary>

  전달되었거나 보낼 프린터 없이 렌더링되었습니다(다운로드 전용 작업).
</details>

<details>
  <summary>**failed**</summary>

  렌더링 또는 전달이 실패했거나 전달을 확인할 수 없었습니다. `error`가 사유를 알려 주고 `attempts`는 시도 횟수를 집계합니다.
</details>

각 작업은 `origin`을 기록합니다.

| 출처 | 의미 |
| - | - |
| **auto** | 비즈니스 이벤트 후 자동으로 인쇄되었습니다. |
| **manual** | 누군가 인쇄를 선택했습니다. |
| **reprint** | 작업 목록에서 다시 실행되었습니다. |

작업은 `sourceDocument`, `sourceDocumentId`, 읽기 쉬운 id, `contentType`, 전송된 `printerUrl`도 저장합니다.

### 모니터링과 재출력

**설정 → 인쇄 → 인쇄 작업 지시**를 엽니다. 테이블은 상태, 설명, 소스, 유형, 출처, 시각과 함께 실시간으로 업데이트됩니다. 행을 펼치면 프린터 URL, 시도 횟수, 타임스탬프, 오류를 볼 수 있습니다. 행에서 다음을 할 수 있습니다.

* 내용을 **보기**: ZPL은 Labelary로 미리보고, PDF는 인라인 프레임으로 봅니다.
* **재출력**: `origin: "reprint"`인 새 작업을 만듭니다.
* **삭제**.

NOTE

시간 초과나 결과를 기록할 수 없었다는 이유로 전달 결과를 확인할 수 없으면 작업은 실패로 표시되며 **자동으로 다시 전송되지 않습니다**. 라벨이 이미 인쇄되었을 수 있기 때문입니다. 프린터를 확인한 다음 필요하면 **재출력**하십시오.

## 라벨 크기

용지 크기는 고정된 카탈로그(`packages/web/utils/src/labels.ts`)에서 가져옵니다. `label2x1`, `label4x2`, 미터법 `label100x50mm`과 `label50x25mm`, PDF 전용 `avery5163`입니다. ZPL 치수가 있는 크기만 열전사 프린터에서 인쇄할 수 있으므로 Avery 같은 PDF 전용 크기는 인쇄할 수 없습니다.

크기는 두 곳에서 설정됩니다.

* 각 프린터 라우트는 해당 프린터에 장착된 라벨과 일치하는 자체 `mediaSizeId`를 고정합니다.
* 문서 템플릿 화면에서 설정하는 회사의 **기본 제품 라벨 크기**(`companySettings.productLabelSize`)는 라우트가 크기를 설정하지 않을 때 대화형 라벨 다운로드 라우트가 사용합니다.

해당 기본값이 있는 위치는 [회사 설정](https://docs.alforse.com/ko/docs/reference/company-settings.md)을, 기본 제공 라벨 템플릿의 스타일을 지정하는 커스터마이저는 [문서](https://docs.alforse.com/ko/docs/reference/documents.md)를 참조하십시오.

## 문제 해결

### 라벨이 인쇄되지 않았습니다

다음 점검을 순서대로 진행하십시오.

1. 위치와 컨텍스트에 프린터 라우트가 배정되어 있고 **자동 인쇄** 스위치가 켜져 있습니다.
2. 라우트에 연결 가능한 `printerUrl`이 있습니다. 없으면 작업은 렌더링되지만 전달할 수 없습니다.
3. **설정 → 인쇄 → 인쇄 작업 지시**에서 작업이 **failed**가 아닙니다. 행을 펼쳐 `error`를 확인하십시오.

자동 인쇄를 대기열에 넣는 중의 실패는 "Auto-print failed"로 기록되며 입고나 출하 화면에는 표시되지 않으므로 인쇄 작업 목록에서 확인해야 합니다. 작업이 전혀 없다면 프린터가 확정되지 않았고 자동 인쇄가 꺼져 있었거나, 해당 이벤트가 자동 인쇄 대상이 아닌 것입니다. [자동 인쇄](#automatic-printing)의 네 가지 이벤트만 해당하며, 그 외에는 **인쇄**나 수동 라우트를 사용하십시오.

### 오류 메시지

| 메시지 | 원인 | 해결 방법 |
| - | - | - |
| "Print jobs already exist for … …"(… …에 대한 인쇄 작업이 이미 있습니다) | 같은 소스 문서에 대한 자동 작업이 30초 이내에 생성되어 이 중복이 폐기되었습니다. | 다른 사본이 필요하면 **재출력**을 사용하십시오. 재출력은 중복 제거되지 않습니다. |
| "Rendering failed: …"(렌더링 실패: …) | 내용을 생성할 수 없었습니다. ZPL 치수가 없는 용지 크기로 ZPL 라벨이 라우팅되었거나 PDF 전용 칸반 카드가 ZPL 전용 프린터로 보내진 경우가 많습니다. | 라우트의 용지 크기와 형식을 확인하십시오. |
| "Printer delivery could not be confirmed. This job will not be sent again automatically."(프린터 전달을 확인할 수 없습니다. 이 작업은 자동으로 다시 전송되지 않습니다.) | 엔드포인트가 시간 내에 응답하지 않았거나 결과를 기록할 수 없었습니다. | 프린터를 확인하고 인쇄된 것이 없으면 작업 목록에서 재출력하십시오. |
| "Print job not found: …"(인쇄 작업을 찾을 수 없습니다: …) / "The print job has no valid stored content."(인쇄 작업에 유효하게 저장된 내용이 없습니다.) | 전달이 작업이나 내용을 불러올 수 없었습니다. 후자는 렌더링이 완료되지 않았다는 뜻입니다. | 작업 목록에서 작업의 상태와 오류를 확인하십시오. |
| "No printer is assigned to this print job; nothing was sent."(이 인쇄 작업에 배정된 프린터가 없습니다. 아무것도 전송되지 않았습니다.) | 프린터가 없는 작업에 대해 재출력이 요청되었습니다. | 위치와 컨텍스트에 프린터를 배정한 다음 다시 인쇄하십시오. |
| "Print failed (…)"(인쇄 실패 (…)) | 엔드포인트가 HTTP 오류를 반환했으며 코드가 메시지에 있습니다. 대개 프린터가 오프라인이거나, `printerUrl`이 잘못되었거나, `apiKey`가 없거나 유효하지 않습니다. | 라우트의 **테스트** 작업으로 연결 가능 여부를 확인하십시오. |
| "Test print is only supported for ZPL label printers with a media size configured."(테스트 인쇄는 용지 크기가 구성된 ZPL 라벨 프린터에서만 지원됩니다.) | PDF 라우트 또는 용지 크기가 없는 ZPL 라우트에서 **테스트**를 사용했습니다. | 용지 크기가 있는 ZPL 라우트만 테스트하십시오. |
| "Cannot reprint a job with no content"(내용이 없는 작업은 재출력할 수 없습니다) / "Cannot reprint a job that is still generating"(아직 생성 중인 작업은 재출력할 수 없습니다) | 재출력은 원본의 렌더링된 내용을 복사하는데 이 작업은 렌더링된 적이 없습니다. | 원본 작업을 해결하거나 소스 문서에서 다시 인쇄하십시오. |

## 관련 문서

**회사 설정**

기본 제품 라벨 크기와 기타 회사 전체의 인쇄 기본값입니다.

[Open](https://docs.alforse.com/ko/docs/reference/company-settings.md)

**재고 및 위치**

보관 단위 라벨과 대부분의 인쇄 작업이 설명하는 추적 대상입니다.

[Open](https://docs.alforse.com/ko/docs/reference/inventory.md)

**추적성**

제품 라벨에 담기는 일련번호와 배치 번호입니다.

[Open](https://docs.alforse.com/ko/docs/reference/traceability.md)

**칸반**

보충 빈과 이를 위해 인쇄되는 PDF 카드입니다.

[Open](https://docs.alforse.com/ko/docs/reference/kanban.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.