diff --git a/.vs/marking_gui.slnx/v18/.suo b/.vs/marking_gui.slnx/v18/.suo
index fb1a699..ca1727a 100644
Binary files a/.vs/marking_gui.slnx/v18/.suo and b/.vs/marking_gui.slnx/v18/.suo differ
diff --git a/.vs/marking_gui.slnx/v18/DocumentLayout.backup.json b/.vs/marking_gui.slnx/v18/DocumentLayout.backup.json
index 22dca5d..4c1d162 100644
--- a/.vs/marking_gui.slnx/v18/DocumentLayout.backup.json
+++ b/.vs/marking_gui.slnx/v18/DocumentLayout.backup.json
@@ -22,16 +22,12 @@
"DocumentGroups": [
{
"DockedWidth": 200,
- "SelectedChildIndex": 4,
+ "SelectedChildIndex": 3,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
},
- {
- "$type": "Bookmark",
- "Name": "ST:0:0:{cce594b6-0c39-4442-ba28-10c64ac7e89f}"
- },
{
"$type": "Document",
"DocumentIndex": 1,
diff --git a/.vs/marking_gui.slnx/v18/DocumentLayout.json b/.vs/marking_gui.slnx/v18/DocumentLayout.json
index 22dca5d..4c1d162 100644
--- a/.vs/marking_gui.slnx/v18/DocumentLayout.json
+++ b/.vs/marking_gui.slnx/v18/DocumentLayout.json
@@ -22,16 +22,12 @@
"DocumentGroups": [
{
"DockedWidth": 200,
- "SelectedChildIndex": 4,
+ "SelectedChildIndex": 3,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{aa2115a1-9712-457b-9047-dbb71ca2cdd2}"
},
- {
- "$type": "Bookmark",
- "Name": "ST:0:0:{cce594b6-0c39-4442-ba28-10c64ac7e89f}"
- },
{
"$type": "Document",
"DocumentIndex": 1,
diff --git a/docs/knowledge_base.md b/docs/knowledge_base.md
index e27b41a..92e1e5f 100644
--- a/docs/knowledge_base.md
+++ b/docs/knowledge_base.md
@@ -110,7 +110,7 @@
- 고유 QR 코드 문자열 `Marking_QR` (NVARCHAR(60)): `IC_SN;도면품번;HKMC품번;각인번호;` 포맷으로 구성되며, 60자 초과 시 절삭합니다.
- 공정 정보(`Maker`, `Model`, `Variant_1`, `Variant_2`, `Operator`, `Production_Date`, `Line`, `Lot_No`, `Jig_No`) 및 최종 판정(`Result`)이 통합 적재됩니다. 각 문자열 컬럼은 최대 10자로 초과 시 절삭 처리됩니다.
- 3단계에 걸친 전압/전류/저항 컬럼(`PT_Vol_1~3`, `PT_Current_1~3`, `PT_Resistance_1~3`)이 존재하며, 현재는 1번 컬럼들에 최종 계측 수치(소수점 2~3자리 반올림)를 저장하고 2, 3번 컬럼은 `0.00`으로 기본값을 보정하여 저장합니다.
- - `Result` 컬럼에는 **`OK`** (QR 검증 통과 시) 또는 **`NG`** (불합격 또는 QR 검증 실패 시) 두 가지 값만 저장됩니다.
+ - `Result` 컬럼에는 최종 합격된 **`OK`** 레코드만 저장됩니다. (계측 불합격 또는 QR 검증 실패 등의 **`NG`**인 경우, 각인 순번이 불필요하게 카운트되는 것을 방지하기 위해 DB에 적재하지 않고 저장을 건너뜁니다.)
- `Lot_No` 컬럼은 `YYMMDDLL` 형식(예: `26080401`)으로 입력되며 최대 **10자**까지 허용됩니다.
### 4.2. 로그인 검증 저장 프로시저 ([CheckOperator])
diff --git a/marking_gui/MainWindow.xaml.cs b/marking_gui/MainWindow.xaml.cs
index eb9bd08..a445d3a 100644
--- a/marking_gui/MainWindow.xaml.cs
+++ b/marking_gui/MainWindow.xaml.cs
@@ -1454,9 +1454,9 @@ namespace marking_gui
{
if (txtMarkingStatus != null) txtMarkingStatus.Text = "마킹 성공 / QR 검증 NG";
if (borderMarkingStatus != null) borderMarkingStatus.Background = new SolidColorBrush(Color.FromRgb(239, 68, 68)); // Red
- LoggerService.Warn($"[QR 검증 실패] S/N: {serial}, 각인번호: {markedSerial} -> DB NG 저장 진행");
+ LoggerService.Warn($"[QR 검증 실패] S/N: {serial}, 각인번호: {markedSerial} -> DB 미저장");
- // 마킹 성공 후 QR 검증 불일치/취소 시 NG로 DB 저장 (EZD 추출 실시간 품번 포함)
+ // 마킹 성공 후 QR 검증 불일치/취소 시 NG 처리 (DB 저장 생략하여 순번 카운트 제외)
await SaveAndFinalizeAsync(serial, finalVoltage, finalCurrent, finalResistance, false, "NG", markedSerial, ezdDrawingNo, ezdHkmcNo, bypassPrevSteps);
}
}
@@ -1466,7 +1466,7 @@ namespace marking_gui
if (borderMarkingStatus != null) borderMarkingStatus.Background = new SolidColorBrush(Color.FromRgb(239, 68, 68)); // Red
LoggerService.Error($"[마킹 실패] S/N: {serial}, 각인번호: {markedSerial}, Code: {markingRes.ErrorCode}, Message: {markingRes.ErrorMessage} -> DB 저장 생략");
- txtFinalResult.Text = "FAIL";
+ txtFinalResult.Text = "NG";
txtFinalResult.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68));
txtSystemStatus.Text = string.Format("마킹 실패 [{0}]: {1} (DB 미저장)", markingRes.ErrorCode, markingRes.ErrorMessage);
txtSystemStatus.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68));
@@ -1513,7 +1513,7 @@ namespace marking_gui
if (borderMarkingStatus != null) borderMarkingStatus.Background = new SolidColorBrush(Color.FromRgb(239, 68, 68)); // Red
LoggerService.Error($"[마킹 스레드 오류] S/N: {serial}", threadEx);
- txtFinalResult.Text = "FAIL";
+ txtFinalResult.Text = "NG";
txtFinalResult.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68));
txtSystemStatus.Text = "마킹 예외 (DB 미저장): " + threadEx.Message;
txtSystemStatus.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68));
@@ -1534,7 +1534,7 @@ namespace marking_gui
}
else
{
- // 불합격인 경우에도 Lot No 및 예정 각인번호/품번 정보를 포함하여 DB 저장 및 복구
+ // 불합격인 경우 각인 및 DB 저장 생략 (순번 카운트 제외)
string markedSerial = GetCurrentMarkedSerial();
string drawingNo = _markingConfig.GetDrawingNoForEzd(_currentEzdFile);
string hkmcNo = _markingConfig.GetHkmcNoForEzd(_currentEzdFile);
@@ -1629,12 +1629,55 @@ namespace marking_gui
return string.Format("{0}{1:D4}", lotNo, seq);
}
- private async Task SaveAndFinalizeAsync(string serial, double voltage, double current, double resistance, bool isFinalPass, string result, string markedSerial, string drawingNo = "", string hkmcNo = "", bool bypassPrevSteps = false)
+ private async Task SaveAndFinalizeAsync(string serial, double voltage, double current, double resistance, bool isFinalPass, string result, string markedSerial, string drawingNo = "", string hkmcNo = "", bool bypassPrevSteps = false)
{
// 종료 시간 기록 및 UI 갱신
_testEndTime = DateTime.Now;
txtTestEndTime.Text = "종료 시간: " + _testEndTime.ToString("yyyy-MM-dd HH:mm:ss");
+ bool isOk = isFinalPass && (result == "PASS" || result == "OK");
+
+ if (!isOk)
+ {
+ // === [NG 결과 처리 - DB 미저장 (순번 카운트 제외)] ===
+ LoggerService.Warn($"[검사 NG] S/N: {serial}, 결과: NG (isFinalPass: {isFinalPass}, result: {result}) -> DB 저장 생략 (순번 카운트 제외)");
+
+ txtFinalResult.Text = "NG";
+ txtFinalResult.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68)); // Red text
+ if (borderVerdictCard != null)
+ {
+ borderVerdictCard.Background = new SolidColorBrush(Color.FromRgb(254, 242, 242)); // Light Red
+ borderVerdictCard.BorderBrush = new SolidColorBrush(Color.FromRgb(239, 68, 68)); // Red border
+ borderVerdictCard.BorderThickness = new Thickness(3);
+ }
+
+ if (result == "NG" && isFinalPass)
+ {
+ txtSystemStatus.Text = "상태: 각인 QR 검증 불합격 (NG, DB 미저장)";
+ if (txtProgressStatus != null)
+ {
+ txtProgressStatus.Text = "각인 QR 검증 실패 (DB 미저장, 순번 유지)";
+ txtProgressStatus.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68));
+ }
+ }
+ else
+ {
+ txtSystemStatus.Text = "상태: 성능 검사 불합격 (NG, DB 미저장)";
+ if (txtProgressStatus != null)
+ {
+ txtProgressStatus.Text = "검사 불합격 (각인 및 DB 저장 생략)";
+ txtProgressStatus.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68));
+ }
+ }
+ txtSystemStatus.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68));
+
+ // 컨트롤 원상 복구 (재검사를 위해)
+ txtSerial.IsEnabled = true;
+ SetStartButtonReady();
+ return;
+ }
+
+ // === [OK 결과 처리 - DB 저장 (순번 카운트)] ===
if (txtProgressStatus != null)
{
txtProgressStatus.Text = "결과 데이터베이스 저장 중...";
@@ -1672,7 +1715,7 @@ namespace marking_gui
voltage,
current,
resistance,
- result,
+ "OK",
_testStartTime,
_testEndTime,
markedSerial,
@@ -1683,59 +1726,26 @@ namespace marking_gui
if (dbResult)
{
- LoggerService.Info($"[DB 저장 완료] S/N: {serial}, 결과: {result}, V: {voltage:F2}, I: {current:F2}, R: {resistance:F2}");
+ LoggerService.Info($"[DB 저장 완료] S/N: {serial}, 결과: OK, V: {voltage:F2}, I: {current:F2}, R: {resistance:F2}");
- // 스캔 검증까지 포함한 최종 판정 결과 카드 갱신
- if (isFinalPass && (result == "PASS" || result == "OK"))
- {
- txtFinalResult.Text = "OK";
- txtFinalResult.Foreground = new SolidColorBrush(Color.FromRgb(16, 185, 129)); // Green text
- if (borderVerdictCard != null)
- {
- borderVerdictCard.Background = new SolidColorBrush(Color.FromRgb(240, 253, 250)); // Light Green
- borderVerdictCard.BorderBrush = new SolidColorBrush(Color.FromRgb(16, 185, 129)); // Green border
- borderVerdictCard.BorderThickness = new Thickness(3);
- }
- txtSystemStatus.Text = "상태: 모든 공정 검사 및 QR 스캔 합격";
- txtSystemStatus.Foreground = new SolidColorBrush(Color.FromRgb(16, 185, 129));
- }
- else
+ txtFinalResult.Text = "OK";
+ txtFinalResult.Foreground = new SolidColorBrush(Color.FromRgb(16, 185, 129)); // Green text
+ if (borderVerdictCard != null)
{
- txtFinalResult.Text = "NG";
- txtFinalResult.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68)); // Red text
- if (borderVerdictCard != null)
- {
- borderVerdictCard.Background = new SolidColorBrush(Color.FromRgb(254, 242, 242)); // Light Red
- borderVerdictCard.BorderBrush = new SolidColorBrush(Color.FromRgb(239, 68, 68)); // Red border
- borderVerdictCard.BorderThickness = new Thickness(3);
- }
- txtSystemStatus.Text = (result == "NG") ? "상태: 각인 QR 검증 불합격 (NG)" : "상태: 검사 불합격";
- txtSystemStatus.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68));
+ borderVerdictCard.Background = new SolidColorBrush(Color.FromRgb(240, 253, 250)); // Light Green
+ borderVerdictCard.BorderBrush = new SolidColorBrush(Color.FromRgb(16, 185, 129)); // Green border
+ borderVerdictCard.BorderThickness = new Thickness(3);
}
+ txtSystemStatus.Text = "상태: 모든 공정 검사 및 QR 스캔 합격";
+ txtSystemStatus.Foreground = new SolidColorBrush(Color.FromRgb(16, 185, 129));
if (txtProgressStatus != null)
{
- if (isFinalPass && (result == "PASS" || result == "OK"))
- {
- txtProgressStatus.Text = _database.OfflineMode ? "[오프라인] 각인 및 DB 모사 성공" : "모든 공정 완료 (DB 저장 성공)";
- txtProgressStatus.Foreground = new SolidColorBrush(Color.FromRgb(16, 185, 129)); // Green text
- }
- else if (isFinalPass)
- {
- txtProgressStatus.Text = "최종 합격 (마킹 실패)";
- txtProgressStatus.Foreground = new SolidColorBrush(Color.FromRgb(245, 158, 11)); // Amber/Orange text
- }
- else
- {
- txtProgressStatus.Text = (result == "NG") ? "각인 QR 검증 실패 (DB NG 저장 완료)" : "최종 불합격 (DB 저장 성공)";
- txtProgressStatus.Foreground = new SolidColorBrush(Color.FromRgb(239, 68, 68)); // Red text
- }
+ txtProgressStatus.Text = _database.OfflineMode ? "[오프라인] 각인 및 DB 모사 성공" : "모든 공정 완료 (DB 저장 성공)";
+ txtProgressStatus.Foreground = new SolidColorBrush(Color.FromRgb(16, 185, 129)); // Green text
}
- if (isFinalPass && (result == "PASS" || result == "OK"))
- {
- LoggerService.Info($"[설비 통신] S/N: {serial} | 최종 SUCCESS 신호를 외부 메모리에 전달했습니다.");
- }
+ LoggerService.Info($"[설비 통신] S/N: {serial} | 최종 SUCCESS 신호를 외부 메모리에 전달했습니다.");
// 실시간 각인 순번 화면 정보 갱신
RefreshNextSequence();
diff --git a/marking_gui/Manual/03_메인_화면.md b/marking_gui/Manual/03_메인_화면.md
index 64bee27..61df8af 100644
--- a/marking_gui/Manual/03_메인_화면.md
+++ b/marking_gui/Manual/03_메인_화면.md
@@ -52,7 +52,7 @@
![[Pasted image 20260728100404.png]]
### 3.2.4 [카드 4] 최종 판정 및 종합 상태 영역 (우측 하단)
진행 상황 및 최종 판정 결과를 통합 표시하는 영역입니다.
-* **💬 진행 상황 뱃지**: "대기 상태", "제품 정보 수집 중...", "측정 계측기 데이터 수집 중...", "제품 합격 - 레이저 각인 중...", "각인 QR 검증 실패 (DB NG 저장 완료)" 등 설비 시퀀스 및 검증 동작을 실시간 텍스트로 표출합니다.
+* **💬 진행 상황 뱃지**: "대기 상태", "제품 정보 수집 중...", "측정 계측기 데이터 수집 중...", "제품 합격 - 레이저 각인 중...", "각인 QR 검증 실패 (DB 미저장, 순번 유지)" 등 설비 시퀀스 및 검증 동작을 실시간 텍스트로 표출합니다.
* **세부 정보 그리드**:
- **검사 시간 정보**: 전체 시퀀스 기동 시작 시간 및 종료 시간 표출
- **일련번호 정보**: `IC S/N`, **`Marking QR :`** (마킹 생성 QR 값), **`Scan QR :`** (스캐너 실측 QR 값), `각인 번호` 4개 항목을 수직 배열로 표출
diff --git a/marking_gui/Manual/07_시험_프로세스.md b/marking_gui/Manual/07_시험_프로세스.md
index fa876ef..7935047 100644
--- a/marking_gui/Manual/07_시험_프로세스.md
+++ b/marking_gui/Manual/07_시험_프로세스.md
@@ -82,8 +82,8 @@ graph TD
2. **QR 스캔 검증 실패 (팝업 유지 및 연속 재스캔 지원)**
- 스캔된 QR 코드가 불일치(대조 실패)할 경우, 팝업 창이 **자동으로 닫히지 않고 열린 상태를 유지**하며 "QR 바코드 불일치" 경고 상태를 표출합니다.
- 팝업이 열려 있는 동안 바코드/QR 스캐너 또는 키보드 입력을 통해 올바른 QR 코드로 **연속 재스캔**할 수 있으며, 재스캔에서 대조 성공 시 자동으로 통과(닫힘) 및 DB `OK` 저장 처리됩니다.
- - 대조 불일치 상태에서 작업자가 **[확인]** 또는 **[취소]** (ESC 키) 버튼을 누르면 팝업 창이 닫히며, 판정 결과 **`NG`**로 데이터베이스 저장을 완료합니다.
+ - 대조 불일치 상태에서 작업자가 **[확인]** 또는 **[취소]** (ESC 키) 버튼을 누르면 팝업 창이 닫히며, 판정 결과 **`NG`**로 처리됩니다. (**DB에 저장하지 않으므로 각인 순번 카운트가 증가하지 않습니다.**)
- 팝업이 닫힘과 동시에 메인 화면의 대형 판정 카드가 **`OK`**에서 **`NG`** (빨간색 테두리 및 배경)로 전환됩니다.
- - 공정 진행 상태 및 시스템 상태 바에 `"마킹 완료 / 각인 QR 검증 NG"`, `"상태: 검사 불합격 (각인 QR 검증 실패)"`, `"각인 QR 검증 실패 (DB NG 저장 완료)"` 등 구체적인 원인 설명이 표시되며, DB에 최종 `NG` 결과로 기록됩니다.
+ - 공정 진행 상태 및 시스템 상태 바에 `"마킹 완료 / 각인 QR 검증 NG"`, `"상태: 각인 QR 검증 불합격 (NG, DB 미저장)"` 등 구체적인 원인 설명이 표시됩니다. **NG 판정 시 DB에 기록하지 않으므로** 불량 제품이 집계 순번에 포함되지 않습니다.
diff --git a/marking_gui/Manual/Manual_Merged.md b/marking_gui/Manual/Manual_Merged.md
index dbf36f9..e32a411 100644
--- a/marking_gui/Manual/Manual_Merged.md
+++ b/marking_gui/Manual/Manual_Merged.md
@@ -654,7 +654,7 @@ Channel=1 ; 통신 채널 번호 (1 또는 2)
### 3.2.4 [카드 4] 최종 판정 및 종합 상태 영역 (우측 하단)
진행 상황 및 최종 판정 결과를 통합 표시하는 영역입니다.
-* **💬 진행 상황 뱃지**: "대기 상태", "제품 정보 수집 중...", "측정 계측기 데이터 수집 중...", "제품 합격 - 레이저 각인 중...", "각인 QR 검증 실패 (DB NG 저장 완료)" 등 설비 시퀀스 및 검증 동작을 실시간 텍스트로 표출합니다.
+* **💬 진행 상황 뱃지**: "대기 상태", "제품 정보 수집 중...", "측정 계측기 데이터 수집 중...", "제품 합격 - 레이저 각인 중...", "각인 QR 검증 실패 (DB 미저장, 순번 유지)" 등 설비 시퀀스 및 검증 동작을 실시간 텍스트로 표출합니다.
* **세부 정보 그리드**:
- **검사 시간 정보**: 전체 시퀀스 기동 시작 시간 및 종료 시간 표출
- **일련번호 정보**: `IC S/N`, **`Marking QR :`** (마킹 생성 QR 값), **`Scan QR :`** (스캐너 실측 QR 값), `각인 번호` 4개 항목을 수직 배열로 표출
@@ -900,9 +900,9 @@ graph TD
2. **QR 스캔 검증 실패 (팝업 유지 및 연속 재스캔 지원)**
- 스캔된 QR 코드가 불일치(대조 실패)할 경우, 팝업 창이 **자동으로 닫히지 않고 열린 상태를 유지**하며 "QR 바코드 불일치" 경고 상태를 표출합니다.
- 팝업이 열려 있는 동안 바코드/QR 스캐너 또는 키보드 입력을 통해 올바른 QR 코드로 **연속 재스캔**할 수 있으며, 재스캔에서 대조 성공 시 자동으로 통과(닫힘) 및 DB `OK` 저장 처리됩니다.
- - 대조 불일치 상태에서 작업자가 **[확인]** 또는 **[취소]** (ESC 키) 버튼을 누르면 팝업 창이 닫히며, 판정 결과 **`NG`**로 데이터베이스 저장을 완료합니다.
+ - 대조 불일치 상태에서 작업자가 **[확인]** 또는 **[취소]** (ESC 키) 버튼을 누르면 팝업 창이 닫히며, 판정 결과 **`NG`**로 처리됩니다. (**DB에 저장하지 않으므로 각인 순번 카운트가 증가하지 않습니다.**)
- 팝업이 닫힘과 동시에 메인 화면의 대형 판정 카드가 **`OK`**에서 **`NG`** (빨간색 테두리 및 배경)로 전환됩니다.
- - 공정 진행 상태 및 시스템 상태 바에 `"마킹 완료 / 각인 QR 검증 NG"`, `"상태: 검사 불합격 (각인 QR 검증 실패)"`, `"각인 QR 검증 실패 (DB NG 저장 완료)"` 등 구체적인 원인 설명이 표시되며, DB에 최종 `NG` 결과로 기록됩니다.
+ - 공정 진행 상태 및 시스템 상태 바에 `"마킹 완료 / 각인 QR 검증 NG"`, `"상태: 각인 QR 검증 불합격 (NG, DB 미저장)"` 등 구체적인 원인 설명이 표시됩니다. **NG 판정 시 DB에 기록하지 않으므로** 불량 제품이 집계 순번에 포함되지 않습니다.
diff --git a/marking_gui/Manual/Manual_for_pdf.html b/marking_gui/Manual/Manual_for_pdf.html
index 5a9e004..08095ec 100644
--- a/marking_gui/Manual/Manual_for_pdf.html
+++ b/marking_gui/Manual/Manual_for_pdf.html
@@ -745,7 +745,7 @@ Channel=1 ; 통신 채널 번호 (1 또는 2)

진행 상황 및 최종 판정 결과를 통합 표시하는 영역입니다.
-* 💬 진행 상황 뱃지: "대기 상태", "제품 정보 수집 중...", "측정 계측기 데이터 수집 중...", "제품 합격 - 레이저 각인 중...", "각인 QR 검증 실패 (DB NG 저장 완료)" 등 설비 시퀀스 및 검증 동작을 실시간 텍스트로 표출합니다.
+* 💬 진행 상황 뱃지: "대기 상태", "제품 정보 수집 중...", "측정 계측기 데이터 수집 중...", "제품 합격 - 레이저 각인 중...", "각인 QR 검증 실패 (DB 미저장, 순번 유지)" 등 설비 시퀀스 및 검증 동작을 실시간 텍스트로 표출합니다.
* 세부 정보 그리드:
- 검사 시간 정보: 전체 시퀀스 기동 시작 시간 및 종료 시간 표출
- 일련번호 정보: IC S/N, Marking QR : (마킹 생성 QR 값), Scan QR : (스캐너 실측 QR 값), 각인 번호 4개 항목을 수직 배열로 표출
@@ -986,9 +986,9 @@ Channel=1 ; 통신 채널 번호 (1 또는 2)
OK 저장 처리됩니다.NG로 데이터베이스 저장을 완료합니다.NG로 처리됩니다. (DB에 저장하지 않으므로 각인 순번 카운트가 증가하지 않습니다.)OK에서 NG (빨간색 테두리 및 배경)로 전환됩니다."마킹 완료 / 각인 QR 검증 NG", "상태: 검사 불합격 (각인 QR 검증 실패)", "각인 QR 검증 실패 (DB NG 저장 완료)" 등 구체적인 원인 설명이 표시되며, DB에 최종 NG 결과로 기록됩니다."마킹 완료 / 각인 QR 검증 NG", "상태: 각인 QR 검증 불합격 (NG, DB 미저장)" 등 구체적인 원인 설명이 표시됩니다. NG 판정 시 DB에 기록하지 않으므로 불량 제품이 집계 순번에 포함되지 않습니다.