# 機能設計書 49-カタログアイテム検索

## 概要

本ドキュメントは、QuickerSite CMSにおけるカタログアイテム検索機能の設計仕様を定義する。この機能は、カタログに登録されたアイテムを様々な条件で検索し、結果を表示・Excel出力する機能である。

### 本機能の処理概要

**業務上の目的・背景**：
商品カタログに登録された多数のアイテムから、特定の条件に合致するアイテムを効率的に探し出す必要がある。本機能により、管理者はタイトルやカスタムフィールドの値を指定して検索を行い、該当するアイテムの一覧を取得できる。

**機能の利用シーン**：
- 特定の商品名でアイテムを検索する場面
- フィールド値を条件にアイテムを絞り込む場面
- 日付範囲でアイテムを検索する場面
- 検索結果をExcelファイルとして出力する場面
- 検索結果からアイテムをコピーする場面

**主要な処理内容**：
1. カタログの選択（ドロップダウンから選択）
2. 検索条件の入力（タイトル、各種フィールド値）
3. 検索の実行とSQL動的構築
4. 検索結果のテーブル表示
5. 検索結果のExcel出力
6. アイテムのコピー機能

**関連システム・外部連携**：
- カタログ一覧機能（機能45）からの遷移
- カタログアイテム管理機能（機能48）への遷移（編集・新規作成）
- Excel出力機能（cls_excelFileクラス）

**権限による制御**：
- `secondAdmin.bCatalog`権限を持つ管理者のみがアクセス可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 39 | カタログアイテム検索 | 主画面 | カタログアイテムの検索・一覧表示 |
| 34 | カタログ一覧 | 参照元画面 | 登録済みカタログの一覧表示 |
| 38 | カタログアイテム編集 | 遷移先画面 | アイテムの編集画面 |

## 機能種別

検索・一覧表示（カタログアイテムの動的検索とExcel出力）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| iCatalogID | String(暗号化) | Yes | 対象カタログのID | 復号化後に数値であること |
| sTitle | String | No | タイトル検索文字列 | 空白区切りでOR検索 |
| {fieldID} | String(暗号化) | No | フィールド値（テキスト系） | フィールドタイプに応じた形式 |
| from{fieldID} | String | No | 日付範囲の開始 | 日付形式 |
| untill{fieldID} | String | No | 日付範囲の終了 | 日付形式 |
| btnaction | String | No | 実行アクション | 検索/excel |
| pageSize | Integer | No | ページサイズ | 数値、デフォルト9999 |
| absolutepage | Integer | No | ページ番号 | 数値、デフォルト1 |
| iItemID | String(暗号化) | No | コピー対象アイテムID | 復号化後に数値であること |

### 入力データソース

- 画面フォームからのPOSTリクエスト
- URLパラメータ（暗号化されたID）
- データベース（tblCatalogItem, tbCatalogItemFields, tblCatalogField）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 検索フォーム | HTML | 検索条件入力フォーム |
| 検索結果テーブル | HTML | アイテム一覧のテーブル（ソート可能） |
| 検索件数 | Integer | 該当アイテム数 |
| Excelファイル | File | 検索結果のExcel形式出力 |
| ページネーション | HTML | ページ送りリンク |

### 出力先

- 管理画面（HTML形式でブラウザに表示）
- Excelファイル（ダウンロード）

## 処理フロー

### 処理シーケンス

```
1. 認証・権限チェック
   └─ secondAdmin.bCatalog権限の確認

2. cls_itemSearchオブジェクト生成
   └─ パラメータの初期化

3. 検索フィールド設定
   └─ catalog.fields("search")で検索対象フィールド取得

4. リクエスト値取得
   └─ itemSearch.getRequestValues()

5. コピー処理判定
   └─ iItemIDが数値ならcatalogItem.copy()実行
   └─ 同ページにリダイレクト

6. 検索条件フォーム表示
   └─ カタログ選択、タイトル、各フィールド条件

7. 検索実行・結果表示
   ├─ search: itemSearch.resultTableでHTML出力
   └─ excel: cls_excelFileでExcel出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{認証・権限チェック}
    B -->|権限なし| C[アクセス拒否]
    B -->|権限あり| D[cls_itemSearch生成]
    D --> E[検索フィールド取得]
    E --> F[リクエスト値取得]
    F --> G{iItemIDあり?}
    G -->|Yes| H[catalogItem.copy]
    H --> I[同ページへリダイレクト]
    G -->|No| J[検索フォーム表示]
    J --> K{カタログ選択済?}
    K -->|No| L[カタログ選択待ち]
    K -->|Yes| M[条件入力フォーム表示]
    M --> N{アクション判定}
    N -->|search| O[resultTable生成]
    N -->|excel| P[Excel出力]
    O --> Q[検索結果テーブル表示]
    P --> R[ダウンロードリンク表示]
    Q --> S[終了]
    R --> S
    L --> S
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-49-01 | カタログ選択必須 | 検索実行にはカタログ選択が必要 | 検索時 |
| BR-49-02 | タイトル部分一致検索 | タイトルはLIKE '%keyword%'で検索 | タイトル入力時 |
| BR-49-03 | タイトル空白区切りOR検索 | 空白で区切った複数キーワードはOR条件 | タイトル入力時 |
| BR-49-04 | 日付範囲検索 | from-untillで日付範囲を指定可能 | 日付フィールド検索時 |
| BR-49-05 | 検索対象フィールド限定 | bSearchField=trueのフィールドのみ検索条件に表示 | 検索フォーム表示時 |
| BR-49-06 | フィールド値部分一致 | フィールド値もLIKE '%value%'で検索 | フィールド条件入力時 |
| BR-49-07 | 結果ソート順 | catalog.sOrderItemsByに従ってソート | 結果表示時 |

### 計算ロジック

検索結果件数の計算：
- 各アイテムは検索フィールド数分のレコードを持つため、`recordCount / searchFields.count`で実際のアイテム数を算出

ページネーション計算：
- `First_Record = (absolutepage * pageSize) - (pageSize - 1)`
- `Last_Record = absolutepage * pageSize`（レコード総数を超えない）

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| カタログ取得 | tblCatalog | SELECT | 選択可能なカタログ一覧 |
| フィールド取得 | tblCatalogField | SELECT | 検索対象フィールド定義 |
| アイテム検索 | tblCatalogItem, tbCatalogItemFields, tblCatalogField | SELECT(JOIN) | 検索条件に合致するアイテム |
| アイテムコピー | tblCatalogItem, tbCatalogItemFields | INSERT | アイテムの複製 |

### テーブル別操作詳細

#### 検索クエリ（動的生成）

| 操作 | 項目（カラム名） | 取得条件 | 備考 |
|-----|-----------------|---------|------|
| SELECT | tbCatalogItemFields.iFieldID, iItemID, sValue | INNER JOINで結合 | 検索フィールドに限定 |
| SELECT | tblCatalogItem.sTitle, dOnlineFrom, dOnlineUntill, sPicExt | WHERE条件で絞り込み | タイトル部分一致 |

#### 検索WHERE条件の動的構築

- カタログID指定: `tblCatalogField.iCatalogID = 指定値`
- 検索フィールド限定: `tbCatalogItemFields.iFieldID in (検索フィールドIDリスト)`
- タイトル検索: `tblCatalogItem.sTitle like '%keyword%'`（OR結合）
- フィールド値検索: サブクエリで `tbCatalogItemFields.sValue like '%value%'`
- 日付範囲検索: サブクエリで `sValue >= fromDate and sValue <= untillDate`
- オンライン状態: `dOnlineFrom <= 現在日 and dOnlineUntill >= 現在日`

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ACCESS_DENIED | 権限エラー | bCatalog権限なし | アクセス拒否画面へ遷移 |
| NO_CATALOG | 入力エラー | カタログ未選択で検索 | 検索フォームのみ表示 |
| NO_RESULTS | 検索結果なし | 該当アイテムなし | "0 件"と表示 |

### リトライ仕様

特になし（検索条件を変更して再実行）

## トランザクション仕様

検索処理は参照のみのため、トランザクション制御は不要。アイテムコピー時はcatalogItem.copy()内で処理される。

## パフォーマンス要件

- 検索画面表示：1秒以内
- 検索結果表示：アイテム数1000件以下で3秒以内
- Excel出力：アイテム数1000件以下で5秒以内

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

- 認証・認可：logon.hasaccess による権限チェック
- ID暗号化：encrypt/decrypt関数によるID値の保護（フィールドIDも暗号化）
- SQLインジェクション対策：cleanup関数による入力値のサニタイズ
- XSS対策：quotRep関数による出力エスケープ

## 備考

フィールドタイプ別の検索UI：
- sb_text, sb_textarea, sb_url, sb_email, sb_richtext: テキストボックス
- sb_checkbox: チェックボックス
- sb_select: ドロップダウン（定義済み選択肢）
- sb_date: 日付範囲入力（from-untill）with DatePicker

検索結果表示の特徴：
- sortableクラスによるクライアントサイドソート機能
- オンライン/オフライン状態の視覚的表示（V/X、色分け）
- サムネイル画像表示（catalog.bAutoThumb=true時）
- アイテムコピーアイコン

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

検索機能のデータモデルを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ItemSearch.asp | `asp/includes/ItemSearch.asp` | cls_itemSearchクラスのプロパティ・メソッドを理解する |

**主要プロパティ（2-17行目）**:
- recordCount, pageCount: ページネーション用
- searchFields, inputFields, dateFields: 検索条件管理
- pageSize, absolutepage: ページング制御
- sTitle, iCatalogID, bOnline: 基本検索条件
- p_catalog: カタログオブジェクト（遅延ロード）

**読解のコツ**:
- 18-41行目: Class_Initialize（inputFields、dateFieldsをDictionaryで初期化）
- 42-113行目: fixedSQL関数（動的SQL構築の核心部分）
- 114-134行目: getRequestValues（暗号化フィールドIDからの値取得）
- 216-293行目: resultTable関数（HTML/Excel出力の分岐）

#### Step 2: エントリーポイントを理解する

検索画面の処理起点を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | bs_catalogItemSearch.asp | `asp/bs_catalogItemSearch.asp` | 検索画面のメイン処理 |

**主要処理フロー**:
1. **4行目**: 権限チェック（secondAdmin.bCatalog）
2. **5-8行目**: cls_itemSearchオブジェクト生成、検索フィールド設定
3. **9-13行目**: inputFields、dateFieldsの準備
4. **18-20行目**: アイテムコピー処理（iItemIDがある場合）
5. **21-25行目**: 検索フォーム表示（フィールドタイプ別UI）
6. **29行目**: resultTableで検索結果出力

### プログラム呼び出し階層図

```
bs_catalogItemSearch.asp (検索画面)
    │
    ├─ cls_itemSearch.new()
    │      ├─ inputFields=Dictionary
    │      └─ dateFields=Dictionary
    │
    ├─ catalog.fields("search")
    │      └─ tblCatalogField SELECT (bSearchField=true)
    │
    ├─ cls_itemSearch.getRequestValues()
    │      ├─ sTitle取得
    │      ├─ inputFields.Add (各フィールド値)
    │      └─ dateFields.Add (日付from/untill)
    │
    ├─ cls_catalogItem.copy() [iItemIDがある場合]
    │      ├─ tblCatalogItem INSERT
    │      └─ tbCatalogItemFields INSERT
    │
    └─ cls_itemSearch.resultTable()
           ├─ getRows()
           │      └─ fixedSQL() - 動的SQL生成
           │             ├─ JOIN構築
           │             ├─ WHERE条件構築
           │             │      ├─ タイトルLIKE
           │             │      ├─ フィールド値サブクエリ
           │             │      └─ 日付範囲サブクエリ
           │             └─ ORDER BY
           │
           └─ [mode判定]
                  ├─ search: HTMLテーブル生成
                  └─ excel: cls_excelFile.export()
```

### データフロー図

```
[入力]                    [処理]                         [出力]

URLパラメータ ──────▶ bs_catalogItemSearch.asp ──▶ 検索フォームHTML
(iCatalogID)            │
                        └─ catalog.fields("search")
                               └─ tblCatalogField SELECT

POSTデータ ────────▶ bs_catalogItemSearch.asp ──▶ 検索結果
(sTitle, フィールド値)   │
                        ├─ cls_itemSearch.getRequestValues()
                        │
                        ├─ cls_itemSearch.fixedSQL()
                        │      └─ 動的WHERE句構築
                        │
                        └─ cls_itemSearch.resultTable()
                               ├─ [search] HTMLテーブル
                               └─ [excel] cls_excelFile
                                          └─ ダウンロードリンク
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| bs_catalogItemSearch.asp | `asp/bs_catalogItemSearch.asp` | ソース | 検索画面メイン |
| ItemSearch.asp | `asp/includes/ItemSearch.asp` | ソース | cls_itemSearchクラス定義 |
| catalogItem.asp | `asp/includes/catalogItem.asp` | ソース | cls_catalogItemクラス（コピー機能） |
| catalog.asp | `asp/includes/catalog.asp` | ソース | cls_catalogクラス（fields取得） |
| excelFile.asp | `asp/includes/excelFile.asp` | ソース | cls_excelFileクラス（Excel出力） |
| bs_catalogItemEdit.asp | `asp/bs_catalogItemEdit.asp` | ソース | アイテム編集画面（遷移先） |
| bs_catalogList.asp | `asp/bs_catalogList.asp` | ソース | カタログ一覧画面（戻り先） |
