Finish basic API implementation
This commit is contained in:
192
rog/location_interaction.py
Normal file
192
rog/location_interaction.py
Normal file
@ -0,0 +1,192 @@
|
||||
"""
|
||||
Location evaluation_value に基づく処理ロジック
|
||||
|
||||
evaluation_value の値に応じた処理を定義:
|
||||
- 0: 通常ポイント (通常のチェックイン)
|
||||
- 1: 写真撮影 + 買い物ポイント
|
||||
- 2: QRコードスキャン + クイズ回答
|
||||
"""
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class LocationInteractionType:
|
||||
"""ロケーションインタラクションタイプの定数"""
|
||||
NORMAL_CHECKIN = "0"
|
||||
PHOTO_SHOPPING = "1"
|
||||
QR_QUIZ = "2"
|
||||
|
||||
CHOICES = [
|
||||
(NORMAL_CHECKIN, _("通常ポイント")),
|
||||
(PHOTO_SHOPPING, _("写真撮影 + 買い物ポイント")),
|
||||
(QR_QUIZ, _("QRコードスキャン + クイズ回答")),
|
||||
]
|
||||
|
||||
|
||||
def get_interaction_type(location):
|
||||
"""
|
||||
Locationオブジェクトから適切なインタラクションタイプを取得
|
||||
|
||||
Args:
|
||||
location: Locationモデルのインスタンス
|
||||
|
||||
Returns:
|
||||
dict: インタラクション情報
|
||||
"""
|
||||
evaluation_value = location.evaluation_value or "0"
|
||||
|
||||
interaction_info = {
|
||||
'type': evaluation_value,
|
||||
'requires_photo': False,
|
||||
'requires_qr_code': False,
|
||||
'point_type': 'checkin',
|
||||
'description': '',
|
||||
'instructions': '',
|
||||
}
|
||||
|
||||
if evaluation_value == LocationInteractionType.NORMAL_CHECKIN:
|
||||
interaction_info.update({
|
||||
'point_type': 'checkin',
|
||||
'description': '通常のチェックイン',
|
||||
'instructions': 'この場所でチェックインしてポイントを獲得してください',
|
||||
})
|
||||
|
||||
elif evaluation_value == LocationInteractionType.PHOTO_SHOPPING:
|
||||
interaction_info.update({
|
||||
'requires_photo': True,
|
||||
'point_type': 'buy',
|
||||
'description': '写真撮影 + 買い物ポイント',
|
||||
'instructions': '商品の写真を撮影してください。買い物をすることでポイントを獲得できます',
|
||||
})
|
||||
|
||||
elif evaluation_value == LocationInteractionType.QR_QUIZ:
|
||||
interaction_info.update({
|
||||
'requires_qr_code': True,
|
||||
'point_type': 'quiz',
|
||||
'description': 'QRコードスキャン + クイズ回答',
|
||||
'instructions': 'QRコードをスキャンしてクイズに答えてください',
|
||||
})
|
||||
|
||||
else:
|
||||
# 未知の値の場合はデフォルト処理
|
||||
interaction_info.update({
|
||||
'point_type': 'checkin',
|
||||
'description': '通常のチェックイン',
|
||||
'instructions': 'この場所でチェックインしてポイントを獲得してください',
|
||||
})
|
||||
|
||||
return interaction_info
|
||||
|
||||
|
||||
def should_use_qr_code(location):
|
||||
"""
|
||||
ロケーションでQRコードを使用すべきかを判定
|
||||
|
||||
Args:
|
||||
location: Locationモデルのインスタンス
|
||||
|
||||
Returns:
|
||||
bool: QRコード使用フラグ
|
||||
"""
|
||||
# use_qr_codeフラグが設定されている場合、またはevaluation_value=2の場合
|
||||
return (getattr(location, 'use_qr_code', False) or
|
||||
location.evaluation_value == LocationInteractionType.QR_QUIZ)
|
||||
|
||||
|
||||
def get_point_calculation(location, interaction_result=None):
|
||||
"""
|
||||
ロケーションでのポイント計算
|
||||
|
||||
Args:
|
||||
location: Locationモデルのインスタンス
|
||||
interaction_result: インタラクション結果 (写真、クイズ回答など)
|
||||
|
||||
Returns:
|
||||
dict: ポイント情報
|
||||
"""
|
||||
evaluation_value = location.evaluation_value or "0"
|
||||
base_checkin_point = location.checkin_point or 10
|
||||
buy_point = location.buy_point or 0
|
||||
|
||||
point_info = {
|
||||
'points_awarded': 0,
|
||||
'point_type': 'checkin',
|
||||
'bonus_applied': False,
|
||||
'message': '',
|
||||
}
|
||||
|
||||
if evaluation_value == LocationInteractionType.NORMAL_CHECKIN:
|
||||
# 通常ポイント
|
||||
point_info.update({
|
||||
'points_awarded': base_checkin_point,
|
||||
'point_type': 'checkin',
|
||||
'message': f'チェックインポイント {base_checkin_point}pt を獲得しました!',
|
||||
})
|
||||
|
||||
elif evaluation_value == LocationInteractionType.PHOTO_SHOPPING:
|
||||
# 写真撮影 + 買い物ポイント
|
||||
total_points = base_checkin_point + buy_point
|
||||
point_info.update({
|
||||
'points_awarded': total_points,
|
||||
'point_type': 'buy',
|
||||
'bonus_applied': True,
|
||||
'message': f'写真撮影ボーナス込みで {total_points}pt を獲得しました! (基本: {base_checkin_point}pt + ボーナス: {buy_point}pt)',
|
||||
})
|
||||
|
||||
elif evaluation_value == LocationInteractionType.QR_QUIZ:
|
||||
# QRクイズの場合、正答によってポイントが変わる
|
||||
if interaction_result and interaction_result.get('quiz_correct', False):
|
||||
bonus_points = 20 # クイズ正答ボーナス
|
||||
total_points = base_checkin_point + bonus_points
|
||||
point_info.update({
|
||||
'points_awarded': total_points,
|
||||
'point_type': 'quiz',
|
||||
'bonus_applied': True,
|
||||
'message': f'クイズ正答ボーナス込みで {total_points}pt を獲得しました! (基本: {base_checkin_point}pt + ボーナス: {bonus_points}pt)',
|
||||
})
|
||||
else:
|
||||
# 不正解またはクイズ未実施
|
||||
point_info.update({
|
||||
'points_awarded': base_checkin_point,
|
||||
'point_type': 'checkin',
|
||||
'message': f'基本ポイント {base_checkin_point}pt を獲得しました',
|
||||
})
|
||||
|
||||
return point_info
|
||||
|
||||
|
||||
def validate_interaction_requirements(location, request_data):
|
||||
"""
|
||||
インタラクション要件の検証
|
||||
|
||||
Args:
|
||||
location: Locationモデルのインスタンス
|
||||
request_data: リクエストデータ
|
||||
|
||||
Returns:
|
||||
dict: 検証結果
|
||||
"""
|
||||
evaluation_value = location.evaluation_value or "0"
|
||||
validation_result = {
|
||||
'valid': True,
|
||||
'errors': [],
|
||||
'warnings': [],
|
||||
}
|
||||
|
||||
if evaluation_value == LocationInteractionType.PHOTO_SHOPPING:
|
||||
# 写真が必要
|
||||
if not request_data.get('photo'):
|
||||
validation_result['valid'] = False
|
||||
validation_result['errors'].append('写真の撮影が必要です')
|
||||
|
||||
elif evaluation_value == LocationInteractionType.QR_QUIZ:
|
||||
# QRコードスキャンとクイズ回答が必要
|
||||
if not request_data.get('qr_code_data'):
|
||||
validation_result['valid'] = False
|
||||
validation_result['errors'].append('QRコードのスキャンが必要です')
|
||||
|
||||
if not request_data.get('quiz_answer'):
|
||||
validation_result['valid'] = False
|
||||
validation_result['errors'].append('クイズの回答が必要です')
|
||||
|
||||
return validation_result
|
||||
Reference in New Issue
Block a user