# 画面設計書 139-顧客製品詳細

## 概要

本ドキュメントは、QuickerSite CMSにおける顧客製品詳細画面（ad_clientproduct.asp）の設計仕様を定義するものである。

### 本画面の処理概要

本画面は、システム管理者（Admin）がクライアント製品（サービス契約）の詳細情報を編集するための画面である。製品名、料金、更新周期、サービス期間、請求書番号などの契約情報を管理できる。

**業務上の目的・背景**：QuickerSiteはホスティングサービスとして複数のクライアントにサービスを提供している。本画面は、個々の製品（サービス契約）の詳細情報を登録・編集するための画面である。契約管理、請求業務、更新管理などの業務で活用される。

**画面へのアクセス方法**：顧客詳細画面（ad_client.asp）の製品一覧から「製品追加」リンクまたは既存製品をクリックしてアクセスする。また、顧客製品一覧画面（ad_clientproducts.asp）から製品名をクリックしてもアクセス可能。

**主要な操作・処理内容**：
1. 製品情報の新規登録
2. 既存製品情報の編集
3. 製品の削除
4. FCKEditorによるメモ編集

**画面遷移**：
- 遷移元：ad_client.asp（顧客詳細）、ad_clientproducts.asp（顧客製品一覧）
- 遷移先：ad_client.asp（保存/削除後）

**権限による表示制御**：管理者認証（ad_security.asp）を通過したシステム管理者のみがアクセス可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 77 | ショッピングカート管理 | 主機能 | 顧客製品の編集 |

## 画面種別

編集（顧客製品詳細画面）

## URL/ルーティング

`asp/ad_clientproduct.asp?iClientProductId={製品ID}&iClientID={顧客ID}`

## 入出力項目

| 項目名 | 項目ID | 入力/出力 | データ型 | 必須 | 説明 |
|--------|--------|-----------|----------|------|------|
| 製品ID | iClientProductID | 入力 | Integer | - | 製品ID（編集時、暗号化） |
| 顧客ID | iClientID | 入力 | Integer | 必須 | 所属クライアントID（暗号化） |
| 製品名 | sName | 入力 | String | 必須 | 製品名（最大250文字） |
| メモ | sNotes | 入力 | String | - | メモ（FCKEditor） |
| 料金 | iPrice | 入力 | Integer | - | 料金 |
| 消費税 | iVat | 入力 | Integer | - | 消費税率（%） |
| サービス開始日 | dStartService | 入力 | Date | - | サービス開始日 |
| サービス終了日 | dEndService | 入力 | Date | - | サービス終了日 |
| 更新周期 | iRenewal | 入力 | Integer | - | 更新周期（月数、0:更新なし） |
| 最終更新日 | dLastRenewalDate | 入力 | Date | - | 最終更新日 |
| 請求書番号 | sInvoiceNr | 入力 | String | - | 請求書番号（最大50文字） |
| アクション | btnaction | 入力 | String | - | 保存/削除 |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| 顧客名リンク | Link | 所属顧客詳細へのリンク |
| Product infoセクション | Header | 製品情報ヘッダー |
| 顧客選択 | Select | 顧客ドロップダウン |
| 製品名 | TextInput | 製品名入力 |
| メモ | FCKEditor | リッチテキストエディタ |
| 料金 | TextInput | 料金入力（50px幅） |
| VAT | TextInput | 消費税率入力（30px幅） |
| サービス開始日 | DatePicker | 開始日ピッカー |
| サービス終了日 | DatePicker | 終了日ピッカー |
| 更新周期 | Select | 0〜96ヶ月選択 |
| 最終更新日 | DatePicker | 最終更新日ピッカー |
| 請求書番号 | TextInput | 請求書番号入力（130px幅） |

## イベント仕様

### 1-保存（Save）

btnactionが"save"の場合、製品情報を保存する。

1. フォームから各項目を取得
2. 暗号化されたiClientIDを復号化
3. 日付項目をconvertDateFromPicker()で変換
4. clientproduct.save()で保存
5. ad_client.aspにリダイレクト（クライアントID付き）

### 2-削除（Delete）

btnactionが"delete"の場合、製品を削除する。

1. JavaScript confirm()で確認
2. CSRF検証（checkCSRF）
3. clientproduct.remove()で削除
4. ad_client.aspにリダイレクト（クライアントID付き）

### 3-顧客リンククリック

顧客名リンクをクリックすると、顧客詳細画面に遷移する。

1. 暗号化されたクライアントIDをパラメータとして渡す
2. ad_client.aspに遷移

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 保存（新規） | tblClientProduct | INSERT | 製品情報を新規作成 |
| 保存（更新） | tblClientProduct | UPDATE | 製品情報を更新 |
| 削除 | tblClientProduct | DELETE | 製品情報を削除 |
| 画面表示 | tblClient | SELECT | 顧客一覧取得（ドロップダウン用） |

### テーブル別更新項目詳細

#### tblClientProduct

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | sName | フォーム入力値 | 製品名 |
| INSERT/UPDATE | iPrice | フォーム入力値 | 料金 |
| INSERT/UPDATE | iVat | フォーム入力値 | 消費税率 |
| INSERT/UPDATE | iRenewal | フォーム入力値 | 更新周期（月） |
| INSERT/UPDATE | dLastRenewalDate | フォーム入力値 | 最終更新日 |
| INSERT/UPDATE | sNotes | フォーム入力値 | メモ |
| INSERT/UPDATE | iClientID | フォーム入力値 | クライアントID |
| INSERT/UPDATE | dStartService | フォーム入力値 | サービス開始日 |
| INSERT/UPDATE | dEndService | フォーム入力値 | サービス終了日 |
| INSERT/UPDATE | sInvoiceNr | フォーム入力値 | 請求書番号 |
| INSERT | dCreatedTS | now() | 作成日時 |
| UPDATE | dUpdatedTS | now() | 更新日時 |
| DELETE | iId | 対象製品ID | 製品削除 |

## メッセージ仕様

| 種別 | メッセージ | 発生条件 |
|------|----------|---------|
| エラー | err_mandatory | 必須項目（製品名、顧客ID）未入力時 |
| 確認 | areyousure | 削除ボタンクリック時 |

## 例外処理

| 例外 | 処理内容 |
|------|---------|
| 必須項目未入力 | message.AddError()でエラー表示、保存処理中止 |
| 顧客未選択 | message.AddError()でエラー表示、保存処理中止 |
| 新規作成時 | 削除ボタンを非表示にして防止 |

## 備考

- 必須項目：製品名（sName）、顧客（iClientID）
- 新規作成時のデフォルト値：
  - dStartService: 今日の日付
  - dEndService: 今日から1年後
  - iRenewal: 12（月）
- 更新周期は0〜96ヶ月から選択（0は更新なしのサービス）
- FCKEditorでメモ（sNotes）をリッチテキスト編集可能
- 日付はJQDatePicker()でピッカー入力
- 暗号化された製品IDとクライアントIDを使用してセキュリティ確保
- 保存/削除後は元の顧客詳細画面に戻る

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | clientproduct.asp | `asp/includes/clientproduct.asp` | cls_clientproductクラスの全体構造を理解 |
| 1-2 | client.asp | `asp/includes/client.asp` | cls_clientクラスのshowSelected()メソッドを理解 |

**読解のコツ**: cls_clientproductクラスは製品情報を管理する。class_initialize()でデフォルト値を設定し、check()で必須項目を検証する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ad_clientproduct.asp | `asp/ad_clientproduct.asp` | メイン処理フロー |

**主要処理フロー**:
1. **行5**: cls_clientproductインスタンス作成（class_initializeで自動取得）
2. **行6-20**: 保存処理（フォーム値取得→save()→リダイレクト）
3. **行21-25**: 削除処理（CSRF検証→remove()→リダイレクト）
4. **行26**: フォーム表示（FCKEditor、DatePicker含む）

#### Step 3: 各処理層の詳細

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | clientproduct.asp | `asp/includes/clientproduct.asp` | check()メソッド（行19-29）でバリデーション |
| 3-2 | clientproduct.asp | `asp/includes/clientproduct.asp` | save()メソッド（行53-84）で保存処理 |
| 3-3 | clientproduct.asp | `asp/includes/clientproduct.asp` | remove()メソッド（行98-104）で削除処理 |

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

```
ad_clientproduct.asp
    │
    ├─ begin.asp (共通初期化)
    │
    ├─ beginClient.asp (クライアント初期化)
    │
    ├─ ad_security.asp (管理者認証)
    │
    ├─ ad_adminMenu.asp (管理者メニュー)
    │
    ├─ cls_clientproduct
    │      ├─ class_initialize() (初期化、デフォルト値設定)
    │      │     └─ pick() (既存製品取得)
    │      ├─ client() (クライアント情報取得)
    │      │     └─ cls_client.pick()
    │      ├─ check() (バリデーション)
    │      ├─ save() (保存)
    │      │     ├─ dCreatedTS設定（新規時）
    │      │     └─ dUpdatedTS設定
    │      └─ remove() (削除)
    │
    ├─ cls_client
    │      └─ showSelected() (顧客ドロップダウン)
    │
    ├─ createFCKInstance() (リッチテキストエディタ)
    │
    └─ JQDatePicker() (日付ピッカー)
```

### データフロー図

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

iClientProductID     ┌─────────────────┐
iClientID      ─────▶│ class_initialize│
                     │ pick()          │
                     └─────────────────┘
                           │
                           ▼
                     ┌─────────────────┐
                     │ tblClientProduct│
                     │ SELECT          │
                     └─────────────────┘
                           │
                           ▼
                     ┌─────────────────┐
フォーム入力 ─────────▶│ 製品情報編集     │
                     │ ・製品名        │
                     │ ・料金/VAT      │
                     │ ・サービス期間  │
                     │ ・更新情報      │
                     └─────────────────┘
                           │
        ┌──────────────────┼──────────────────┐
        ▼                  ▼                  ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ check()       │ │ remove()      │ │ 表示処理       │
│ バリデーション │ │ 削除処理       │ │ FCKEditor     │
└───────────────┘ └───────────────┘ │ DatePicker    │
        │                  │        └───────────────┘
        ▼                  ▼
┌───────────────┐ ┌───────────────┐
│ save()        │ │ DELETE        │
│ INSERT/UPDATE │ │ tblClientProd │
└───────────────┘ └───────────────┘
        │                  │
        └──────────────────┘
                 │
                 ▼
           [リダイレクト]
           ad_client.asp
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ad_clientproduct.asp | `asp/ad_clientproduct.asp` | ソース | 製品詳細画面 |
| ad_client.asp | `asp/ad_client.asp` | ソース | 顧客詳細画面（遷移元/先） |
| ad_clientproducts.asp | `asp/ad_clientproducts.asp` | ソース | 製品一覧画面（遷移元） |
| clientproduct.asp | `asp/includes/clientproduct.asp` | インクルード | 製品クラス定義 |
| client.asp | `asp/includes/client.asp` | インクルード | クライアントクラス定義 |
| ad_security.asp | `asp/ad_security.asp` | インクルード | 管理者認証 |
| ad_adminMenu.asp | `asp/ad_adminMenu.asp` | インクルード | 管理者メニュー |
