diff --git a/CPLIST/input/import_results_None_20250905_162344.csv b/CPLIST/input/import_results_None_20250905_162344.csv
new file mode 100644
index 0000000..7fccfd1
--- /dev/null
+++ b/CPLIST/input/import_results_None_20250905_162344.csv
@@ -0,0 +1 @@
+チーム名,ゼッケン番号,カテゴリー,時間,オーナーメール,メンバー数,メンバー一覧,参加登録状況,エントリーID,作成日時
diff --git a/CPLIST/input/import_results_None_20250905_162613.csv b/CPLIST/input/import_results_None_20250905_162613.csv
new file mode 100644
index 0000000..7fccfd1
--- /dev/null
+++ b/CPLIST/input/import_results_None_20250905_162613.csv
@@ -0,0 +1 @@
+チーム名,ゼッケン番号,カテゴリー,時間,オーナーメール,メンバー数,メンバー一覧,参加登録状況,エントリーID,作成日時
diff --git a/CPLIST/input/import_results_None_20250905_162727.csv b/CPLIST/input/import_results_None_20250905_162727.csv
new file mode 100644
index 0000000..7fccfd1
--- /dev/null
+++ b/CPLIST/input/import_results_None_20250905_162727.csv
@@ -0,0 +1 @@
+チーム名,ゼッケン番号,カテゴリー,時間,オーナーメール,メンバー数,メンバー一覧,参加登録状況,エントリーID,作成日時
diff --git a/CPLIST/input/import_results_None_20250905_163055.csv b/CPLIST/input/import_results_None_20250905_163055.csv
new file mode 100644
index 0000000..1b8c133
--- /dev/null
+++ b/CPLIST/input/import_results_None_20250905_163055.csv
@@ -0,0 +1 @@
+チーム名,ゼッケン番号,カテゴリー,時間,オーナーメール,リーダー,メンバー数,メンバー一覧,参加登録状況,エントリーID,作成日時
diff --git a/CPLIST/input/import_results_None_20250905_164643.csv b/CPLIST/input/import_results_None_20250905_164643.csv
new file mode 100644
index 0000000..30e6d0c
--- /dev/null
+++ b/CPLIST/input/import_results_None_20250905_164643.csv
@@ -0,0 +1,25 @@
+チーム名,ゼッケン番号,カテゴリー,時間,オーナーメール,リーダー,メンバー数,メンバー一覧,参加登録状況,エントリーID,作成日時
+いなりずし,1,一般-3時間,3.0時間,いなりずし_member_1@dummy.local,児玉優美(1976-12-13),5,優美(1976-12-13); 豊久(1973-11-23); 児玉優美(1976-12-13); 児玉豊久(1973-11-23); 田中広美(1975-10-31),完了,548,2025-09-05 07:46:39
+Go to the peak!,2,一般-5時間,5.0時間,go_to_the_peak_member_1@dummy.local,柴山晋太郎(1974-12-14),3,柴山晋太郎(1974-12-14); 後藤克弘(1968-04-07); 二村修(1967-06-22),完了,549,2025-09-05 07:46:40
+きみこうじ,3,一般-3時間,3.0時間,きみこうじ_member_1@dummy.local,齋藤貴美子(1980-07-06),2,齋藤貴美子(1980-07-06); 江口浩次(1968-04-19),完了,550,2025-09-05 07:46:40
+ウエストサイド,4,一般-5時間,5.0時間,ウエストサイド_member_1@dummy.local,後藤睦子(1961-05-01),8,睦子(2000-01-01); マサトシ(2000-01-01); ショウコ(2000-01-01); ヨシミ(2000-01-01); 後藤睦子(1961-05-01); 後藤正寿(1959-07-23); 大坪照子(1958-11-11); 松村芳美(1964-04-28),完了,551,2025-09-05 07:46:40
+ベル,5,一般-3時間,3.0時間,ベル_member_1@dummy.local,川村健一(1969-10-08),7,健一(2000-01-01); ショウジ(2000-01-01); チナミ(2000-01-01); 川村健一(1969-10-08); 曽我部知奈美(1973-12-17); 伊藤徳幸(1975-02-06); 筒井勝児(1976-05-31),完了,552,2025-09-05 07:46:40
+ぐりと愉快な仲間たち,6,一般-3時間,3.0時間,ぐりと愉快な仲間たち_member_1@dummy.local,長屋香代子(1961-10-27),4,(1961-10-27); (1961-05-26); 長屋香代子(1961-10-27); 長屋宣宏(1961-05-26),完了,553,2025-09-05 07:46:40
+坂本555,7,一般-5時間,5.0時間,坂本555_member_1@dummy.local,坂本正憲(1972-05-30),3,坂本正憲(1972-05-30); 坂本彩子(1976-03-29); 坂本瑠璃子(2003-08-23),完了,554,2025-09-05 07:46:40
+M sisters with D,8,一般-5時間,5.0時間,m__sisters_with__d_member_1@dummy.local,前田貴代美(1973-01-15),2,前田貴代美(1973-01-15); 中濱智恵美(1969-06-16),完了,555,2025-09-05 07:46:41
+さなっく,9,一般-5時間,5.0時間,さなっく_member_1@dummy.local,山田朋博(1971-04-23),2,山田朋博(1971-04-23); 眞田尚亮(1982-11-30),完了,556,2025-09-05 07:46:41
+煮込みラーメン,10,一般-3時間,3.0時間,煮込みラーメン_member_1@dummy.local,西岡嵩倫(1999-01-05),4,(1999-01-05); (1971-02-02); 西岡嵩倫(1999-01-05); 西岡影忠(1971-02-02),完了,557,2025-09-05 07:46:41
+サウナとビリヤニ,11,一般-3時間,3.0時間,サウナとビリヤニ_member_1@dummy.local,坂口祐生(1992-01-07),3,坂口祐生(1992-01-07); 近藤準(1987-01-25); 圓山大貴(1993-05-10),完了,558,2025-09-05 07:46:41
+ひろ君と愉快な仲間たち,12,お試し・一般-3時間,3.0時間,ひろ君と愉快な仲間たち_member_1@dummy.local,山脇裕子(1984-01-26),5,山脇裕子(1984-01-26); 高橋美智子(1975-04-21); 樋口博久(1964-01-08); 雨宮功治(1962-05-25); 広瀬貴士(1978-08-17),完了,559,2025-09-05 07:46:41
+山下和乃,13,女性ソロ-3時間,3.0時間,山下和乃_member_1@dummy.local,山下和乃(2004-04-26),1,山下和乃(2004-04-26),完了,560,2025-09-05 07:46:42
+Best Wishes,14,女性ソロ-5時間,5.0時間,best_wishes_member_1@dummy.local,長谷川美貴(1973-05-06),2,美貴(1973-05-06); 長谷川美貴(1973-05-06),完了,561,2025-09-05 07:46:42
+しーくん,15,男性ソロ-3時間,3.0時間,しーくん_member_1@dummy.local,水門茂(1962-12-24),2,茂(1962-12-24); 水門茂(1962-12-24),完了,562,2025-09-05 07:46:42
+風呂の会,16,男性ソロ-5時間,5.0時間,風呂の会_member_1@dummy.local,浅井貴弘(1984-07-11),2,貴弘(2000-01-01); 浅井貴弘(1984-07-11),完了,563,2025-09-05 07:46:42
+近藤隆,17,男性ソロ-5時間,5.0時間,近藤隆_member_1@dummy.local,近藤隆(1962-06-28),1,近藤隆(1962-06-28),完了,564,2025-09-05 07:46:42
+日吉将大,18,男性ソロ-3時間,3.0時間,日吉将大_member_1@dummy.local,日吉将大(1995-09-14),2,(1995-09-14); 日吉将大(1995-09-14),完了,565,2025-09-05 07:46:42
+東京OLクラブ,19,男性ソロ-3時間,3.0時間,東京olクラブ_member_1@dummy.local,阿部昌隆(1956-04-20),1,阿部昌隆(1956-04-20),完了,566,2025-09-05 07:46:42
+Best Wishes,20,男性ソロ-5時間,5.0時間,best_wishes_member_1@dummy.local,長谷川美貴(1973-05-06),2,寿郎(1973-10-26); 長谷川美貴(1973-05-06),完了,567,2025-09-05 07:46:42
+脇屋貴司,21,男性ソロ-5時間,5.0時間,脇屋貴司_member_1@dummy.local,脇屋貴司(1983-10-26),1,脇屋貴司(1983-10-26),完了,568,2025-09-05 07:46:42
+うぱうぱアイランド,22,ファミリー-3時間,3.0時間,うぱうぱアイランド_member_1@dummy.local,伊藤由美子(1992-03-28),3,伊藤由美子(1992-03-28); 伊藤嘉仁(1993-08-25); 伊藤嘉利(2022-09-13),完了,569,2025-09-05 07:46:42
+Team117,23,ファミリー-3時間,3.0時間,team117_member_1@dummy.local,佐々木孝好(1970-12-20),4,佐々木孝好(1970-12-20); 佐々木享子(1977-08-25); 佐々木実希(2012-01-21); 佐々木麻妃(2016-07-01),完了,570,2025-09-05 07:46:43
+チームしぇいや,24,ファミリー-3時間,3.0時間,チームしぇいや_member_1@dummy.local,山本龍也(1976-03-14),6,聖也(2009-09-09); 輝也(2015-06-03); 龍也(1976-03-14); 山本龍也(1976-03-14); 山本聖也(2009-09-09); 山本輝也(2015-06-03),完了,571,2025-09-05 07:46:43
diff --git a/CPLIST/input/import_results_None_20250905_165633.csv b/CPLIST/input/import_results_None_20250905_165633.csv
new file mode 100644
index 0000000..d76d201
--- /dev/null
+++ b/CPLIST/input/import_results_None_20250905_165633.csv
@@ -0,0 +1,28 @@
+チーム名,ゼッケン番号,カテゴリー,時間,オーナーメール,リーダー,メンバー数,メンバー一覧,参加登録状況,エントリーID,作成日時
+いなりずし,1,一般-3時間,3.0時間,いなりずし_member_1@dummy.local,児玉優美(1976-12-13),5,優美(1976-12-13); 豊久(1973-11-23); 児玉優美(1976-12-13); 児玉豊久(1973-11-23); 田中広美(1975-10-31),完了,548,2025-09-05 07:46:39
+Go to the peak!,2,一般-5時間,5.0時間,go_to_the_peak_member_1@dummy.local,柴山晋太郎(1974-12-14),3,柴山晋太郎(1974-12-14); 後藤克弘(1968-04-07); 二村修(1967-06-22),完了,549,2025-09-05 07:46:40
+きみこうじ,3,一般-3時間,3.0時間,きみこうじ_member_1@dummy.local,齋藤貴美子(1980-07-06),2,齋藤貴美子(1980-07-06); 江口浩次(1968-04-19),完了,550,2025-09-05 07:46:40
+ウエストサイド,4,一般-5時間,5.0時間,ウエストサイド_member_1@dummy.local,後藤睦子(1961-05-01),8,睦子(2000-01-01); マサトシ(2000-01-01); ショウコ(2000-01-01); ヨシミ(2000-01-01); 後藤睦子(1961-05-01); 後藤正寿(1959-07-23); 大坪照子(1958-11-11); 松村芳美(1964-04-28),完了,551,2025-09-05 07:46:40
+ベル,5,一般-3時間,3.0時間,ベル_member_1@dummy.local,川村健一(1969-10-08),7,健一(2000-01-01); ショウジ(2000-01-01); チナミ(2000-01-01); 川村健一(1969-10-08); 曽我部知奈美(1973-12-17); 伊藤徳幸(1975-02-06); 筒井勝児(1976-05-31),完了,552,2025-09-05 07:46:40
+ぐりと愉快な仲間たち,6,一般-3時間,3.0時間,ぐりと愉快な仲間たち_member_1@dummy.local,長屋香代子(1961-10-27),4,(1961-10-27); (1961-05-26); 長屋香代子(1961-10-27); 長屋宣宏(1961-05-26),完了,553,2025-09-05 07:46:40
+坂本555,7,一般-5時間,5.0時間,坂本555_member_1@dummy.local,坂本正憲(1972-05-30),3,坂本正憲(1972-05-30); 坂本彩子(1976-03-29); 坂本瑠璃子(2003-08-23),完了,554,2025-09-05 07:46:40
+M sisters with D,8,一般-5時間,5.0時間,m__sisters_with__d_member_1@dummy.local,前田貴代美(1973-01-15),2,前田貴代美(1973-01-15); 中濱智恵美(1969-06-16),完了,555,2025-09-05 07:46:41
+さなっく,9,一般-5時間,5.0時間,さなっく_member_1@dummy.local,山田朋博(1971-04-23),2,山田朋博(1971-04-23); 眞田尚亮(1982-11-30),完了,556,2025-09-05 07:46:41
+煮込みラーメン,10,一般-3時間,3.0時間,煮込みラーメン_member_1@dummy.local,西岡嵩倫(1999-01-05),4,(1999-01-05); (1971-02-02); 西岡嵩倫(1999-01-05); 西岡影忠(1971-02-02),完了,557,2025-09-05 07:46:41
+サウナとビリヤニ,11,一般-3時間,3.0時間,サウナとビリヤニ_member_1@dummy.local,坂口祐生(1992-01-07),3,坂口祐生(1992-01-07); 近藤準(1987-01-25); 圓山大貴(1993-05-10),完了,558,2025-09-05 07:46:41
+ひろ君と愉快な仲間たち,12,お試し・一般-3時間,3.0時間,ひろ君と愉快な仲間たち_member_1@dummy.local,山脇裕子(1984-01-26),5,山脇裕子(1984-01-26); 高橋美智子(1975-04-21); 樋口博久(1964-01-08); 雨宮功治(1962-05-25); 広瀬貴士(1978-08-17),完了,559,2025-09-05 07:46:41
+山下和乃,13,女性ソロ-3時間,3.0時間,山下和乃_member_1@dummy.local,山下和乃(2004-04-26),1,山下和乃(2004-04-26),完了,560,2025-09-05 07:46:42
+Best Wishes,14,女性ソロ-5時間,5.0時間,best_wishes_member_1@dummy.local,長谷川美貴(1973-05-06),2,美貴(1973-05-06); 長谷川美貴(1973-05-06),完了,561,2025-09-05 07:46:42
+しーくん,15,男性ソロ-3時間,3.0時間,しーくん_member_1@dummy.local,水門茂(1962-12-24),2,茂(1962-12-24); 水門茂(1962-12-24),完了,562,2025-09-05 07:46:42
+風呂の会,16,男性ソロ-5時間,5.0時間,風呂の会_member_1@dummy.local,浅井貴弘(1984-07-11),2,貴弘(2000-01-01); 浅井貴弘(1984-07-11),完了,563,2025-09-05 07:46:42
+近藤隆,17,男性ソロ-5時間,5.0時間,近藤隆_member_1@dummy.local,近藤隆(1962-06-28),1,近藤隆(1962-06-28),完了,564,2025-09-05 07:46:42
+日吉将大,18,男性ソロ-3時間,3.0時間,日吉将大_member_1@dummy.local,日吉将大(1995-09-14),2,(1995-09-14); 日吉将大(1995-09-14),完了,565,2025-09-05 07:46:42
+東京OLクラブ,19,男性ソロ-3時間,3.0時間,東京olクラブ_member_1@dummy.local,阿部昌隆(1956-04-20),1,阿部昌隆(1956-04-20),完了,566,2025-09-05 07:46:42
+Best Wishes,20,男性ソロ-5時間,5.0時間,best_wishes_member_1@dummy.local,長谷川美貴(1973-05-06),2,寿郎(1973-10-26); 長谷川美貴(1973-05-06),完了,567,2025-09-05 07:46:42
+脇屋貴司,21,男性ソロ-5時間,5.0時間,脇屋貴司_member_1@dummy.local,脇屋貴司(1983-10-26),1,脇屋貴司(1983-10-26),完了,568,2025-09-05 07:46:42
+うぱうぱアイランド,22,ファミリー-3時間,3.0時間,うぱうぱアイランド_member_1@dummy.local,伊藤由美子(1992-03-28),3,伊藤由美子(1992-03-28); 伊藤嘉仁(1993-08-25); 伊藤嘉利(2022-09-13),完了,569,2025-09-05 07:46:42
+Team117,23,ファミリー-3時間,3.0時間,team117_member_1@dummy.local,佐々木孝好(1970-12-20),4,佐々木孝好(1970-12-20); 佐々木享子(1977-08-25); 佐々木実希(2012-01-21); 佐々木麻妃(2016-07-01),完了,570,2025-09-05 07:46:43
+チームしぇいや,24,ファミリー-3時間,3.0時間,チームしぇいや_member_1@dummy.local,山本龍也(1976-03-14),6,聖也(2009-09-09); 輝也(2015-06-03); 龍也(1976-03-14); 山本龍也(1976-03-14); 山本聖也(2009-09-09); 山本輝也(2015-06-03),完了,571,2025-09-05 07:46:43
+まゆちー,25,お試し-3時間,3.0時間,まゆちー_member_1@dummy.local,浅田舞子(1986-02-22),4,浅田舞子(1986-02-22); 浅田真結菜(2014-03-30); 森美紀(1988-03-06); 森千晴(2017-08-04),完了,572,2025-09-05 07:56:33
+ガンバルゾー,26,お試し-3時間,3.0時間,ガンバルゾー_member_1@dummy.local,森祐貴(1985-09-26),4,森祐貴(1985-09-26); 浅田直之(1987-12-12); 浅田晃汰(2014-01-06); 森光喜(2015-04-22),完了,573,2025-09-05 07:56:33
+ランエンジョン!,27,お試し-5時間,5.0時間,ランエンジョン!_member_1@dummy.local,河合賢次(1972-12-14),2,河合賢次(1972-12-14); 中野真樹(1973-01-23),完了,574,2025-09-05 07:56:33
diff --git a/CPLIST/input/teams2025.csv b/CPLIST/input/teams2025.csv
new file mode 100644
index 0000000..08cc2f2
--- /dev/null
+++ b/CPLIST/input/teams2025.csv
@@ -0,0 +1,53 @@
+部門別数,時間,部門,チーム名,メール,パスワード,電話番号,氏名1,誕生日1,氏名2,誕生日2,氏名3,誕生日3,氏名4,誕生日4,氏名5,誕生日5,氏名6,誕生日6,氏名7,誕生日7,,
+1,3,一般,いなりずし,takuyuna1123@icloud.com,ko1703,09014701703,児玉優美,1976/12/13,児玉豊久,1973/11/23,田中広美,1975/10/31,,,,,,,,,,
+1,5,一般,Go to the peak!,shibashintan@c.vodafone.ne.jp,shi0145,090-8499-0145,柴山晋太郎,1974/12/14,後藤克弘,1968/04/07,二村修,1967/06/22,,,,,,,,,,
+2,3,一般,きみこうじ,chibi-kimi.706@ezweb.ne.jp,sa8309,09062518309,齋藤貴美子,1980/07/06,江口浩次,1968/04/19,,,,,,,,,,,,
+2,5,一般,ウエストサイド,chikachan-5101414@i.softbank.jp,go7471,09047997471,後藤睦子,1961/5/1,後藤正寿,1959/7/23,大坪照子,1958/11/11,松村芳美,1964/4/28,,,,,,,,
+3,3,一般,ベル,kekomura1008@yahoo.co.jp,ka3001,090-3564-3001,川村健一,1969/10/08,曽我部知奈美,1973/12/17,伊藤徳幸,1975/02/06 ,筒井勝児,1976/05/31,,,,,,,,
+3,5,一般,ランエンジョン!,baycools16@gmail.com,ka9749,090÷4790÷9749,河合賢次,1972/12/14,中野真樹,1973/01/23,,,,,,,,,,,,
+4,3,一般,ぐりと愉快な仲間たち,kayochu.v.mame.526@icloud.com,na6547,090-1564-6547,長屋香代子,1961/10/27,長屋宣宏,1961/5/26,,,,,,,,,,,,
+4,5,一般,坂本555,sakamoto180909@yahoo.co.jp,sa4396,090-8480-4396,坂本正憲,1972/5/30,坂本彩子,1976/3/29,坂本瑠璃子,2003/8/23,,,,,,,,,,
+5,3,一般,リキとりんごてぃー,apple1977tea@yahoo.co.jp,te1499,08051241499,鄭寛子,1977/6/13,鄭昌彦,1971/5/26,,,,,,,,,,,,
+5,5,一般,East Field,ryo1hi@outlook.com,hi0504,070-8564-0504,東野遼一,1983/09/27,東野智子,1977/03/16,,,,,,,,,,,,
+6,3,一般,としちんかずちん,kazu-chin1998@docomo.ne.jp,shi9127,080-2616-9127,渋谷和広,1970/8/1,渋谷敏江,1956/6/16,,,,,,,,,,,,
+6,5,一般,M sisters with D,m.kiyomi.115@gmail.com,ma3731,090-4869-3731,前田貴代美,1973/01/15,中濱智恵美,1969/06/16,,,,,,,,,,,,
+7,3,一般,シマエナガ,c6d6.lpbm5-s@ezweb.ne.jp,shi1925,090-6336-1925,神谷孫斗,1997/03/02,小栗彩瑚,2001/9/21,,,,,,,,,,,,
+7,5,一般,さなっく,santa04230722@icloud.com,ya7192,070-5640-7192,山田朋博,1971/04/23,眞田尚亮,1982/11/30,,,,,,,,,,,,
+8,3,一般,煮込みラーメン,t.nishioka1575tt@gmail.com,ni9354,080-8523-9354,西岡嵩倫,1999/1/5,西岡影忠,1971/2/2,,,,,,,,,,,,
+9,3,一般,そうたとなゆ,hmt.sota@gmail.com,ho6594,090-1109-6594,甫本創太,1991/06/07,後藤菜友,1994/02/22,,,,,,,,,,,,
+10,3,一般,KOJ,balccitomatochop@gmail.com,to5670,090-2181-5670,轟原功樹,1978/08/10,田中美樹,1978/09/07,,,,,,,,,,,,
+11,3,一般,サウナとビリヤニ,bitter_smile107@yahoo.co.jp,sa9007,090-4760-9007,坂口祐生,1992/1/7,近藤準,1987/1/25,圓山大貴,1993/5/10,,,,,,,,,,
+1,3,お試し・一般,ひろ君と愉快な仲間たち,y0126k@yahoo.co.jp,ya7467,090-9902-7467,山脇裕子,1984/1/26,高橋美智子,1975/04/21,樋口博久,1964/01/08,雨宮功治,1962/05/25,広瀬貴士,1978/08/17,,,,,,
+2,3,お試し・一般,フクニシ,appleorange100pct@yahoo.co.jp,fu2792,080-6954-2792,福西直之,1986/2/5,福西愛,1986/3/2,,,,,,,,,,,,
+3,3,お試し・一般,あやみち,h613-y5m9t-mich@ezweb.ne.jp,ya3144,090-4447-3144,谷許文音,2006/07/26,谷許美千代,1976/03/27,,,,,,,,,,,,
+1,3,お試し・男性ソロ,松村覚司,happy.dreams.come.true923@gmail.com,ma3625,090-8186-3625,松村覚司,1967/9/23,,,,,,,,,,,,,,
+2,3,お試し・男性ソロ,高野清司,wakano_528@yahoo.co.jp,ta5865,090-5603-5865,高野清司,71歳,,,,,,,,,,,,,,
+1,3,お試し・ファミリー,まゆちー,takoyaki_sena@icloud.com,a1246,090-6090-1246,浅田舞子,1986/02/22,浅田真結菜,2014/03/30,森美紀,1988/03/06,森千晴,2017/8/4,,,,,,,,
+1,5,お試し・ファミリー,ポエドリ,takagitoshihiro8@yahoo.co.jp,ta4245,090-5866-4245,高木俊裕,1984/03/09,,,,,,,,,,,,,,
+2,3,お試し・ファミリー,ガンバルゾー,youkeymr.01@gmail.com,mo6605,090-6080-6605,森祐貴,1985/9/26,浅田直之,1987/12/12,浅田晃汰,2014/01/06,森光喜,2015/4/22,,,,,,,,
+2,5,お試し・ファミリー,fun!fun!うごchan,fulayota333@gmail.com,ha7384,090-6599-7384,早川宏美,1975/6/15,,,,,,,,,,,,,,
+3,3,お試し・ファミリー,チームT,sphin28420@aim.com,te1882,080-6709-1882,寺田剛,1979/06/04,寺田恭子,1985/01/10,寺田向希,2023/11/08,,,,,,,,,,
+1,3,女性ソロ,山下和乃,kazjamster@gmail.com,ya2450,090-4229-2450,山下和乃,2004/4/26,,,,,,,,,,,,,,
+1,5,女性ソロ,Best Wishes,thunderhead_56@yahoo.co.jp,ha7226,090-5652-7226,長谷川美貴,1973/5/6,,,,,,,,,,,,,,
+1,3,男性ソロ,しーくん,redleif57917913@ezweb.ne.jp,mi6827,090-2946-6827,水門茂,1962/12/24,,,,,,,,,,,,,,
+1,5,男性ソロ,風呂の会,1845dondon@gmail.com,a9050,09096369050,浅井貴弘,1984/07/11,,,,,,,,,,,,,,
+2,3,男性ソロ,野田達男,tatchi.sat111@docomo.ne.jp,no0873,0901417-0873,野田達男,1950/9/14,,,,,,,,,,,,,,
+2,5,男性ソロ,近藤隆,kondo2000gt@yahoo.ne.jp,ko0666,09018300666,近藤隆,1962/6/28,,,,,,,,,,,,,,
+3,3,男性ソロ,日吉将大,hiyomasa0034@gmail.com,hi6343,080-2733-6343,日吉将大,1995/09/14,,,,,,,,,,,,,,
+3,5,男性ソロ,松野昌紀,matsubottkuri11994730@gmail.com,ma2606,090-1272-2606,松野昌紀,1972/9/30,,,,,,,,,,,,,,
+4,3,男性ソロ,東京OLクラブ,abe_1755_31@yahoo.co.jp,a7102,090-2203-7102,阿部昌隆,1956/4/20,,,,,,,,,,,,,,
+4,5,男性ソロ,白木稔人,amida48gan@icloud.com,shi6048,090-7302-6048,白木稔人,1972/5/17,,,,,,,,,,,,,,
+5,3,男性ソロ,大阪OLC,t.okiura1961@gmail.com,o1141,090-7888-1141,沖浦徹二,1961/4/29,,,,,,,,,,,,,,
+5,5,男性ソロ,Best Wishes,jovi_bounce14@yahoo.co.jp,ko0716,090−3284−0716,小林寿郎,1973/10/26,,,,,,,,,,,,,,
+6,3,男性ソロ,つるまいOLC,junhagi68@gmail.com,ha1001,080-3159-1001,萩原淳,1968/3/17,,,,,,,,,,,,,,
+6,5,男性ソロ,脇屋貴司,takarinkuririn@gmail.com,wa2659,080-3508-2659,脇屋貴司,1983/10/26,,,,,,,,,,,,,,
+7,3,男性ソロ,㈱大垣ケーブルテレビ,so-kishida@ogaki-tv.co.jp,ki1207,0584-82-1207,岸田爽,2001/8/12,,,,,,,,,,,,,,
+7,5,男性ソロ,前川一彦,yoshino-chuo@docomo.ne.jp,ma2351,090-1074-2351,前川一彦,不明,,,,,,,,,,,,,,
+8,3,男性ソロ,㈱大垣ケーブルテレビ,ta-shiba@ogaki-tv.co.jp,shi1207,,芝建,1998/11/9,,,,,,,,,,,,,,
+1,3,ファミリー,うぱうぱアイランド,serukasu@gmail.com,i4200,09084584200,伊藤由美子,19920328,伊藤嘉仁,19930825,伊藤嘉利,20220913,,,,,,,,,,
+1,5,ファミリー,ながれぼし,h2798723ddwyus@i.softbank.jp,ta8317,090-1782-8317,高田めぐみ,1982/4/28,高田志穂,2013/12/5,,,,,,,,,,,,
+2,3,ファミリー,Team117,miki.maki0107@gmail.com,sa3915,090-7678-3915,佐々木孝好,1970/12/20,佐々木享子,1977/8/25,佐々木実希,2012/1/21,佐々木麻妃,2016/7/1,,,,,,,,
+2,5,ファミリー,500えん,roumnet@yahoo.co.jp,go6814,090-9890-6814,五百木弘道,1972/4/29,五百木芽彩,2015/3/13,,,,,,,,,,,,
+3,3,ファミリー,チームしぇいや,rayrain3000@docomo.ne.jp,ya2905,090-3056-2905,山本龍也,1976/3/14,山本聖也,2009/9/9,山本輝也,2015/6/3,,,,,,,,,,
+3,5,ファミリー,チームユズ,livertish_v.g.35@docomo.ne.jp,ko7822,090-7311-7822,小出龍,1983/2/27,小出柚希,2019/1/7,,,,,,,,,,,,
+4,3,ファミリー,Y'sファミリー,inukisen@gmail.com,ya1285,09042581285,安田千穂,1984/3/7,安田尚広,1978/1/18,安田雫,2014/9/2,安田葵,2018/5/13,,,,,,,,
\ No newline at end of file
diff --git a/CPLIST/input/teams2025_test.csv b/CPLIST/input/teams2025_test.csv
new file mode 100644
index 0000000..a8f64bf
--- /dev/null
+++ b/CPLIST/input/teams2025_test.csv
@@ -0,0 +1,4 @@
+部門別数,時間,部門,チーム名,メール,パスワード,電話番号,氏名1,誕生日1,氏名2,誕生日2,氏名3,誕生日3,氏名4,誕生日4,氏名5,誕生日5,氏名6,誕生日6,氏名7,誕生日7,,
+1,3,一般,いなりずし,takuyuna1123@icloud.com,ko1703,09014701703,児玉優美,1976/12/13,児玉豊久,1973/11/23,田中広美,1975/10/31,,,,,,,,,,
+1,5,一般,Go to the peak!,shibashintan@c.vodafone.ne.jp,shi0145,090-8499-0145,柴山晋太郎,1974/12/14,後藤克弘,1968/04/07,二村修,1967/06/22,,,,,,,,,,
+2,3,一般,きみこうじ,chibi-kimi.706@ezweb.ne.jp,sa8309,09062518309,齋藤貴美子,1980/07/06,江口浩次,1968/04/19,,,,,,,,,,,,
diff --git a/CPLIST/input/test_trial.csv b/CPLIST/input/test_trial.csv
new file mode 100644
index 0000000..cdbe814
--- /dev/null
+++ b/CPLIST/input/test_trial.csv
@@ -0,0 +1,4 @@
+部門別数,時間,部門,チーム名,メール,パスワード,電話番号,氏名1,誕生日1,氏名2,誕生日2,氏名3,誕生日3,氏名4,誕生日4,氏名5,誕生日5,氏名6,誕生日6,氏名7,誕生日7,,
+3,3,お試し・ファミリー,まゆちー,takoyaki_sena@icloud.com,ma0222,090-3309-0222,浅田舞子,1986/02/22,浅田真結菜,2014/03/30,森美紀,1988/03/06,森千晴,2017/8/4,,,,,,,,
+4,3,お試し・ファミリー,ガンバルゾー,youkeymr.01@gmail.com,mo3540,090-8962-3540,森祐貴,1985/9/26,浅田直之,1987/12/12,浅田晃汰,2014/01/06,森光喜,2015/4/22,,,,,,,,
+7,5,お試し,ランエンジョン!,baycools16@gmail.com,ka9749,090÷4790÷9749,河合賢次,1972/12/14,中野真樹,1973/01/23,,,,,,,,,,,,
diff --git a/TEAM_CSV_IMPORT_MANUAL.md b/TEAM_CSV_IMPORT_MANUAL.md
new file mode 100644
index 0000000..ab2bb3f
--- /dev/null
+++ b/TEAM_CSV_IMPORT_MANUAL.md
@@ -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の列名が正しいか(氏名1、氏名2等)確認してください。
+
+## サポート
+
+技術的な問題や質問がある場合は、システム開発チームまでお問い合わせください。
+
+---
+**作成日:** 2025年9月5日
+**バージョン:** 1.0
+**対象システム:** 岐阜ロゲイニングサーバー
diff --git a/rog/management/__init__.py b/rog/management/__init__.py
new file mode 100644
index 0000000..6385696
--- /dev/null
+++ b/rog/management/__init__.py
@@ -0,0 +1 @@
+# Django management module
diff --git a/rog/management/commands/__init__.py b/rog/management/commands/__init__.py
new file mode 100644
index 0000000..702fa7c
--- /dev/null
+++ b/rog/management/commands/__init__.py
@@ -0,0 +1 @@
+# Django management commands module
diff --git a/rog/management/commands/import_teams.py b/rog/management/commands/import_teams.py
new file mode 100644
index 0000000..df70c52
--- /dev/null
+++ b/rog/management/commands/import_teams.py
@@ -0,0 +1,548 @@
+"""
+CSVファイルからチームエントリーをインポートするDjango管理コマンド
+CPLIST/input/teams2025.csv 本番用対応
+
+Usage:
+ docker compose exec app python manage.py import_teams --event_code=岐阜ロゲイニング2025 --csv_file=CPLIST/input/teams2025.csv
+
+Author: システム開発チーム
+Date: 2025-09-05
+"""
+
+import csv
+import os
+import logging
+import re
+from datetime import datetime, timedelta
+from django.core.management.base import BaseCommand, CommandError
+from django.db import transaction, models
+from django.contrib.auth.hashers import make_password
+from django.utils import timezone
+from django.core.exceptions import ValidationError
+
+from rog.models import (
+ CustomUser, Team, Member, Entry, NewEvent2, NewCategory
+)
+
+logger = logging.getLogger(__name__)
+
+
+class Command(BaseCommand):
+ help = 'CSVファイルからチームエントリーをインポート'
+
+ def add_arguments(self, parser):
+ parser.add_argument(
+ '--event_code',
+ type=str,
+ required=True,
+ help='インポート先のイベントコード'
+ )
+ parser.add_argument(
+ '--csv_file',
+ type=str,
+ default='CPLIST/input/teams2025.csv',
+ help='インポートするCSVファイルのパス (default: CPLIST/input/teams2025.csv)'
+ )
+ parser.add_argument(
+ '--dry_run',
+ action='store_true',
+ help='実際にはデータベースに書き込まずに処理を確認'
+ )
+
+ def handle(self, *args, **options):
+ event_code = options['event_code']
+ csv_file = options['csv_file']
+ dry_run = options['dry_run']
+
+ self.stdout.write(
+ self.style.SUCCESS(f'CSVインポート開始: event_code={event_code}, csv_file={csv_file}, dry_run={dry_run}')
+ )
+
+ # イベントの存在確認
+ try:
+ event = NewEvent2.objects.get(event_name=event_code)
+ self.stdout.write(f'イベント見つかりました: {event.event_name} (ID: {event.id})')
+ except NewEvent2.DoesNotExist:
+ raise CommandError(f'イベントが見つかりません: {event_code}')
+
+ # CSVファイルの存在確認
+ if not os.path.exists(csv_file):
+ raise CommandError(f'CSVファイルが見つかりません: {csv_file}')
+
+ # 統計情報
+ stats = {
+ 'total_rows': 0,
+ 'users_created': 0,
+ 'users_existing': 0,
+ 'teams_created': 0,
+ 'members_created': 0,
+ 'entries_created': 0,
+ 'errors': []
+ }
+
+ try:
+ with open(csv_file, 'r', encoding='utf-8-sig') as f: # BOM対応のためutf-8-sigを使用
+ reader = csv.DictReader(f)
+
+ for row_num, row in enumerate(reader, start=2): # ヘッダー行の次から開始
+ stats['total_rows'] += 1
+
+ try:
+ if dry_run:
+ self.process_row_dry_run(row, event, stats, row_num)
+ else:
+ with transaction.atomic():
+ self.process_row(row, event, stats, row_num)
+ except Exception as e:
+ error_msg = f'行 {row_num}: {str(e)}'
+ stats['errors'].append(error_msg)
+ self.stdout.write(self.style.ERROR(error_msg))
+ continue
+
+ except Exception as e:
+ raise CommandError(f'CSVファイル読み込みエラー: {str(e)}')
+
+ # 結果レポート
+ self.print_stats(stats, dry_run)
+
+ # CSV出力
+ if not dry_run:
+ self.export_results_to_csv(event, options['csv_file'])
+
+ def export_results_to_csv(self, event, input_csv_file):
+ """インポート結果をCSVファイルに出力"""
+ # 出力ファイル名を生成
+ input_dir = os.path.dirname(input_csv_file)
+ timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
+ output_file = os.path.join(input_dir, f'import_results_{event.event_code}_{timestamp}.csv')
+
+ try:
+ with open(output_file, 'w', newline='', encoding='utf-8-sig') as csvfile:
+ fieldnames = [
+ 'チーム名', 'ゼッケン番号', 'カテゴリー', '時間',
+ 'オーナーメール', 'リーダー', 'メンバー数', 'メンバー一覧',
+ '参加登録状況', 'エントリーID', '作成日時'
+ ]
+ writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
+ writer.writeheader()
+
+ # イベントのエントリーを取得
+ entries = Entry.objects.filter(event=event).select_related(
+ 'team', 'category', 'owner'
+ ).prefetch_related('team__members__user')
+
+ for entry in entries:
+ # メンバー一覧を作成
+ member_list = []
+ for member in entry.team.members.all():
+ member_info = f"{member.user.firstname}"
+ if member.user.date_of_birth:
+ member_info += f"({member.user.date_of_birth})"
+ member_list.append(member_info)
+
+ # リーダー情報を取得(チームオーナー)
+ leader_name = ""
+ if entry.team.owner:
+ leader_name = f"{entry.team.owner.firstname}"
+ if entry.team.owner.date_of_birth:
+ leader_name += f"({entry.team.owner.date_of_birth})"
+
+ writer.writerow({
+ 'チーム名': entry.team.team_name,
+ 'ゼッケン番号': entry.zekken_number,
+ 'カテゴリー': entry.category.category_name if entry.category else '',
+ '時間': f"{entry.category.duration.total_seconds() // 3600}時間" if entry.category else '',
+ 'オーナーメール': entry.owner.email,
+ 'リーダー': leader_name,
+ 'メンバー数': entry.team.members.count(),
+ 'メンバー一覧': '; '.join(member_list),
+ '参加登録状況': '完了',
+ 'エントリーID': entry.id,
+ '作成日時': entry.date.strftime('%Y-%m-%d %H:%M:%S')
+ })
+
+ self.stdout.write(
+ self.style.SUCCESS(f'インポート結果をCSVに出力しました: {output_file}')
+ )
+
+ except Exception as e:
+ self.stdout.write(
+ self.style.ERROR(f'CSV出力エラー: {str(e)}')
+ )
+
+ def process_row(self, row, event, stats, row_num):
+ """CSVの1行を処理(実際にデータベースに書き込み)"""
+ team_name = row.get('チーム名', '').strip()
+ self.stdout.write(f'行 {row_num} 処理中: チーム={team_name}')
+
+ # 2-1. カスタムユーザー登録
+ user = self.get_or_create_user(row, stats)
+
+ # 2-2. チーム登録
+ team = self.create_team(row, user, event, stats)
+
+ # メンバー登録(最大7名)
+ members = self.create_members(row, team, stats)
+
+ # 2-3. エントリー登録
+ entry = self.create_entry(row, team, event, stats)
+
+ self.stdout.write(self.style.SUCCESS(f'行 {row_num} 完了: チーム={team.team_name}'))
+
+ def process_row_dry_run(self, row, event, stats, row_num):
+ """CSVの1行を処理(ドライラン - データベースには書き込まない)"""
+ team_name = row.get('チーム名', '').strip()
+ self.stdout.write(f'[DRY RUN] 行 {row_num}: チーム={team_name}')
+
+ # ユーザーの存在確認のみ
+ email = row.get('メール', '').strip()
+ password = row.get('パスワード', '').strip()
+ if email:
+ existing_user = CustomUser.objects.filter(email=email).first()
+ if existing_user:
+ self.stdout.write(f' ユーザー既存: {email} パスワード:既存')
+ stats['users_existing'] += 1
+ else:
+ display_password = password if password else 'defaultpassword123'
+ self.stdout.write(f' ユーザー新規作成予定: {email} パスワード:{display_password}')
+ stats['users_created'] += 1
+
+ stats['teams_created'] += 1
+ stats['entries_created'] += 1
+
+ # エントリー情報の表示
+ category_name = row.get('部門', '').strip()
+ duration_str = row.get('時間', '').strip()
+
+ # 予想されるゼッケン番号を計算(ドライラン用)
+ max_zekken = Entry.objects.filter(event=event).aggregate(
+ max_zekken=models.Max('zekken_number')
+ )['max_zekken'] or 0
+ predicted_zekken = max_zekken + stats['entries_created']
+
+ self.stdout.write(f' エントリー: ゼッケン{predicted_zekken}, カテゴリー:{category_name}, 時間:{duration_str}時間')
+
+ # 参加登録状況の確認
+ existing_entry = Entry.objects.filter(team__team_name=team_name, event=event).first()
+ if existing_entry:
+ self.stdout.write(f' 参加登録: 済み(既存エントリーID: {existing_entry.id})')
+ else:
+ self.stdout.write(f' 参加登録: 新規作成予定')
+
+ # メンバー数カウント
+ member_count = 0
+ member_names = []
+ for i in range(1, 8): # 最大7名
+ # 全角数字を使用
+ name_key = f'氏名{chr(0xFF10 + i)}' # 全角数字123...を生成
+ name = row.get(name_key, '').strip()
+ if name:
+ member_count += 1
+ birthday_key = f'誕生日{chr(0xFF10 + i)}'
+ birthday = row.get(birthday_key, '').strip()
+ member_names.append(f'{name}({birthday})')
+ stats['members_created'] += member_count
+
+ self.stdout.write(f' メンバー: {member_count}名 [{", ".join(member_names)}]')
+
+ def get_or_create_user(self, row, stats):
+ """カスタムユーザーの取得または作成"""
+ email = row.get('メール', '').strip()
+ password = row.get('パスワード', '').strip()
+ phone = row.get('電話番号', '').strip()
+
+ if not email:
+ raise ValueError('メールアドレスが必要です')
+
+ # 特殊文字のクリーンアップ
+ email = email.replace('@', '@')
+ phone = self.clean_phone_number(phone)
+
+ # 既存ユーザーの検索
+ user = CustomUser.objects.filter(email=email).first()
+ if user:
+ self.stdout.write(f' 既存ユーザー: {email}')
+ stats['users_existing'] += 1
+ return user
+
+ # 新規ユーザー作成
+ user = CustomUser.objects.create_user(
+ email=email,
+ password=password if password else 'defaultpassword123',
+ is_active=True
+ )
+ self.stdout.write(f' 新規ユーザー作成: {email}')
+ stats['users_created'] += 1
+ return user
+
+ def clean_phone_number(self, phone):
+ """電話番号のクリーンアップ"""
+ if not phone:
+ return ''
+
+ # 全角文字を半角に変換
+ phone = phone.replace('-', '-').replace('÷', '-')
+
+ # 余分な文字を削除
+ phone = re.sub(r'[^\d\-]', '', phone)
+
+ return phone
+
+ def create_team(self, row, user, event, stats):
+ """チームの作成"""
+ team_name = row.get('チーム名', '').strip()
+ category_name = row.get('部門', '').strip()
+
+ if not team_name:
+ raise ValueError('チーム名が必要です')
+
+ # チームの重複チェック(同一ユーザー・同一チーム名)
+ existing_team = Team.objects.filter(team_name=team_name, owner=user).first()
+ if existing_team:
+ self.stdout.write(f' 既存チーム使用: {team_name}')
+ return existing_team
+
+ team = Team.objects.create(
+ team_name=team_name,
+ owner=user,
+ class_name=category_name,
+ event=event, # イベントを設定
+ created_at=timezone.now()
+ )
+ self.stdout.write(f' 新規チーム作成: {team_name}')
+ stats['teams_created'] += 1
+ return team
+
+ def create_members(self, row, team, stats):
+ """メンバーの作成(最大7名)"""
+ members = []
+
+ for i in range(1, 8): # 最大7名
+ # 全角数字を使用
+ name_key = f'氏名{chr(0xFF10 + i)}'
+ birthday_key = f'誕生日{chr(0xFF10 + i)}'
+
+ name = row.get(name_key, '').strip()
+ birthday_str = row.get(birthday_key, '').strip()
+
+ if not name:
+ continue
+
+ # 誕生日の解析
+ birthday = self.parse_birthday(birthday_str)
+
+ # ダミーメールアドレス生成
+ dummy_email = f"{team.team_name.replace(' ', '_').replace('!', '').replace('?', '').lower()}_member_{i}@dummy.local"
+
+ # 既存のダミーユーザーチェック
+ existing_dummy = CustomUser.objects.filter(email=dummy_email).first()
+ if existing_dummy:
+ dummy_user = existing_dummy
+ else:
+ # ダミーユーザー作成
+ dummy_user = CustomUser.objects.create_user(
+ email=dummy_email,
+ password='dummypassword123',
+ firstname=name,
+ date_of_birth=birthday,
+ is_active=True
+ )
+
+ # 既存メンバーチェック
+ existing_member = Member.objects.filter(team=team, user=dummy_user).first()
+ if existing_member:
+ member = existing_member
+ else:
+ # メンバー作成(1番目の人がリーダー)
+ member = Member.objects.create(
+ team=team,
+ user=dummy_user,
+ firstname=name,
+ date_of_birth=birthday
+ )
+ # 1番目の人をチームのオーナーとして設定(リーダーの概念)
+ if i == 1 and team.owner != dummy_user:
+ team.owner = dummy_user
+ team.save()
+
+ stats['members_created'] += 1
+
+ members.append(member)
+ self.stdout.write(f' メンバー{i}作成: {name}')
+
+ return members
+
+ def parse_birthday(self, birthday_str):
+ """誕生日文字列の解析"""
+ if not birthday_str or birthday_str in ['不明', '']:
+ return None
+
+ # 年齢のみの場合(例:71歳)
+ if '歳' in birthday_str:
+ try:
+ age = int(birthday_str.replace('歳', ''))
+ # 現在年から年齢を引いて生年を推定
+ birth_year = datetime.now().year - age
+ return datetime(birth_year, 1, 1).date()
+ except ValueError:
+ return None
+
+ # 日付形式の解析
+ try:
+ # YYYY/MM/DD形式
+ if '/' in birthday_str:
+ return datetime.strptime(birthday_str, '%Y/%m/%d').date()
+ # YYYYMMDD形式
+ elif len(birthday_str) == 8 and birthday_str.isdigit():
+ return datetime.strptime(birthday_str, '%Y%m%d').date()
+ # YYYY-MM-DD形式
+ elif '-' in birthday_str:
+ return datetime.strptime(birthday_str, '%Y-%m-%d').date()
+ except ValueError:
+ pass
+
+ self.stdout.write(self.style.WARNING(f' 誕生日形式エラー: {birthday_str}'))
+ return None
+
+ def create_entry(self, row, team, event, stats):
+ """エントリーの作成"""
+ category_name = row.get('部門', '').strip()
+ duration_str = row.get('時間', '').strip()
+
+ # メンバー数を取得
+ member_count = team.members.count()
+
+ # カテゴリーの取得または作成
+ category = None
+ if category_name and duration_str:
+ # 既存のカテゴリーから最適なものを選択
+ duration_hours = int(duration_str) if duration_str.isdigit() else 3
+
+ # お試し部門の判定
+ is_trial = 'お試し' in category_name
+
+ if is_trial:
+ # お試しカテゴリーを検索(時間が一致するもの)
+ trial_categories = NewCategory.objects.filter(
+ trial=True,
+ duration__exact=timedelta(hours=duration_hours)
+ ).order_by('-num_of_member') # メンバー数が多い順
+
+ # メンバー数に適したカテゴリーを選択
+ for cat in trial_categories:
+ if cat.num_of_member >= member_count:
+ category = cat
+ break
+
+ if not category and trial_categories.exists():
+ # 適切なサイズがない場合は最大のお試しカテゴリーを使用
+ category = trial_categories.first()
+ else:
+ # 1. 完全一致するカテゴリーを探す
+ full_category_name = f"{category_name}-{duration_hours}時間"
+ category = NewCategory.objects.filter(category_name=full_category_name).first()
+
+ if not category:
+ # 2. 部分一致するカテゴリーを探す(時間が一致するもの)
+ categories = NewCategory.objects.filter(
+ category_name__icontains=category_name,
+ duration__exact=timedelta(hours=duration_hours),
+ trial=False # お試しではないもの
+ ).order_by('-num_of_member') # メンバー数が多い順
+
+ # メンバー数に適したカテゴリーを選択
+ for cat in categories:
+ if cat.num_of_member >= member_count:
+ category = cat
+ break
+
+ if not category:
+ # 3. どれも見つからない場合は新規作成(メンバー数を考慮)
+ max_members = max(7, member_count) # 最低でも現在のメンバー数は受け入れる
+ full_category_name = f"{category_name}-{duration_hours}時間"
+ category = NewCategory.objects.create(
+ category_name=full_category_name,
+ duration=timedelta(hours=duration_hours),
+ num_of_member=max_members,
+ trial=is_trial, # お試し判定を反映
+ family='ファミリー' in category_name, # ファミリー判定
+ category_number=0
+ )
+ self.stdout.write(f' 新規カテゴリー作成: {full_category_name} (最大{max_members}名, お試し={is_trial})')
+ else:
+ trial_text = ", お試し" if category.trial else ""
+ self.stdout.write(f' 使用カテゴリー: {category.category_name} (最大{category.num_of_member}名{trial_text})')
+
+ # 重複エントリーチェック
+ existing_entry = Entry.objects.filter(team=team, event=event).first()
+ if existing_entry:
+ self.stdout.write(f' 既存エントリー使用: {team.team_name}')
+ return existing_entry
+
+ # 最大ゼッケン番号を取得
+ max_zekken = Entry.objects.filter(event=event).aggregate(
+ max_zekken=models.Max('zekken_number')
+ )['max_zekken'] or 0
+
+ entry = Entry.objects.create(
+ team=team,
+ event=event,
+ category=category,
+ owner=team.owner,
+ zekken_number=max_zekken + 1,
+ date=timezone.now(),
+ is_active=True
+ )
+
+ self.stdout.write(f' エントリー作成: ゼッケン{entry.zekken_number}')
+ stats['entries_created'] += 1
+ return entry
+
+ # 重複エントリーチェック
+ existing_entry = Entry.objects.filter(team=team, event=event).first()
+ if existing_entry:
+ self.stdout.write(f' 既存エントリー使用: {team.team_name}')
+ return existing_entry
+
+ # 最大ゼッケン番号を取得
+ max_zekken = Entry.objects.filter(event=event).aggregate(
+ max_zekken=models.Max('zekken_number')
+ )['max_zekken'] or 0
+
+ entry = Entry.objects.create(
+ team=team,
+ event=event,
+ category=category,
+ owner=team.owner,
+ zekken_number=max_zekken + 1,
+ date=timezone.now(),
+ is_active=True
+ )
+
+ self.stdout.write(f' エントリー作成: ゼッケン{entry.zekken_number}')
+ stats['entries_created'] += 1
+ return entry
+
+ def print_stats(self, stats, dry_run):
+ """統計情報の表示"""
+ mode = '[DRY RUN] ' if dry_run else ''
+
+ self.stdout.write(self.style.SUCCESS('\n' + '='*50))
+ self.stdout.write(self.style.SUCCESS(f'{mode}インポート結果'))
+ self.stdout.write(self.style.SUCCESS('='*50))
+ self.stdout.write(f'処理行数: {stats["total_rows"]}')
+ self.stdout.write(f'ユーザー新規作成: {stats["users_created"]}')
+ self.stdout.write(f'ユーザー既存利用: {stats["users_existing"]}')
+ self.stdout.write(f'チーム作成: {stats["teams_created"]}')
+ self.stdout.write(f'メンバー作成: {stats["members_created"]}')
+ self.stdout.write(f'エントリー作成: {stats["entries_created"]}')
+
+ if stats['errors']:
+ self.stdout.write(self.style.ERROR(f'\nエラー数: {len(stats["errors"])}'))
+ for error in stats['errors']:
+ self.stdout.write(self.style.ERROR(f' {error}'))
+
+ if dry_run:
+ self.stdout.write(self.style.WARNING('\n※ ドライランのため、実際のデータは作成されていません'))
+ else:
+ self.stdout.write(self.style.SUCCESS('\nインポート完了!'))
diff --git a/rog/migrations/0002_add_competition_status_fields.py b/rog/migrations/0002_add_competition_status_fields.py
new file mode 100644
index 0000000..e69de29
diff --git a/エントリー.md b/エントリー.md
new file mode 100644
index 0000000..69dacd7
--- /dev/null
+++ b/エントリー.md
@@ -0,0 +1,34 @@
+CPLIST/input/teams2025.csv から、以下の手順でデータベーステーブルに書き込むプログラムを作成しなさい。docker compose 環境
+
+CSVは以下の項目を持つ。
+
+部門別数,時間,部門,チーム名,メール,パスワード,電話番号,氏名1,誕生日1,氏名2,誕生日2,氏名3,誕生日3,氏名4,誕生日4,氏名5,誕生日5,氏名6,誕生日6,氏名7,誕生日7,,
+
+
+1. 起動パラメータで、event_code を指定する. DBはrogdbを使用。user は admin パスワードは admin123456 ホストは localhost を指定
+
+2. CSVを読みこみ、各行ごとに下記の処理を行う。
+
+2-1. カスタムユーザー
+
+# メールアドレスをキーに既存ユーザーを取得
+ 検索がヒットしなければ、ユーザー登録する。
+
+2-2. チーム登録
+
+# 部門・時間・チーム名でチーム登録
+# メンバーを1名ずつ7名まで登録
+## それぞれダミーメアドと名前と生年月日でメンバー登録
+
+2-3. エントリー登録
+
+# 指定されたイベントにチームを登録する。
+
+2-4. イベント参加
+
+# 登録したエントリーでイベント登録する。
+
+2-5. カスタムユーザーの参加イベント記録
+
+# 関連なデータをカスタムユーザーに書き込む
+
diff --git a/サーバーAPI変更要求書20250905.md b/サーバーAPI変更要求書20250905.md
new file mode 100644
index 0000000..3153e71
--- /dev/null
+++ b/サーバーAPI変更要求書20250905.md
@@ -0,0 +1,104 @@
+# サーバーAPI変更要求書
+
+**日付**: 2025年9月5日
+**要求者**: システム開発チーム
+**対象API**: 通過履歴承認API
+
+## 変更概要
+
+通過履歴の承認処理において、従来の「承認」に加えて「要訂正(仮発行)」機能を追加するため、APIの拡張を要求します。
+
+## 対象API
+
+### エンドポイント
+```
+POST /api/approve_checkin_history
+```
+
+## 変更内容
+
+### 現在のリクエストパラメータ
+```json
+{
+ "event_code": "string",
+ "zekken_number": "string",
+ "checkin_ids": [int],
+ "approval_comment": "string" (optional)
+}
+```
+
+### 変更後のリクエストパラメータ
+```json
+{
+ "event_code": "string",
+ "zekken_number": "string",
+ "checkin_ids": [int],
+ "approval_comment": "string" (optional),
+ "acc_flag": boolean (optional, new)
+}
+```
+
+### 新規追加パラメータ詳細
+
+| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
+|-------------|---|-----|------------|-----|
+| acc_flag | boolean | No | true | 承認フラグ
- `true`: 通常の承認処理(自動印刷実行)
- `false`: 要訂正(仮発行処理) |
+
+## 処理仕様
+
+### acc_flag = true(承認)の場合
+- 従来通りの承認処理を実行
+- サーバー側で自動印刷を実行
+- 承認ステータスを「承認済み」に更新
+
+### acc_flag = false(要訂正/仮発行)の場合
+- 仮発行処理を実行
+- 通過訂正依頼の自動印刷を行う。
+- 承認ステータスを「要訂正」または適切なステータスに更新
+- 後で再度承認処理が可能な状態を維持
+
+### acc_flagが省略された場合
+- デフォルト値 `true` として処理(従来の承認処理)
+- 既存のクライアントとの互換性を保持
+
+## レスポンス仕様
+
+現在のレスポンス形式を維持し、処理結果に応じてメッセージを調整:
+
+```json
+{
+ "status": "OK",
+ "approved_count": int,
+ "message": "string"
+}
+```
+
+### メッセージ例
+- 承認時: "通過履歴の承認が完了しました"
+- 仮発行時: "通過履歴の仮発行が完了しました"
+
+## 実装優先度
+
+**高**: クライアント側実装完了済み、サーバー側対応待ち
+
+## 補足事項
+
+- 既存のAPIとの互換性を保持すること
+- acc_flagパラメータは省略可能とし、省略時は従来の承認処理を実行
+- エラーハンドリングは既存の仕様を継承
+- ログ出力にacc_flagの値を含めることを推奨
+
+## 影響範囲
+
+- 通過履歴承認API(/api/approve_checkin_history)
+- 承認処理ロジック
+- 印刷処理の制御
+- 承認ステータス管理
+
+## テスト項目
+
+1. acc_flag=trueでの承認処理(従来通り)
+2. acc_flag=falseでの仮発行処理
+3. acc_flag省略時のデフォルト動作
+4. 不正なacc_flag値のエラーハンドリング
+5. 既存クライアントとの互換性確認