Basic release 1-Aug-2024

This commit is contained in:
2024-08-01 07:51:52 +00:00
parent 49b3ee7342
commit bc74b14cbc
10 changed files with 500 additions and 86 deletions

View File

@ -0,0 +1,33 @@
# Generated by Django 3.2.9 on 2024-08-01 04:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('rog', '0039_auto_20240726_1508'),
]
operations = [
migrations.AddField(
model_name='member',
name='date_of_birth',
field=models.DateField(blank=True, null=True),
),
migrations.AddField(
model_name='member',
name='female',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='member',
name='firstname',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='member',
name='lastname',
field=models.CharField(blank=True, max_length=255, null=True),
),
]

View File

@ -301,6 +301,11 @@ class Team(models.Model):
class Member(models.Model):
team = models.ForeignKey(Team, on_delete=models.CASCADE, related_name='members')
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
firstname = models.CharField(max_length=255, blank=True, null=True)
lastname = models.CharField(max_length=255, blank=True, null=True)
date_of_birth = models.DateField(null=True, blank=True)
female = models.BooleanField(default=False)
is_temporary = models.BooleanField(default=False) # Akira 2024-7-24
class Meta:

View File

@ -481,8 +481,8 @@ class MemberCreationSerializer(serializers.Serializer):
#email = serializers.EmailField()
email = serializers.EmailField(allow_blank=True, required=False)
firstname = serializers.CharField(required=False)
lastname = serializers.CharField(required=False)
firstname = serializers.CharField(required=False, allow_blank=True)
lastname = serializers.CharField(required=False, allow_blank=True)
date_of_birth = serializers.DateField(required=False)
female = serializers.BooleanField(required=False)
@ -495,7 +495,80 @@ class MemberWithUserSerializer(serializers.ModelSerializer):
fields = ['user', 'team']
class MemberSerializer(serializers.ModelSerializer):
email = serializers.EmailField(write_only=True)
firstname = serializers.CharField(required=False, allow_blank=True, allow_null=True)
lastname = serializers.CharField(required=False, allow_blank=True, allow_null=True)
date_of_birth = serializers.DateField(required=False, allow_null=True)
female = serializers.BooleanField(required=False)
class Meta:
model = Member
fields = ['id', 'email', 'firstname', 'lastname', 'date_of_birth', 'female']
def validate_firstname(self, value):
return value or None
def validate_lastname(self, value):
return value or None
def create(self, validated_data):
email = validated_data.pop('email')
team = self.context['team']
# 既存のユーザーを探すか、新しいユーザーを作成
user, created = CustomUser.objects.get_or_create(email=email)
# ユーザーが新しく作成された場合のみ、追加情報を更新
if created:
user.firstname = validated_data.get('firstname', '')
user.lastname = validated_data.get('lastname', '')
user.date_of_birth = validated_data.get('date_of_birth')
user.female = validated_data.get('female', False)
user.save()
# メンバーを作成
member = Member.objects.create(
user=user,
team=team,
firstname=validated_data.get('firstname'),
lastname=validated_data.get('lastname'),
date_of_birth=validated_data.get('date_of_birth'),
female=validated_data.get('female', False)
)
return member
# メンバーを作成して返す
#class MemberCreationSerializerreturn Member.objects.create(user=user, team=team)
def update(self, instance, validated_data):
user_data = validated_data.pop('user', {})
user = instance.user
for attr, value in user_data.items():
setattr(user, attr, value)
user.save()
return super().update(instance, validated_data)
def to_representation(self, instance):
representation = super().to_representation(instance)
representation['email'] = instance.user.email
representation['firstname'] = instance.user.firstname
representation['lastname'] = instance.user.lastname
representation['date_of_birth'] = instance.user.date_of_birth
representation['female'] = instance.user.female
return representation
class MemberSerializerOld(serializers.ModelSerializer):
user = CustomUserSerializer(read_only=True)
firstname = serializers.CharField(required=False, allow_blank=True, allow_null=True)
lastname = serializers.CharField(required=False, allow_blank=True, allow_null=True)
date_of_birth = serializers.DateField(required=False, allow_null=True)
female = serializers.BooleanField(required=False)
#team = TeamDetailSerializer(read_only=True)
#email = serializers.EmailField(write_only=True, required=False)
@ -506,8 +579,8 @@ class MemberSerializer(serializers.ModelSerializer):
class Meta:
model = Member
fields = ['id','user','team'] # ,'email','firstname','lastname','date_of_birth','female']
read_only_fields = ['id', 'team']
fields = ['id','email','firstname','lastname','date_of_birth','female']
#read_only_fields = ['id', 'team']
'''
@ -530,6 +603,25 @@ class MemberSerializer(serializers.ModelSerializer):
return member
'''
def create(self, validated_data):
email = validated_data.pop('email')
team = self.context['team']
# 既存のユーザーを探すか、新しいユーザーを作成
user, created = CustomUser.objects.get_or_create(email=email)
# メンバーを作成
member = Member.objects.create(
user=user,
team=team,
firstname=validated_data.get('firstname', ''),
lastname=validated_data.get('lastname', ''),
date_of_birth=validated_data.get('date_of_birth'),
female=validated_data.get('female', False)
)
return member
def update(self, instance, validated_data):
user_data = validated_data.pop('user', {})
@ -551,6 +643,12 @@ class MemberSerializer(serializers.ModelSerializer):
#return super().update(instance, validated_data)
def to_representation(self, instance):
representation = super().to_representation(instance)
representation['email'] = instance.user.email
return representation
'''
def to_representation(self, instance):
representation = super().to_representation(instance)
user_data = representation['user']
@ -563,7 +661,7 @@ class MemberSerializer(serializers.ModelSerializer):
'female': user_data['female'],
'team': representation['team']
}
'''
class EntryMemberSerializer(serializers.ModelSerializer):
class Meta:

View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>アクティベーション成功</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
.message {
background-color: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
text-align: center;
}
</style>
</head>
<body>
<div class="message">
<h1>アクティベーション成功</h1>
<p>{{ message }}</p>
</div>
</body>
</html>

View File

@ -12,6 +12,7 @@
リンクをタップすると、アプリからログインすることができるようになります。
ログインした後は、チーム編成やエントリーまたはチームへの参加を行ってください。
すでにメンバーとして登録されている場合には、自動的にメンバー登録されます。
なお、リアルロゲイニングは別途申し込みが必要になりますので、ご連絡をお待ちください。
それでは、岐阜ロゲアプリ「岐阜ナビ」をお楽しみください。

View File

@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>メール確認成功</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
.message {
background-color: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
text-align: center;
}
</style>
</head>
<body>
<div class="message">
<h1>メール確認成功</h1>
<p>{{ message }}</p>
</div>
</body>
</html>

View File

@ -1,7 +1,7 @@
from sys import prefix
from rest_framework import urlpatterns
from rest_framework.routers import DefaultRouter
from .views import LocationViewSet, Location_lineViewSet, Location_polygonViewSet, Jpn_Main_PerfViewSet, LocationsInPerf, ExtentForSubPerf, SubPerfInMainPerf, ExtentForMainPerf, LocationsInSubPerf, CatView, RegistrationAPI, LoginAPI, UserAPI, UserActionViewset, UserMakeActionViewset, UserDestinations, UpdateOrder, LocationInBound, DeleteDestination, CustomAreaLocations, GetAllGifuAreas, CustomAreaNames, userDetials, UserTracksViewSet, CatByCity, ChangePasswordView, GoalImageViewSet, CheckinImageViewSet, ExtentForLocations, DeleteAccount, PrivacyView, RegistrationView, TeamViewSet,MemberViewSet,EntryViewSet,RegisterView, VerifyEmailView, NewEventListView,NewEvent2ListView,NewCategoryListView,CategoryListView, MemberUserDetailView, TeamMembersWithUserView,MemberAddView,UserActivationView,RegistrationView,TempUserRegistrationView,ResendInvitationEmailView,update_user_info
from .views import LocationViewSet, Location_lineViewSet, Location_polygonViewSet, Jpn_Main_PerfViewSet, LocationsInPerf, ExtentForSubPerf, SubPerfInMainPerf, ExtentForMainPerf, LocationsInSubPerf, CatView, RegistrationAPI, LoginAPI, UserAPI, UserActionViewset, UserMakeActionViewset, UserDestinations, UpdateOrder, LocationInBound, DeleteDestination, CustomAreaLocations, GetAllGifuAreas, CustomAreaNames, userDetials, UserTracksViewSet, CatByCity, ChangePasswordView, GoalImageViewSet, CheckinImageViewSet, ExtentForLocations, DeleteAccount, PrivacyView, RegistrationView, TeamViewSet,MemberViewSet,EntryViewSet,RegisterView, VerifyEmailView, NewEventListView,NewEvent2ListView,NewCategoryListView,CategoryListView, MemberUserDetailView, TeamMembersWithUserView,MemberAddView,UserActivationView,RegistrationView,TempUserRegistrationView,ResendInvitationEmailView,update_user_info,update_user_detail,ActivateMemberView, ActivateNewMemberView
from django.urls import path, include
from knox import views as knox_views
@ -34,6 +34,7 @@ router.register(prefix='checkinimage', viewset=CheckinImageViewSet, basename='ch
router.register(r'entry', EntryViewSet, basename='entry')
router.register(r'teams', TeamViewSet, basename='team')
router.register(r'members', MemberViewSet, basename='member')
router.register(r'teams/(?P<team_id>\d+)/members', MemberViewSet, basename='team-members')
# Akira 追加
@ -86,5 +87,8 @@ urlpatterns += [
#path('register/temp/', RegisterView.as_view(), name='register'), # 古い仮登録
path('reactivate/<str:activation_token>/',ResendInvitationEmailView.as_view(),name='reactivate'),
path('userinfo/<int:user_id>/', update_user_info, name='update_user_info'),
path('userdetail/<int:user_id>/',update_user_info, name='update_user_detail')
path('userdetail/<int:user_id>/',update_user_detail, name='update_user_detail'),
path('activate-member/<int:user_id>/<int:team_id>/', ActivateMemberView.as_view(), name='activate-member'),
path('activate-new-member/<uuid:verification_code>/<int:team_id>/', ActivateNewMemberView.as_view(), name='activate-new-member'),
]

View File

@ -3,6 +3,8 @@ from django.template.loader import render_to_string
from django.conf import settings
import logging
from django.core.mail import send_mail
from django.urls import reverse
import uuid
logger = logging.getLogger(__name__)
@ -46,7 +48,12 @@ def send_verification_email(user, activation_link):
# 既にユーザーになっている人にチームへの参加要請メールを出す。
#
def send_team_join_email(sender,user,team,activation_link):
def send_team_join_email(sender,user,team):
activation_link = request.build_absolute_uri(
reverse('activate-member', args=[user.id, team.id])
)
logger.info(f"request: {request}")
context = {
'name': user.lastname or user.email,
'invitor': sender.lastname,
@ -63,22 +70,31 @@ def send_team_join_email(sender,user,team,activation_link):
# その人がユーザー登録して、ユーザー登録されるとメンバーになる。
# アプリからユーザー登録するため、アプリのダウンロードリンクも送る。
#
def send_invitation_email(sender,user,team,activation_link):
def send_invitation_email(sender,request,user_email,team):
verification_code = uuid.uuid4() # UUIDを生成
activation_link = request.build_absolute_uri(
reverse('activate-new-member', args=[verification_code, team.id])
)
context = {
'name': user.firstname or user.email,
'name': user_email,
'invitor': sender.lastname,
'team_name': team.team_name,
'activation_link': activation_link,
'app_download_link': settings.APP_DOWNLOAD_LINK,
'android_download_link': settings.ANDROID_DOWNLOAD_LINK,
}
subject, body = load_email_template('invitation_new_email.txt', context)
share_send_email(subject,body,user.email)
share_send_email(subject,body,user_email)
# 招待された後にユーザー登録された場合、ヴェリフィケーションでチーム参加登録される。
#
def send_invitaion_and_verification_email(sender, user, team, activation_link):
def send_invitaion_and_verification_email(user, team, activation_link):
context = {
'name': user.firstname or user.email,
'activation_link': activation_link,

View File

@ -1,3 +1,4 @@
import requests
from rest_framework import serializers
from django.db import IntegrityError
from django.urls import reverse
@ -158,6 +159,7 @@ def update_user_detail(request, user_id):
setattr(user, field, data[field])
new_value = getattr(user, field)
if old_value != new_value:
logger.debug(f"{field}: {old_value} -> {new_value}")
updated_fields.append(f"{field}: {old_value} -> {new_value}")
logger.debug(f"Fields to be updated: {updated_fields}")
@ -167,6 +169,12 @@ def update_user_detail(request, user_id):
logger.info(f"User {user_id} updated. Changed fields: {', '.join(updated_fields)}")
# 更新されたUserデータを使用して関連するMemberのデータを更新
members = Member.objects.filter(user=user)
for member in members:
member.is_temporary = False
member.save()
serializer = CustomUserSerializer(user)
return Response(serializer.data, status=status.HTTP_200_OK)
@ -832,20 +840,8 @@ class NewEventListView(generics.ListAPIView):
serializer_class = NewEventSerializer
permission_classes = [IsAuthenticated]
def update_external_system(zekken_number, event_code, team_name, class_name, password):
api_url = f"{settings.FRONTEND_URL}/gifuroge/update_team_name"
data = {
"zekken_number": zekken_number,
"new_team_name": team_name,
"event_code": event_code
}
try:
response = requests.post(api_url, json=data)
response.raise_for_status()
return True
except requests.RequestException as e:
logger.error(f"Failed to update external system. Error: {str(e)}")
return False
class TeamViewSet(viewsets.ModelViewSet):
serializer_class = TeamSerializer
@ -855,6 +851,8 @@ class TeamViewSet(viewsets.ModelViewSet):
return Team.objects.filter(owner=self.request.user)
def perform_create(self, serializer):
logger.info(f"Creating new team for user: {self.request.user.email}")
with transaction.atomic():
category = serializer.validated_data['category']
@ -864,12 +862,12 @@ class TeamViewSet(viewsets.ModelViewSet):
category.save()
category.refresh_from_db() # F() 式の結果を評価
serializer.save(owner=self.request.user, zekken_number=zekken_number)
team = self.get_object()
team = serializer.save(owner=self.request.user, zekken_number=zekken_number)
logger.info(f"Team created successfully: {team.id}")
# 外部システムの更新
success = update_external_system(
success = self.register_team(
team.owner,
team.zekken_number,
team.owner.event_code,
team.team_name,
@ -877,21 +875,93 @@ class TeamViewSet(viewsets.ModelViewSet):
team.owner.password
)
if not success:
logger.error("Failed to register external system")
raise serializers.ValidationError("外部システムの更新に失敗しました。")
logger.info("External system register successfully")
def register_team(self, owner,zekken_number,event_code,team_name,category_name,password):
logger.info(f"register_team ==> zekken_number={zekken_number},event_code={event_code},team_name={team_name},category_name={category_name},password={password}")
api_url = f"{settings.FRONTEND_URL}/gifuroge/register_team"
user = owner
headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
data = {
"zekken_number": zekken_number,
"event_code": event_code,
"team_name": team_name,
"class_name": category_name,
"password": password # パスワードの扱いに注意が必要です
}
try:
response = requests.post(api_url,headers=headers,data=data)
response.raise_for_status()
logger.info(f"Team registered successfully for team {team_name}")
return True
except requests.RequestException as e:
logger.error(f"Failed to register team for entry {entry.id}. Error: {str(e)}")
# エラーが発生しても、エントリー自体は作成されています
# 必要に応じて、ここでエラーハンドリングを追加できます
return False
def destroy(self, request, *args, **kwargs):
team = self.get_object()
if team.members.exists():
return Response({"error": "チームにメンバーが残っているため削除できません。"}, status=status.HTTP_400_BAD_REQUEST)
return Response(
{
"error": "チームにメンバーが残っているため削除できません。",
"error_code": "TEAM_HAS_MEMBERS"
},
status=status.HTTP_400_BAD_REQUEST
)
#return Response({"error": "チームにメンバーが残っているため削除できません。"}, status=status.HTTP_400_BAD_REQUEST)
return super().destroy(request, *args, **kwargs)
def update_external_system(zekken_number, event_code, team_name, class_name, password):
api_url = f"{settings.FRONTEND_URL}/gifuroge/update_team_name"
headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
data = {
"zekken_number": zekken_number,
"new_team_name": team_name,
"event_code": event_code,
}
try:
response = requests.post(api_url,headers=headers, data=data)
response.raise_for_status()
return True
except requests.RequestException as e:
logger.error(f"Failed to update external system. Error: {str(e)}")
return False
def update(self, request, *args, **kwargs):
try:
return super().update(request, *args, **kwargs)
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
if getattr(instance, '_prefetched_objects_cache', None):
instance._prefetched_objects_cache = {}
return Response(serializer.data)
except Exception as e:
return Response({"error": "更新に失敗しました。競合が発生した可能性があります。"}, status=status.HTTP_409_CONFLICT)
# def update(self, request, *args, **kwargs):
# try:
# return super().update(request, *args, **kwargs)
# except Exception as e:
# return Response({"error": "更新に失敗しました。競合が発生した可能性があります。"}, status=status.HTTP_409_CONFLICT)
def perform_update(self, serializer):
with transaction.atomic():
team = serializer.save()
@ -906,7 +976,8 @@ class TeamViewSet(viewsets.ModelViewSet):
)
if not success:
raise serializers.ValidationError("外部システムの更新に失敗しました。")
else:
print("岐阜ロゲシステム更新に成功")
@action(detail=True, methods=['post'])
def copy(self, request, pk=None):
@ -1004,27 +1075,6 @@ class EntryViewSet(viewsets.ModelViewSet):
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
def register_team(self, entry):
api_url = f"{settings.FRONTEND_URL}/gifuroge/register_team"
user = self.request.user
data = {
"zekken_number": entry.team.zekken_number,
"event_code": entry.event.event_code,
"team_name": entry.team.team_name,
"class_name": entry.category.category_name,
"password": user.password # パスワードの扱いに注意が必要です
}
try:
response = requests.post(api_url, data=data)
response.raise_for_status()
logger.info(f"Team registered successfully for entry {entry.id}")
except requests.RequestException as e:
logger.error(f"Failed to register team for entry {entry.id}. Error: {str(e)}")
# エラーが発生しても、エントリー自体は作成されています
# 必要に応じて、ここでエラーハンドリングを追加できます
def update(self, request, *args, **kwargs):
logger.info(f"Update method called for Entry with ID: {kwargs.get('pk')}")
@ -1074,7 +1124,7 @@ class EntryViewSet(viewsets.ModelViewSet):
class MemberViewSet(viewsets.ModelViewSet):
#serializer_class = MemberSerializer
serializer_class = MemberSerializer
permission_classes = [permissions.IsAuthenticated,IsTeamOwner]
def get_serializer_class(self):
@ -1086,12 +1136,64 @@ class MemberViewSet(viewsets.ModelViewSet):
team_id = self.kwargs['team_id']
return Member.objects.filter(team_id=team_id)
@action(detail=False, methods=['DELETE'])
def destroy_all(self, request, team_id=None):
team = Team.objects.get(id=team_id)
# チームのオーナーかどうかを確認
if team.owner != request.user:
return Response({"error": "チームのオーナーのみがメンバーを一括削除できます。"}, status=status.HTTP_403_FORBIDDEN)
# 確認パラメータをチェック
confirm = request.query_params.get('confirm', '').lower()
if confirm != 'true':
return Response({"error": "確認パラメータが必要です。'?confirm=true'を追加してください。"}, status=status.HTTP_400_BAD_REQUEST)
try:
with transaction.atomic():
# オーナー以外のすべてのメンバーを削除
#deleted_count = Member.objects.filter(team=team).exclude(user=team.owner).delete()[0]
deleted_count = Member.objects.filter(team=team).delete()[0]
return Response({
"message": f"{deleted_count}人のメンバーが削除されました。",
"deleted_count": deleted_count
}, status=status.HTTP_200_OK)
except Exception as e:
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
team = instance.team
# チームのオーナーかどうかを確認
if team.owner != request.user:
return Response({"error": "チームのオーナーのみがメンバーを削除できます。"}, status=status.HTTP_403_FORBIDDEN)
# オーナー自身は削除できないようにする
#if instance.user == team.owner:
# return Response({"error": "チームのオーナーは削除できません。"}, status=status.HTTP_400_BAD_REQUEST)
self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT)
def create(self, request, *args, **kwargs):
logger.info(f"Attempting to create new member for team: {self.kwargs['team_id']}")
logger.debug(f"Received data: {request.data}")
team = Team.objects.get(id=self.kwargs['team_id'])
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
#serializer = self.get_serializer(data=request.data)
serializer = self.get_serializer(data=request.data, context={'team': team})
try:
serializer.is_valid(raise_exception=True)
except serializers.ValidationError as e:
logger.error(f"Validation error: {e.detail}")
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
email = serializer.validated_data.get('email', '')
logger.info(f"Processing member with email: {email}")
user_data = {
'firstname': serializer.validated_data.get('firstname', ''),
@ -1100,40 +1202,64 @@ class MemberViewSet(viewsets.ModelViewSet):
'female': serializer.validated_data.get('female', False),
}
if not email or email.startswith('dummy_'):
# 直接登録
if email:
user, created = CustomUser.objects.get_or_create(
email=email,
defaults={**user_data, 'is_active':True}
)
# 自分自身を登録する場合
if request.user.email == email:
member, created = Member.objects.get_or_create(user=request.user, team=team)
if created:
return Response(MemberSerializer(member).data, status=status.HTTP_201_CREATED)
else:
# emailが空の場合、一意のダミーメールアドレスを生成
dummy_email = f"dummy_{uuid.uuid4()}@example.com"
user = CustomUser.objects.create(email=dummy_email, **user_data)
return Response({"message": "You are already a member of this team."}, status=status.HTTP_200_OK)
member = Member.objects.create(user=user, team=team)
return Response(MemberSerializer(member).data, status=status.HTTP_201_CREATED)
if not email or email.startswith('dummy_'):
logger.info("Processing as direct registration")
# 直接登録
try:
if email:
user, created = CustomUser.objects.get_or_create(
email=email,
defaults={**user_data, 'is_active':True}
)
else:
# emailが空の場合、一意のダミーメールアドレスを生成
dummy_email = f"dummy_{uuid.uuid4()}@example.com"
user = CustomUser.objects.create(email=dummy_email, **user_data)
member = Member.objects.create(user=user, team=team)
logger.info(f"Member created successfully: {member.id}")
return Response(MemberSerializer(member).data, status=status.HTTP_201_CREATED)
except Exception as e:
logger.error(f"Error creating member: {str(e)}")
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
#member = serializer.save(team=team)
#return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
logger.info("Processing as temporary registration")
# 仮登録
existing_user = CustomUser.objects.filter(email=email).first()
if existing_user:
logger.info(f"Existing user found: {existing_user.id}")
# 既存ユーザーの場合、チーム招待メールを送信
send_team_join_email(existing_user, team)
send_team_join_email(request.user,existing_user, team)
return Response({"message": "Invitation for your team sent to existing user."}, status=status.HTTP_200_OK)
else:
print("新規ユーザー")
temp_user = TempUser.objects.create(
email=email,
**user_data,
verification_code=str(uuid.uuid4())
)
send_invitation_email(temp_user, team) #仮登録済みでも確認メールを送る。
logger.info("Inviting new temporary user")
return Response({"message": "Invitation email sent to the user."}, status=status.HTTP_201_CREATED)
try:
print("新規ユーザー")
#temp_user = TempUser.objects.create(
# email=email,
# **user_data,
# verification_code=str(uuid.uuid4())
#)
send_invitation_email(request.user,request,email, team) #仮登録済みでも確認メールを送る。
logger.info(f"Invitation email sent to: {email}")
return Response({"message": "Invitation email sent to the user."}, status=status.HTTP_201_CREATED)
except Exception as e:
logger.info(f"Error on Invitation email sent to: {email} : {e}")
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
'''
@ -1252,6 +1378,59 @@ class MemberViewSet(viewsets.ModelViewSet):
self.check_object_permissions(self.request, obj)
return obj
class ActivateMemberView(APIView):
def get(self, request, user_id, team_id):
user = get_object_or_404(CustomUser, id=user_id)
team = get_object_or_404(Team, id=team_id)
# メンバーオブジェクトを取得または作成
member, created = Member.objects.get_or_create(user=user, team=team)
if member.lastname == "dummy":
# userデータでmemberデータを更新
member.lastname = user.lastname
member.firstname = user.firstname
member.date_of_birth = user.date_of_birth
member.female = user.female
member.save()
message = f"{team.team_name}に正常に参加し、メンバー情報が更新されました。アプリのチーム管理で確認できます。"
else:
message = f"{team.team_name}に正常に参加しました。"
return render(request, 'activation_success.html', {'message': message})
class ActivateNewMemberView(APIView):
def get(self, request, verification_code, team_id):
try:
team = Team.objects.get(id=team_id)
member, created = Member.objects.get_or_create(team=team, user__email=email)
if created:
return Response({'message': 'Member activated successfully'}, status=status.HTTP_201_CREATED)
else:
return Response({'message': 'Member already exists'}, status=status.HTTP_200_OK)
except Team.DoesNotExist:
return Response({'message': 'Invalid team'}, status=status.HTTP_400_BAD_REQUEST)
'''
temp_user = get_object_or_404(TempUser, verification_code=verification_code)
team = get_object_or_404(Team, id=team_id)
user = CustomUser.objects.create_user(
email=temp_user.email,
password=temp_user.password, # Ensure this is securely handled
**{k: v for k, v in temp_user.__dict__.items() if k in ['firstname', 'lastname', 'date_of_birth', 'female']}
)
Member.objects.create(user=user, team=team)
temp_user.delete()
message = f"アカウントが作成され、{team.team_name}に参加しました。アプリのチーム管理で確認できます。"
return render(request, 'activation_success.html', {'message': message})
'''
class OwnerEntriesView(generics.ListAPIView):
serializer_class = EntrySerializer
permission_classes = [permissions.IsAuthenticated]
@ -1461,13 +1640,24 @@ class VerifyEmailView(APIView):
password=temp_user.password,
**{k: v for k, v in user_data.items() if k != 'email'}
)
temp_user.delete()
return Response({'message': 'Email verified and user created'}, status=status.HTTP_201_CREATED)
# チームへの追加処理(もし必要なら)
if hasattr(temp_user, 'team_id'):
team = Team.objects.get(id=temp_user.team_id)
Member.objects.create(user=user, team=team)
message = f"メールアドレスが確認され、アカウントが作成されました。{team.team_name}のメンバーとして登録されています。アプリでログインして、必要な情報を入力してください。"
else:
message = "メールアドレスが確認され、アカウントが作成されました。アプリでログインして、必要な情報を入力してください。"
temp_user.delete()
return render(request, 'verification_success.html', {'message': message})
else:
return Response({'message': 'Verification link expired'}, status=status.HTTP_400_BAD_REQUEST)
message = "確認リンクの有効期限が切れています。アプリから認証コードの再送信をしてください。"
return render(request, 'verification_success.html', {'message': message})
except TempUser.DoesNotExist:
return Response({'message': 'Invalid verification code'}, status=status.HTTP_400_BAD_REQUEST)
message = "無効な確認コードです。"
return render(request, 'verification_success.html', {'message': message})
class MemberUserDetailView(generics.RetrieveAPIView):