193 lines
6.8 KiB
Python
193 lines
6.8 KiB
Python
"""
|
|
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
|