LaravelでCSVファイルを使った予約データのインポート処理(複数テーブル対応)

Life

この投稿では、Laravelを用いてCSVファイルからCustomerテーブルReservationテーブルに同時にデータを登録し、関連するRoomテーブルのステータス更新も行う一括インポート処理の実装方法を紹介します。

概要

  • CSVには顧客情報と予約情報を含める
  • 1レコードごとにCustomerを追加し、対応するReservationを作成
  • 予約で使用されるRoomのstatusを2に更新
  • トランザクション処理により整合性を確保

1. ルーティングの定義

// routes/web.php
Route::post('/admin/import-csv', [CsvImportController::class, 'importCsv'])->name('admin.import.csv');

2. フォームの作成(CSVアップロード画面)

<!-- resources/views/admin/import_csv.blade.php -->
<form method="POST" action="{{ route('admin.import.csv') }}" enctype="multipart/form-data">
    @csrf
    <input type="file" name="csv_file" required>
    <button type="submit" class="btn btn-primary mt-2">インポート</button>
</form>

3. コントローラーの実装

// app/Http/Controllers/Admin/CsvImportController.php

use App\Models\Customer;
use App\Models\Reservation;
use App\Models\Room;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class CsvImportController extends Controller
{
    public function importCsv(Request $request)
    {
        $request->validate([
            'csv_file' => 'required|file|mimes:csv,txt',
        ]);

        $file = $request->file('csv_file');
        $handle = fopen($file->getRealPath(), 'r');
        $header = fgetcsv($handle);

        DB::beginTransaction();

        try {
            while (($row = fgetcsv($handle)) !== false) {
                $data = array_combine($header, $row);

                $customer = Customer::create([
                    'surname_kana' => $data['surname_kana'],
                    'name_kana'    => $data['name_kana'],
                    'tel'          => $data['tel'],
                    'zipcode'      => $data['zipcode'],
                    'address'      => $data['address'],
                ]);

                $roomId = explode(' ', $data['room_id'])[0];

                Reservation::create([
                    'customer_id' => $customer->id,
                    'room_id'     => $roomId,
                    'status'      => $data['status'],
                    'plan'        => $data['plan'],
                    'plan_tanka'  => $data['plan_tanka'] ?? 0,
                ]);

                Room::where('id', $roomId)->update(['status' => 2]);
            }

            DB::commit();
            return back()->with('success', 'CSVインポートが完了しました');

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('CSVインポート失敗: '.$e->getMessage());
            return back()->with('error', 'インポート中にエラーが発生しました');
        }
    }
}

4. CSVファイルのサンプル形式

surname_kana,name_kana,tel,zipcode,address,room_id,status,plan,plan_tanka
マエガワ,ヒデタカ,09012345678,5300001,大阪市北区,105 葵,仮予約,ビジネス,8000

まとめ

  • CSVの内容をもとにCustomerとReservationを関連付けて登録
  • 対応するRoomのstatusを一括で更新
  • Laravelのトランザクション処理を活用することで、処理中の不整合も防止

今後はバリデーション強化や、既存データの上書き確認なども検討できます。

コメント

タイトルとURLをコピーしました