# 通知設計書 20-在庫操作通知

## 概要

本ドキュメントは、在庫操作（受入、出荷など）の検証結果通知を設計するドキュメントである。

### 本通知の処理概要

本通知は、inventoriesプラグインにおける在庫操作（入庫、出庫、内部移動、ドロップシップ等）の実行時にユーザーへフィードバックを提供するアプリ内通知である。

**業務上の目的・背景**：倉庫管理において、在庫移動操作の結果を即座にフィードバックし、正確な在庫管理を支援する。成功・警告・失敗の各状態を明確に伝達し、問題発生時には適切な対処を促す。特にバリデーション（検証）処理では、ロット/シリアル番号の不整合やパッケージの部分移動など、複雑なチェックを行う。

**通知の送信タイミング**：Todo（準備）、Validate（検証）、削除などの在庫操作実行時に表示される。

**通知の受信者**：操作を実行したログインユーザー。画面上にトースト形式で通知が表示される。

**通知内容の概要**：操作種別と結果に応じたメッセージ。成功時は緑色、警告時はオレンジ、失敗時は赤色で表示される。

**期待されるアクション**：成功通知は確認のみ。警告・失敗通知の場合は、問題を確認・修正してから再試行する。

## 通知種別

アプリ内通知（Filament Notification - トースト形式）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（画面即時表示） |
| 優先度 | 高 |
| リトライ | なし（UI通知のため） |

### 送信先決定ロジック

操作を実行した現在ログイン中のユーザーのブラウザ画面に直接表示される。

## 通知テンプレート

### アプリ内通知の場合

| 項目 | 内容 |
|-----|------|
| 表示位置 | 画面右上（Filamentデフォルト） |
| 表示色 | 成功：緑色、警告：オレンジ、失敗：赤色 |
| 自動消去 | あり（数秒後） |
| 手動消去 | 可能 |

### 本文テンプレート

```
【Todo処理成功】
タイトル: "Operation Ready"
本文: "Transfer is ready for processing."

【Todo処理警告 - 移動明細なし】
タイトル: "Warning"
本文: "Please add at least one move line before proceeding."

【Validate処理成功】
タイトル: "Validated"
本文: "Transfer has been validated successfully."

【Validate警告 - 明細行なし】
タイトル: "Lines Missing"
本文: "Move lines are missing. Please add detailed lines."

【Validate警告 - ロット番号未設定】
タイトル: "Lot Missing"
本文: "Lot/Serial number is required for tracked products."

【Validate警告 - シリアル番号数量不正】
タイトル: "Serial Quantity Issue"
本文: "Serial tracked products must have exactly 1 quantity."

【Validate警告 - 部分パッケージ移動】
タイトル: "Partial Package"
本文: "Cannot move partial contents of a package to the same destination."

【削除成功】
タイトル: "Deleted"
本文: "Operation has been deleted successfully."

【削除失敗 - 参照エラー】
タイトル: "Deletion Failed"
本文: "This record cannot be deleted because it is referenced by other records."
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | アプリ内通知のため添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| title | 通知タイトル | 言語ファイル | Yes |
| body | 通知本文 | 言語ファイル | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | TodoAction成功 | 準備処理完了 | 移動準備完了 |
| 画面操作 | TodoAction警告 | 移動明細なし | moves->count() == 0 |
| 画面操作 | ValidateAction成功 | 検証処理完了 | 在庫移動確定 |
| 画面操作 | ValidateAction警告 | 明細行なし | lines->isEmpty() |
| 画面操作 | ValidateAction警告 | ロット番号未設定 | lot_id未設定（追跡商品） |
| 画面操作 | ValidateAction警告 | シリアル数量不正 | qty != 1（シリアル追跡） |
| 画面操作 | ValidateAction警告 | 部分パッケージ | パッケージの一部移動 |
| 画面操作 | DeleteAction成功 | 削除処理完了 | 操作レコード削除 |
| 画面操作 | DeleteAction失敗 | QueryException | 参照整合性エラー |
| 画面操作 | BulkDeleteAction成功 | 一括削除完了 | 複数レコード削除 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 状態がDONE/CANCELED | 完了・キャンセル済み操作では一部アクション非表示 |

## 処理フロー

### 送信フロー（ValidateAction）

```mermaid
flowchart TD
    A[ValidateAction実行] --> B[hasMoveErrors チェック]
    B --> C{移動明細あり?}
    C -->|No| D[警告通知: 移動明細なし]
    C -->|Yes| E[各moveをチェック]
    E --> F{明細行あり?}
    F -->|No| G[警告通知: 明細行なし]
    F -->|Yes| H{パッケージチェック}
    H -->|部分移動| I[警告通知: 部分パッケージ]
    H -->|OK| J{ロット追跡?}
    J -->|Yes, lot_idなし| K[警告通知: ロット番号未設定]
    J -->|OK| L{シリアル追跡?}
    L -->|Yes, qty!=1| M[警告通知: シリアル数量不正]
    L -->|Yes, 重複lot| M
    L -->|OK| N[バリデーションOK]
    D --> O[処理中断]
    G --> O
    I --> O
    K --> O
    M --> O
    N --> P[Inventory::validateTransfer]
    P --> Q[成功通知表示]
    Q --> R[終了]
    O --> R
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| inventories_operations | 操作データ | CRUD対象 |
| inventories_moves | 移動明細 | バリデーション対象 |
| inventories_move_lines | 明細行 | 詳細チェック |
| inventories_product_quantities | 在庫数量 | パッケージ確認 |
| products_products | 商品情報 | 追跡設定確認 |

### テーブル別参照項目詳細

#### inventories_operations

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | 操作特定 | 対象操作ID |
| state | 状態確認 | 表示制御 |
| operation_type_id | 操作タイプ | バックオーダー設定 |

#### inventories_moves

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| product_id | 商品特定 | 追跡設定確認 |
| lines | 明細行取得 | リレーション |

#### inventories_move_lines

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| lot_id | ロット確認 | 追跡商品 |
| qty | 数量確認 | シリアル追跡 |
| package_id | パッケージ確認 | 部分移動チェック |
| result_package_id | 結果パッケージ | 移動先確認 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| inventories_operations | UPDATE/DELETE | 状態更新・削除 |
| inventories_product_quantities | UPDATE | 在庫数量更新（Validate時） |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 移動明細なし | moves->count() == 0 | 警告通知、処理中断 |
| 明細行なし | lines->isEmpty() | 警告通知、処理中断 |
| ロット未設定 | lot追跡でlot_id = null | 警告通知、処理中断 |
| シリアル数量不正 | serial追跡でqty != 1 | 警告通知、処理中断 |
| シリアル重複 | 同一lot_idが複数 | 警告通知、処理中断 |
| 部分パッケージ | パッケージ一部移動 | 警告通知、処理中断 |
| QueryException | 参照整合性違反 | 失敗通知表示 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（ユーザーが修正後に再試行） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし |
| 1日あたり上限 | なし |

### 配信時間帯

特に制限なし（操作時に即時表示）

## セキュリティ考慮事項

- 在庫操作は倉庫管理権限が必要
- 在庫数量の不正操作防止
- 監査ログによる操作履歴管理

## 備考

- inventoriesプラグインで使用
- TodoAction: 操作の準備（moves計算）
- ValidateAction: 操作の確定（在庫反映）
- ProductTracking Enum: NONE, LOT, SERIAL
- OperationState Enum: DRAFT, CONFIRMED, WAITING, READY, DONE, CANCELED
- CreateBackorder設定によるバックオーダー自動作成
- 言語ファイルは `inventories::filament/clusters/operations/actions/` 配下に配置
- 関連ファイル:
  - TodoAction.php
  - ValidateAction.php
  - ReturnSlipAction.php
  - ReceiptResource.php
  - DeliveryResource.php
  - InternalResource.php
  - DropshipResource.php
