# EDI共通コンポーネント使用ガイド

## 概要

EDI機能全体で統一されたモーダルコンポーネントを提供します。全ての画面で同じデザインと操作性を実現するため、以下の共通コンポーネントを使用してください。

## 共通コンポーネント一覧

### 1. 受注詳細モーダル (`order-detail-modal.blade.php`)
- **用途**: EDI受注の詳細情報を表示
- **表示内容**: 受注ヘッダー情報、受注明細一覧、ステータス表示
- **機能**: 日付フォーマット、ステータス色分け表示

### 2. 統一商品選択モーダル (`product-selection-modal.blade.php`)
- **用途**: JANコードエラー解決時の商品選択
- **表示内容**: エラー情報、候補商品一覧、商品詳細
- **機能**: 商品選択、選択スキップ、価格フォーマット

### 3. 出荷ロット選択モーダル (`lot-selection-modal.blade.php`)
- **用途**: 食品商品の出荷時の賞味期限別在庫選択
- **表示内容**: 商品情報、ロット一覧、数量入力
- **機能**: 複数ロット選択、数量合計チェック、日付フォーマット

## 使用方法

### 基本的な使用手順

1. **共通モーダルをインクルード**
```blade
{{-- 全ての共通モーダルを一括インクルード --}}
@include('user.edi-yodobashi.components.common-modals')
```

2. **個別にインクルードする場合**
```blade
{{-- 必要なモーダルのみインクルード --}}
@include('user.edi-yodobashi.components.order-detail-modal')
@include('user.edi-yodobashi.components.product-selection-modal')
@include('user.edi-yodobashi.components.lot-selection-modal')
```

### モーダルを開く方法

#### 1. 受注詳細モーダル
```blade
<x-button.secondary @click="$refs.orderDetailModal.openModal(orderData)">
    詳細表示
</x-button.secondary>

<script>
// JavaScript側からも開けます
const orderData = {
    edi_order_number: 'PO20250130001',
    order_date: '2025-01-30',
    delivery_date: '2025-02-05',
    status: 1,
    details: [
        {
            id: 1,
            jan_code: '4901234567890',
            product_name: 'サンプル商品',
            order_qty: 10,
            shipment_qty: 8,
            status: 3
        }
    ]
};

EdiModalUtils.openOrderDetailModal(orderData);
</script>
```

#### 2. 商品選択モーダル
```blade
<x-button.primary @click="$refs.productSelectionModal.openModal(errorData, candidateProducts)">
    商品選択
</x-button.primary>

<script>
const errorData = {
    id: 1,
    jan_code: '4901234567890',
    product_name: 'サンプル商品',
    error_type: 'multiple_products'
};

const candidateProducts = [
    {
        id: 1,
        product_code: 'PROD001',
        product_name: 'サンプル商品A',
        specification: '仕様A',
        price: 1000,
        stock_quantity: 50
    },
    {
        id: 2,
        product_code: 'PROD002',
        product_name: 'サンプル商品B',
        specification: '仕様B',
        price: 1200,
        stock_quantity: 30
    }
];

EdiModalUtils.openProductSelectionModal(errorData, candidateProducts);
</script>
```

#### 3. ロット選択モーダル
```blade
<x-button.primary @click="$refs.lotSelectionModal.openModal(productData, availableLots)">
    ロット選択
</x-button.primary>

<script>
const productData = {
    id: 1,
    jan_code: '4901234567890',
    product_name: 'サンプル食品',
    shipment_qty: 10
};

const availableLots = [
    {
        id: 1,
        expiration_date: '2025-03-15',
        lot_number: 'LOT001',
        quantity: 20,
        available_quantity: 15
    },
    {
        id: 2,
        expiration_date: '2025-04-20',
        lot_number: 'LOT002',
        quantity: 30,
        available_quantity: 25
    }
];

EdiModalUtils.openLotSelectionModal(productData, availableLots);
</script>
```

### イベントハンドリング

モーダルからのイベントを受け取るには、親要素にイベントリスナーを設定します。

```blade
<div x-data="pageComponent()" 
     @product-selected="handleProductSelected($event.detail)"
     @product-selection-skipped="handleProductSelectionSkipped($event.detail)"
     @lot-selected="handleLotSelected($event.detail)">
    
    {{-- ページコンテンツ --}}
    
    {{-- 共通モーダル --}}
    @include('user.edi-yodobashi.components.common-modals')
</div>

<script>
function pageComponent() {
    return {
        // 商品選択完了時の処理
        handleProductSelected(data) {
            console.log('商品が選択されました:', data);
            // data.errorId, data.productId を使用して処理
            
            // サーバーに送信
            fetch('/edi-yodobashi/product-selection', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
                },
                body: JSON.stringify(data)
            }).then(response => response.json())
              .then(result => {
                  if (result.success) {
                      // 成功時の処理
                      location.reload();
                  }
              });
        },
        
        // 商品選択スキップ時の処理
        handleProductSelectionSkipped(data) {
            console.log('商品選択がスキップされました:', data);
            // data.errorId を使用して処理
        },
        
        // ロット選択完了時の処理
        handleLotSelected(data) {
            console.log('ロットが選択されました:', data);
            // data.productId, data.selections を使用して処理
            
            // サーバーに送信
            fetch('/edi-yodobashi/lot-selection', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
                },
                body: JSON.stringify(data)
            }).then(response => response.json())
              .then(result => {
                  if (result.success) {
                      // 成功時の処理
                      location.reload();
                  }
              });
        }
    }
}
</script>
```

## スタイリング

全てのモーダルはTailwindCSSを使用して統一されたデザインで作成されています。

### 主要なスタイルクラス
- **モーダル背景**: `fixed inset-0 z-50 overflow-y-auto`
- **モーダルコンテンツ**: `bg-white shadow-xl rounded-lg`
- **ステータス表示**: `inline-flex px-2 py-1 text-xs font-semibold rounded-full`
- **テーブル**: `min-w-full divide-y divide-gray-300`

### カスタマイズ

必要に応じて、各モーダルのスタイルをカスタマイズできます。ただし、システム全体の統一性を保つため、大幅な変更は避けてください。

## 注意事項

1. **Alpine.js必須**: 全てのモーダルはAlpine.jsに依存しています
2. **TailwindCSS必須**: スタイリングにTailwindCSSを使用しています
3. **統一性の維持**: モーダルの基本構造やスタイルを変更する際は、全体への影響を考慮してください
4. **イベント名の統一**: カスタムイベント名は変更しないでください
5. **データ形式の統一**: モーダルに渡すデータ形式は、このドキュメントの例に従ってください

## トラブルシューティング

### よくある問題

1. **モーダルが表示されない**
   - Alpine.jsが正しく読み込まれているか確認
   - `x-cloak`スタイルが設定されているか確認

2. **イベントが発火しない**
   - イベントリスナーが正しく設定されているか確認
   - `$event.detail`でデータを受け取っているか確認

3. **スタイルが適用されない**
   - TailwindCSSが正しく読み込まれているか確認
   - カスタムCSSが競合していないか確認