diff --git a/apps/profiles/serializers/institution_serializers.py b/apps/profiles/serializers/institution_serializers.py index 318ccdc..ad44dc1 100644 --- a/apps/profiles/serializers/institution_serializers.py +++ b/apps/profiles/serializers/institution_serializers.py @@ -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: