add automatic entry script

This commit is contained in:
2025-09-05 16:57:18 +09:00
parent 4a5f6273ed
commit 4e1ef7c230
16 changed files with 1051 additions and 0 deletions

245
TEAM_CSV_IMPORT_MANUAL.md Normal file
View File

@ -0,0 +1,245 @@
# チームCSVインポート機能 操作マニュアル
## 概要
このマニュアルは、CSVファイルからチーム登録データを一括インポートする機能の使用方法を説明します。
## 機能概要
- CSVファイルからチーム情報を一括読み込み
- ユーザー、チーム、メンバー、エントリーの自動作成
- リーダー(氏名1)の自動設定
- イベント参加登録の自動処理
- カテゴリー自動選択NewCategoryデータベース参照
- インポート結果のCSV出力
## 前提条件
### 1. Docker環境
```bash
# Dockerコンテナが起動していることを確認
docker compose ps
# 起動していない場合
docker compose up -d
```
### 2. イベント作成
インポート前に対象イベントがデータベースに存在している必要があります。
```bash
# イベント存在確認
docker compose exec app python manage.py shell -c "
from rog.models import NewEvent2
events = NewEvent2.objects.all()
for event in events:
print(f'イベントコード: {event.event_code}, 名前: {event.event_name}')
"
```
## CSVファイル形式
### 必須列
| 列名 | 説明 | 例 |
|------|------|-----|
| 部門別数 | 部門番号 | 1 |
| 時間 | 競技時間 | 3, 5 |
| 部門 | 部門名 | 一般, ファミリー |
| チーム名 | チーム名 | いなりずし |
| メール | 代表者メールアドレス | test@example.com |
| パスワード | ログインパスワード | password123 |
| 電話番号 | 代表者電話番号 | 090-1234-5678 |
| 氏名1 | 代表者氏名(リーダー) | 山田太郎 |
| 誕生日1 | 代表者誕生日 | 1990/4/15 |
### オプション列
| 列名 | 説明 |
|------|------|
| 氏名2〜氏名7 | 追加メンバー氏名 |
| 誕生日2〜誕生日7 | 追加メンバー誕生日 |
### CSVファイル例
```csv
部門別数,時間,部門,チーム名,メール,パスワード,電話番号,氏名1,誕生日1,氏名2,誕生日2,氏名3,誕生日3
1,3,一般,いなりずし,test@example.com,pass123,090-1234-5678,山田太郎,1990/4/15,山田花子,1992/8/20,田中次郎,1988/12/3
```
## 操作手順
### 1. ドライラン実行(推奨)
実際のデータ変更前に、処理内容を確認します。
```bash
docker compose exec app python manage.py import_teams \
--event_code="岐阜ロゲイニング2025" \
--csv_file="CPLIST/input/teams2025.csv" \
--dry_run
```
**出力例:**
```
[DRY RUN] 行 2: チーム=いなりずし
ユーザー既存: test@example.com パスワード:既存
エントリー: ゼッケン1, カテゴリー:一般, 時間:3時間
参加登録: 新規作成予定
メンバー: 3名 [山田太郎(1990/4/15), 山田花子(1992/8/20), 田中次郎(1988/12/3)]
```
### 2. 本実行
ドライランで問題がないことを確認後、実際のインポートを実行します。
```bash
docker compose exec app python manage.py import_teams \
--event_code="岐阜ロゲイニング2025" \
--csv_file="CPLIST/input/teams2025.csv"
```
## コマンドパラメータ
| パラメータ | 必須 | 説明 | 例 |
|-----------|------|------|-----|
| --event_code | ✓ | 対象イベントコード | "岐阜ロゲイニング2025" |
| --csv_file | ✓ | CSVファイルパス | "CPLIST/input/teams2025.csv" |
| --dry_run | - | ドライラン実行 | (パラメータのみ) |
## 処理内容詳細
### 1. ユーザー登録
- **既存ユーザー**: メールアドレスで検索し、既存の場合は再利用
- **新規ユーザー**: メール、パスワード、電話番号で新規作成
### 2. チーム登録
- **既存チーム**: 同一オーナー・同一チーム名の場合は再利用
- **新規チーム**: チーム名、オーナー、イベント情報で新規作成
### 3. メンバー登録
- **リーダー設定**: 氏名1の人を自動的にチームオーナー(リーダー)に設定
- **追加メンバー**: 氏名2〜氏名7の人をメンバーとして登録
- **ダミーユーザー**: メンバー用に自動生成されるダミーアカウント
### 4. エントリー登録
- **カテゴリー選択**: NewCategoryデータベースから最適なカテゴリーを自動選択
- **ゼッケン番号**: 自動採番(既存の最大番号+1
- **重複チェック**: 同一チーム・同一イベントの重複登録を防止
## カテゴリー自動選択ロジック
1. **完全一致**: `部門名-時間時間`(例:一般-3時間
2. **部分一致**: 部門名と時間が一致し、メンバー数条件を満たすもの
3. **新規作成**: 該当なしの場合は新規カテゴリー作成
**既存カテゴリー例:**
- 一般-3時間最大7名
- 一般-5時間最大7名
- ファミリー-3時間最大7名
- ファミリー-5時間最大7名
- 男子ソロ-3時間最大1名
- 女子ソロ-5時間最大1名
## 出力ファイル
### CSV結果ファイル
実行完了後、以下の形式でCSVファイルが出力されます
**ファイル名:** `import_results_{イベントコード}_{タイムスタンプ}.csv`
**場所:** CSVファイルと同じディレクトリ
**出力項目:**
- チーム名
- ゼッケン番号
- カテゴリー
- 時間
- オーナーメール
- リーダー(氏名と誕生日)
- メンバー数
- メンバー一覧
- 参加登録状況
- エントリーID
- 作成日時
## エラー処理
### よくあるエラー
#### 1. イベントが見つからない
```
エラー: イベントコード '存在しないイベント' が見つかりません
```
**対処法:** 正しいイベントコードを確認してください。
#### 2. CSVファイルが見つからない
```
エラー: CSVファイル 'ファイルパス' が見つかりません
```
**対処法:** ファイルパスを確認してください。
#### 3. カテゴリー制約エラー
```
エラー: このカテゴリーはソロ参加のみ可能です
```
**対処法:** メンバー数とカテゴリーの制約を確認してください。
### エラー出力例
```
エラー数: 3
行 2: メールアドレスが必要です
行 5: チーム名が必要です
行 8: このカテゴリーはソロ参加のみ可能です
```
## データ確認方法
### インポート結果確認
```bash
# エントリー確認
docker compose exec app python manage.py shell -c "
from rog.models import Entry, NewEvent2
event = NewEvent2.objects.get(event_code='岐阜ロゲイニング2025')
entries = Entry.objects.filter(event=event)
print(f'総エントリー数: {entries.count()}')
for entry in entries[:5]: # 最初の5件
print(f'ゼッケン{entry.zekken_number}: {entry.team.team_name} ({entry.category.category_name})')
"
# チーム・メンバー確認
docker compose exec app python manage.py shell -c "
from rog.models import Team, Member
teams = Team.objects.filter(event__event_code='岐阜ロゲイニング2025')
print(f'総チーム数: {teams.count()}')
for team in teams[:3]: # 最初の3チーム
members = team.members.all()
print(f'チーム: {team.team_name} (リーダー: {team.owner.firstname})')
print(f' メンバー数: {members.count()}')
for member in members:
print(f' - {member.firstname}')
"
```
## 注意事項
1. **バックアップ**: 本実行前に必ずデータベースのバックアップを取得してください
2. **重複実行**: 同じCSVファイルを複数回実行すると重複データが作成される可能性があります
3. **文字エンコーディング**: CSVファイルはUTF-8で保存してください
4. **メールアドレス**: 重複不可のため、既存ユーザーと重複しないよう注意してください
5. **カテゴリー制約**: NewCategoryの設定メンバー数制限等に従います
## トラブルシューティング
### Q: インポートが途中で止まる
A: エラーメッセージを確認し、該当行のデータを修正してください。
### Q: ゼッケン番号が重複する
A: 既存エントリーを削除してから再実行してください。
### Q: カテゴリーが正しく選択されない
A: NewCategoryデータベースの設定を確認してください。
### Q: メンバーが登録されない
A: CSVの列名が正しいか氏名、氏名確認してください。
## サポート
技術的な問題や質問がある場合は、システム開発チームまでお問い合わせください。
---
**作成日:** 2025年9月5日
**バージョン:** 1.0
**対象システム:** 岐阜ロゲイニングサーバー