|
|
|
@ -231,6 +231,68 @@ class InstitutionCreateUpdateSerializer(serializers.ModelSerializer): |
|
|
|
'is_featured', |
|
|
|
] |
|
|
|
|
|
|
|
def to_internal_value(self, data): |
|
|
|
if hasattr(data, 'copy'): |
|
|
|
data = data.copy() |
|
|
|
else: |
|
|
|
data = dict(data) |
|
|
|
|
|
|
|
# Normalize institution type if passed in Persian or other aliases |
|
|
|
inst_type = data.get('type') |
|
|
|
if inst_type: |
|
|
|
type_map = { |
|
|
|
'مؤسسه فرهنگی و مذهبی': 'cultural_center', |
|
|
|
'مرکز فرهنگی': 'cultural_center', |
|
|
|
'مسجد': 'mosque', |
|
|
|
'حسینیه': 'hussainiya', |
|
|
|
'حوزه علمیه': 'institute', |
|
|
|
'مرکز آموزشی': 'institute', |
|
|
|
'مرکز پژوهشی': 'institute', |
|
|
|
'مرکز خیریه': 'charity', |
|
|
|
'خیریه': 'charity', |
|
|
|
'کتابخانه': 'library', |
|
|
|
'سایر': 'other', |
|
|
|
} |
|
|
|
if inst_type in type_map: |
|
|
|
data['type'] = type_map[inst_type] |
|
|
|
|
|
|
|
# Normalize established / established_year |
|
|
|
est = data.get('established') if data.get('established') is not None else data.get('established_year') |
|
|
|
if est is not None and not data.get('established_year'): |
|
|
|
try: |
|
|
|
persian_digits = '۰۱۲۳۴۵۶۷۸۹' |
|
|
|
arabic_digits = '٠١٢٣٤٥٦٧٨٩' |
|
|
|
est_str = str(est).strip() |
|
|
|
for i, d in enumerate(persian_digits): |
|
|
|
est_str = est_str.replace(d, str(i)) |
|
|
|
for i, d in enumerate(arabic_digits): |
|
|
|
est_str = est_str.replace(d, str(i)) |
|
|
|
if est_str: |
|
|
|
data['established_year'] = int(est_str) |
|
|
|
except (ValueError, TypeError): |
|
|
|
data['established_year'] = None |
|
|
|
|
|
|
|
# Normalize website: prepend https:// if missing scheme |
|
|
|
website = data.get('website') |
|
|
|
if website and isinstance(website, str) and website.strip(): |
|
|
|
website = website.strip() |
|
|
|
if not (website.startswith('http://') or website.startswith('https://')): |
|
|
|
data['website'] = f'https://{website}' |
|
|
|
|
|
|
|
# Normalize camelCase socialMedia / workingHours if provided |
|
|
|
if 'socialMedia' in data and not data.get('social_media'): |
|
|
|
data['social_media'] = data.get('socialMedia') or {} |
|
|
|
if 'workingHours' in data and not data.get('working_hours'): |
|
|
|
data['working_hours'] = data.get('workingHours') or {} |
|
|
|
|
|
|
|
# If cover_image or avatar is not an actual uploaded file (e.g. string path or URL), ignore it so ImageField doesn't fail |
|
|
|
for img_field in ['cover_image', 'avatar']: |
|
|
|
val = data.get(img_field) |
|
|
|
if val is not None and not hasattr(val, 'read'): |
|
|
|
data.pop(img_field, None) |
|
|
|
|
|
|
|
return super().to_internal_value(data) |
|
|
|
|
|
|
|
def create(self, validated_data): |
|
|
|
user = self.context.get('request').user if self.context.get('request') else None |
|
|
|
if user and user.is_authenticated: |
|
|
|
|