# 画面設計書 9-取引先新規作成フォーム

## 概要

本ドキュメントは、Fat Free CRMの取引先新規作成フォームの設計仕様を記述したものです。

### 本画面の処理概要

新規取引先（Account）を作成するためのフォームです。取引先一覧画面からモーダル/インラインで表示され、基本情報、連絡先情報、アクセス権限、コメントを入力して取引先を作成します。

**業務上の目的・背景**：本フォームは、新規顧客、パートナー企業、競合他社などの取引先情報を登録するための機能を提供します。営業担当者が商談や連絡先を関連付ける前に、まず取引先（会社）の情報を登録することで、組織的な顧客管理を実現します。アクセス権限設定により、チーム内での情報共有範囲を制御できます。

**画面へのアクセス方法**：取引先一覧画面の「Create Account」ボタンをクリックするか、URL `/accounts/new` にアクセスします（通常はAJAXで表示）。

**主要な操作・処理内容**：
1. 取引先名を入力する（必須）
2. 担当者を選択する
3. カテゴリを選択する
4. 評価（Rating）を設定する
5. 背景情報を入力する
6. タグを設定する
7. 連絡先情報（電話、FAX、メール、ウェブサイト）を入力する
8. 住所（請求先・配送先）を入力する
9. カスタムフィールドを入力する
10. コメントを入力する
11. アクセス権限を設定する
12. 「Create Account」ボタンをクリックして作成する

**画面遷移**：
- この画面に遷移してくる画面: 取引先一覧画面（新規作成ボタン）
- この画面から遷移できる画面: 取引先一覧画面（作成成功後/キャンセル時）

**権限による表示制御**：
- 認証済みユーザーのみがアクセス可能
- アクセス権限設定は全ユーザーに表示

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | 取引先作成 | 主機能 | 新規取引先情報入力、コメント追加、作成実行 |
| 83 | タグ付け | 補助機能 | 取引先へのタグ付け |
| 84 | アクセス権限管理 | 補助機能 | 取引先のアクセス権限設定 |

## 画面種別

登録（モーダル/インライン）

## URL/ルーティング

| メソッド | URL | アクション |
|----------|-----|----------|
| GET | `/accounts/new` | accounts#new (AJAX) |
| POST | `/accounts` | accounts#create (AJAX) |

## 入出力項目

| 項目名 | 項目ID | 入力/出力 | データ型 | 必須 | 最大長 | 説明 |
|--------|--------|----------|---------|------|--------|------|
| 取引先名 | account[name] | 入力 | String | 必須 | 64 | 取引先の名前 |
| 担当者 | account[assigned_to] | 入力 | Integer | - | - | 割り当てるユーザーID |
| カテゴリ | account[category] | 入力 | String | - | 32 | affiliate/competitor/customer/partner/reseller/vendor/other |
| 評価 | account[rating] | 入力 | Integer | - | - | 0-5の評価値 |
| 背景情報 | account[background_info] | 入力 | String | - | 255 | 取引先の背景情報 |
| タグ | account[tag_list] | 入力 | String | - | - | カンマ区切りのタグ |
| フリーダイヤル | account[toll_free_phone] | 入力 | String | - | 32 | フリーダイヤル番号 |
| 電話番号 | account[phone] | 入力 | String | - | 32 | 電話番号 |
| FAX | account[fax] | 入力 | String | - | 32 | FAX番号 |
| ウェブサイト | account[website] | 入力 | String | - | 64 | ウェブサイトURL |
| メールアドレス | account[email] | 入力 | String | - | 254 | メールアドレス |
| 緯度 | account[latitude] | 入力 | Decimal | - | - | 緯度（-90〜90） |
| 経度 | account[longitude] | 入力 | Decimal | - | - | 経度（-180〜180） |
| 請求先住所 | account[billing_address_attributes] | 入力 | Object | - | - | 請求先住所情報 |
| 配送先住所 | account[shipping_address_attributes] | 入力 | Object | - | - | 配送先住所情報 |
| アクセス権限 | account[access] | 入力 | String | - | 8 | Public/Private/Shared |
| 共有ユーザー | account[user_ids] | 入力 | Array | - | - | 共有するユーザーID |
| コメント | comment_body | 入力 | Text | - | - | 作成時のコメント |

## 表示項目

| 項目名 | 表示条件 | 説明 |
|--------|---------|------|
| フォームタイトル | 常時 | 新規作成フォームのタイトル |
| 取引先名入力フィールド | 常時 | 必須入力フィールド |
| 担当者選択 | 常時 | ユーザー選択ドロップダウン |
| カテゴリ選択 | 常時 | カテゴリドロップダウン |
| 評価選択 | 常時 | 星評価セレクター |
| 背景情報入力 | Setting.background_info含む場合 | テキストエリア |
| タグ入力 | 常時 | タグ入力フィールド |
| 連絡先情報セクション | 常時 | 電話、FAX、メール、ウェブサイト |
| 住所セクション | 常時 | 請求先・配送先住所 |
| カスタムフィールドセクション | カスタムフィールドが定義されている場合 | フィールドグループ単位で表示 |
| コメント入力 | 常時 | テキストエリア |
| アクセス権限セクション | 常時 | 権限設定ラジオボタン |
| 作成ボタン | 常時 | 「Create Account」ボタン |
| キャンセルリンク | 常時 | フォームを閉じるリンク |

## イベント仕様

### 1-Create Accountボタン押下

**トリガー**: 「Create Account」ボタンのクリック

**処理フロー**:
1. フォームデータがAJAXでPOSTリクエストとして送信される
2. `AccountsController#create` が実行される
3. バリデーションを実行
   - 取引先名: 必須、一意性（Setting.require_unique_account_names有効時）
   - カテゴリ: 設定値のいずれか
   - 評価: 0-5の範囲
   - 緯度/経度: 有効な範囲
4. バリデーション成功時:
   - Accountレコードを作成
   - コメントがある場合、コメントを追加
   - アクセス権限に応じてpermissionsレコードを作成
   - バージョン履歴を記録
   - 取引先一覧を再描画
5. バリデーション失敗時:
   - エラーメッセージを表示
   - フォームを再表示

### 2-キャンセルリンク押下

**トリガー**: 「cancel」リンクのクリック

**処理フロー**:
1. AJAXリクエストで `/accounts/new` が呼び出される（cancel=true）
2. フォームを閉じる

### 3-請求先住所と同じチェックボックス

**トリガー**: 「same as billing」チェックボックスの変更

**処理フロー**:
1. JavaScriptで請求先住所の値を配送先住所にコピー
2. 配送先住所フィールドを無効化/有効化

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 作成ボタン押下（成功時） | accounts | INSERT | 取引先レコードの作成 |
| 作成ボタン押下（成功時） | addresses | INSERT | 住所レコードの作成（0-2件） |
| 作成ボタン押下（成功時） | comments | INSERT | コメントレコードの作成（入力時のみ） |
| 作成ボタン押下（成功時） | permissions | INSERT | 権限レコードの作成（Shared時） |
| 作成ボタン押下（成功時） | taggings | INSERT | タグ関連レコードの作成（タグ入力時） |
| 作成ボタン押下（成功時） | versions | INSERT | バージョン履歴レコードの作成 |

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

#### accounts

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | user_id | current_user.id | 作成者 |
| INSERT | assigned_to | フォーム入力値 | 担当者 |
| INSERT | name | フォーム入力値 | 必須 |
| INSERT | access | フォーム入力値（デフォルト: Public） | アクセス権限 |
| INSERT | category | フォーム入力値 | カテゴリ |
| INSERT | rating | フォーム入力値（デフォルト: 0） | 評価 |
| INSERT | website | フォーム入力値 | ウェブサイト |
| INSERT | toll_free_phone | フォーム入力値 | フリーダイヤル |
| INSERT | phone | フォーム入力値 | 電話番号 |
| INSERT | fax | フォーム入力値 | FAX |
| INSERT | email | フォーム入力値 | メールアドレス |
| INSERT | background_info | フォーム入力値 | 背景情報 |
| INSERT | latitude | フォーム入力値 | 緯度 |
| INSERT | longitude | フォーム入力値 | 経度 |
| INSERT | created_at | 現在日時 | 作成日時 |
| INSERT | updated_at | 現在日時 | 更新日時 |

#### addresses

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | addressable_type | 'Account' | ポリモーフィック関連 |
| INSERT | addressable_id | 作成された取引先ID | 関連取引先 |
| INSERT | address_type | 'Billing' / 'Shipping' | 住所種別 |
| INSERT | street1 | フォーム入力値 | 住所1 |
| INSERT | street2 | フォーム入力値 | 住所2 |
| INSERT | city | フォーム入力値 | 市区町村 |
| INSERT | state | フォーム入力値 | 都道府県 |
| INSERT | zipcode | フォーム入力値 | 郵便番号 |
| INSERT | country | フォーム入力値 | 国 |

## メッセージ仕様

| メッセージID | メッセージ種別 | メッセージ内容 | 表示条件 |
|-------------|---------------|---------------|---------|
| create_account | ボタン | Create Account | 作成ボタン |
| save_account | ボタン | Save Account | 保存ボタン（編集時用） |
| missing_account_name | エラー | Please specify account name. | 取引先名未入力時 |
| share_account | エラー | Please specify users with whom to share the account. | Shared選択時にユーザー未選択 |
| intro | 案内 | You can add %{value} information later. | 各セクションの案内 |
| keep_private | ラベル | Keep it private, do not share with others | Private選択時のラベル |
| make_public | ラベル | Share it with everyone | Public選択時のラベル |
| share_with | ラベル | Share it with the following people | Shared選択時のラベル |

## 例外処理

| 例外条件 | 処理内容 | 遷移先 |
|---------|---------|--------|
| 未認証アクセス | ログイン画面にリダイレクト | ログイン画面 |
| 取引先名が未入力 | バリデーションエラー表示 | フォーム再表示 |
| 取引先名が重複（一意性設定有効時） | バリデーションエラー表示 | フォーム再表示 |
| Shared選択時にユーザー未選択 | バリデーションエラー表示 | フォーム再表示 |

## 備考

- Simple Formを使用してフォームを生成
- AJAXで非同期送信（`remote: true`）
- 二重送信防止機能あり（`one_submit_only`）
- カスタムフィールドはフィールドグループ単位で表示
- 住所入力時に「same as billing」で請求先と同じ住所を設定可能
- `Setting.compound_address` の設定により住所入力形式が変わる

---

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

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

### 推奨読解順序

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

まず、取引先作成に関わるデータ構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | account.rb | `app/models/entities/account.rb` | Accountモデルのバリデーション（76-82行目）、nested attributes（46-47行目）を確認 |
| 1-2 | schema.rb | `db/schema.rb` | accountsテーブル、addressesテーブルの構造を確認 |

**読解のコツ**: Accountモデルの76-79行目でバリデーション定義が確認できます。`validates_presence_of :name`で取引先名の必須チェック、`validates :category, inclusion: ...`でカテゴリの有効値チェックが行われます。

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

処理の起点となるコントローラーを特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | accounts_controller.rb | `app/controllers/entities/accounts_controller.rb` | newアクション（33-43行目）、createアクション（54-66行目）を確認 |
| 2-2 | routes.rb | `config/routes.rb` | 取引先作成関連のルーティングを確認 |

**主要処理フロー**:
1. **33-43行目**: `new` - 新規作成フォームの準備
2. **35行目**: デフォルト値の設定（user, access, assigned_to）
3. **54-66行目**: `create` - 取引先の作成処理
4. **57-59行目**: 作成成功時のコメント追加、一覧再取得

#### Step 3: ビューテンプレートを理解する

画面表示のロジックを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | _new.html.haml | `app/views/accounts/_new.html.haml` | 新規作成フォームのメイン構造を確認 |
| 3-2 | _top_section.html.haml | `app/views/accounts/_top_section.html.haml` | 基本情報入力セクションを確認 |
| 3-3 | _contact_info.html.haml | `app/views/accounts/_contact_info.html.haml` | 連絡先情報入力セクションを確認 |

**主要処理フロー**:
- **1行目**: `simple_form_for(@account, ..., remote: true)` - AJAXフォーム生成
- **7行目**: top_sectionパーシャル（基本情報）
- **8行目**: カスタムフィールドグループ
- **9行目**: コメント入力
- **10行目**: 連絡先情報
- **11行目**: フィールドグループ
- **12行目**: アクセス権限設定
- **15-20行目**: 作成ボタンとキャンセルリンク

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

```
ブラウザ (POST /accounts) [AJAX]
    │
    ├─ routes.rb (resources :accounts)
    │
    └─ AccountsController#create
           │
           ├─ load_and_authorize_resource
           │      └─ @account = Account.new(params[:account])
           │
           ├─ @account.save
           │      ├─ バリデーション実行
           │      ├─ before_save コールバック
           │      │      └─ nullify_blank_category
           │      └─ INSERTs (accounts, addresses, permissions, taggings)
           │
           ├─ @account.add_comment_by_user (コメント追加)
           │
           ├─ get_accounts (一覧再取得)
           │
           └─ respond_with(@account)
                   │
                   ├─ [成功] create.js.haml → 一覧再描画
                   └─ [失敗] new.js.haml → エラー表示
```

### データフロー図

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

フォーム入力値    ───▶  AccountsController#create
                            │
                            ▼
                      バリデーション
                            │
                   ┌────────┴────────┐
                   ▼                 ▼
             [成功]              [失敗]
                │                   │
                ▼                   ▼
        DBへINSERT            エラーメッセージ
        ├─ accounts               │
        ├─ addresses              ▼
        ├─ comments          フォーム再表示
        ├─ permissions
        ├─ taggings
        └─ versions
                │
                ▼
        一覧再描画
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| accounts_controller.rb | `app/controllers/entities/accounts_controller.rb` | コントローラー | 取引先作成処理の制御 |
| _new.html.haml | `app/views/accounts/_new.html.haml` | テンプレート | 新規作成フォームの表示 |
| _top_section.html.haml | `app/views/accounts/_top_section.html.haml` | テンプレート | 基本情報セクション |
| _contact_info.html.haml | `app/views/accounts/_contact_info.html.haml` | テンプレート | 連絡先情報セクション |
| _permissions.html.haml | `app/views/entities/_permissions.html.haml` | テンプレート | アクセス権限セクション |
| _add_comment.html.haml | `app/views/shared/_add_comment.html.haml` | テンプレート | コメント入力セクション |
| account.rb | `app/models/entities/account.rb` | モデル | 取引先モデル |
| routes.rb | `config/routes.rb` | 設定 | ルーティング定義 |
| fat_free_crm.en-US.yml | `config/locales/fat_free_crm.en-US.yml` | 設定 | 国際化メッセージ定義 |
