import logging from django import forms from django.utils.translation import gettext_lazy as _ from django.core.exceptions import ValidationError from pingcap_sso.models import ( PartnerCompatibilityCertification, SecurityCode, ) from pingcap_sso.user_behavior_track.models import TrackEvent from pingcap_sso.validators.phone import PhoneNumberValidator from pingcap_sso.utils import crm from pingcap_sso.utils.requests import get_client_ip, get_client_agent from pingcap_sso.utils.phone import is_virtual_phone from pingcap_sso.lib.upload import upload_file logger = logging.getLogger(__name__) class PartnerCompatibilityCertificationApplicationForm(forms.ModelForm): solution_type = forms.CharField(max_length=100) product_industry = forms.CharField(max_length=100) compatible_database_version = forms.CharField(max_length=100) infra_category = forms.CharField(max_length=100, required=False) phone_code = forms.CharField(max_length=6) contact_job_title = forms.CharField(max_length=100) attachment_1 = forms.FileField() company_logo = forms.ImageField() def __init__(self, request, user, *args, **kwargs): self.request = request self.user = user super(PartnerCompatibilityCertificationApplicationForm, self).__init__(*args, **kwargs) def _clean_attachment_ext(self, file, exts): if file and not file.name.endswith(exts): raise ValidationError('file type must be {}'.format(exts)) return file def _clean_file_size(self, file, max_size=20 * 1 << 20): if file: try: file.size except Exception: import traceback logger.error(traceback.format_exc()) else: if file.size > max_size: raise ValidationError('file size exceeds limit ({}M)'.format(max_size)) return file def clean_attachment_1(self): file = self.cleaned_data.get('attachment_1') file = self._clean_attachment_ext(file, ('.doc', '.docx')) return self._clean_file_size(file, 20 * 1 << 20) def clean_company_logo(self): file = self.cleaned_data.get('company_logo') return self._clean_file_size(file, 5 * 1 << 20) def clean_company_address(self): company_address = self.cleaned_data.get('company_address') if company_address and company_address not in crm.CHINA_BUSINESS_PROVINCES: raise ValidationError(_('invalid option')) return company_address def clean_solution_type(self): solution_type = self.cleaned_data.get('solution_type') if solution_type and solution_type not in crm.PARTNER_SOLUTION_TYPE_OPTIONS: raise ValidationError(_('invalid option')) return solution_type def clean_contact_phone(self): phone = self.cleaned_data.get('contact_phone') if phone: PhoneNumberValidator()(phone) if is_virtual_phone(phone): raise ValidationError(_('currently does not support virtual carrier numbers')) return phone def clean_product_industry(self): product_industry = self.cleaned_data.get('product_industry') if product_industry and product_industry not in crm.PARTNER_SOLUTION_INDUSTRY_OPTIONS: raise ValidationError(_('invalid option')) return product_industry def clean_compatible_database_version(self): compatible_database_version = self.cleaned_data.get('compatible_database_version') if compatible_database_version and compatible_database_version not in crm.PARTNER_COMPATIBLE_DATABASE_VERSION_OPTIONS: raise ValidationError(_('invalid option')) return compatible_database_version def clean_contact_job_title(self): contact_job_title = self.cleaned_data.get('contact_job_title') if contact_job_title and contact_job_title not in crm.JOB_TITLE_OPTIONS: raise ValidationError(_('invalid option')) return contact_job_title def clean_infra_category(self): infra_category = self.cleaned_data.get('infra_category') if infra_category and infra_category not in crm.PARTNER_INFRASTRUCTURE_CATEGORY_OPTIONS: raise ValidationError(_('invalid option')) return infra_category def clean(self): if self.errors: return solution_type = self.cleaned_data.get('solution_type') infra_category = self.cleaned_data.get('infra_category') if solution_type == "ke76LBbs7" and not infra_category: self.add_error('infra_category', '基础设施分类不能为空') phone = self.cleaned_data.get('contact_phone') phone_code = self.cleaned_data.get('phone_code') if not SecurityCode.check_code( phone, phone_code, scene=SecurityCode.SCENE_PARTNER_CERTIFICATION, ): self.add_error('phone_code', '手机验证码错误') return self.cleaned_data def save(self): data = self.cleaned_data instance = super(PartnerCompatibilityCertificationApplicationForm, self).save(commit=False) instance.user = self.user solution_type = data.get('solution_type') if solution_type: instance.solution_type_code = solution_type instance.solution_type_text = crm.PARTNER_SOLUTION_TYPE_OPTIONS[solution_type] product_industry = data.get('product_industry') if product_industry: instance.product_industry_code = product_industry instance.product_industry_text = crm.PARTNER_SOLUTION_INDUSTRY_OPTIONS[product_industry] compatible_database_version = data.get('compatible_database_version') if compatible_database_version: instance.compatible_database_version_code = compatible_database_version instance.compatible_database_version_text = crm.PARTNER_COMPATIBLE_DATABASE_VERSION_OPTIONS[compatible_database_version] infra_category = data.get('infra_category') if infra_category: instance.infra_category_code = infra_category instance.infra_category_text = crm.PARTNER_INFRASTRUCTURE_CATEGORY_OPTIONS[infra_category] contact_job_title = data.get('contact_job_title') if contact_job_title: instance.contact_job_title_code = contact_job_title instance.contact_job_title_text = crm.JOB_TITLE_OPTIONS[contact_job_title] company_address = data.get('company_address') if company_address: for area_code, area_info in crm.CHINA_BUSINESS_AREA_MAP.items(): for province in area_info['provinces']: if province == company_address: instance.company_area_code = area_code instance.company_area_text = area_info['name'] break docx_file_1 = upload_file(self.cleaned_data.get('attachment_1'), self.user) company_logo = upload_file(self.cleaned_data.get('company_logo'), self.user) instance.attachment_1 = docx_file_1 instance.company_logo = company_logo instance.save() if self.user and self.user.is_authenticated: TrackEvent.objects.create( openid=self.user.openid, event_type='sso.submit_partner_compatibility_certification', event_body={}, user_agent=get_client_agent(self.request), ip=get_client_ip(self.request), description='提交了联合解决方案互认证申请', source=TrackEvent.SOURCE_SERVER ) class Meta: model = PartnerCompatibilityCertification fields = [ 'company', 'company_address', 'contact_name', 'contact_phone', 'contact_email', 'cert_owner_name', 'cert_owner_job_title', 'product_name', 'product_description', 'purpose_of_certification', 'shipping_address' ]