# -*- coding: utf-8 -*- from django import forms from django.utils.encoding import force_unicode from django.utils.safestring import mark_safe from django.conf import settings from yandex_money.forms import PaymentForm from project.commons.forms import MyBaseModelForm, set_field_error from . import consts, models FILE_UPLOAD_MAX_MEMORY_SIZE = getattr(settings, 'FILE_UPLOAD_MAX_MEMORY_SIZE ', 2621440) # default 2.5Mb def get_profile_form_class(profile_type): """Возвращает класс формы редактирования профиля пользователя.""" if profile_type == consts.IP_PROFILE: return IpUserProfileForm elif profile_type == consts.ORG_PROFILE: return OrgUserProfileForm return None def get_profile_filters_form_class(profile_type): """Возвращает класс формы фильтрации профиля пользователя.""" if profile_type == consts.IP_PROFILE: return IpUserProfileFiltersForm elif profile_type == consts.ORG_PROFILE: return OrgUserProfileFiltersForm return None ### def _numeric(field): real_maxlength = field.widget.attrs['maxlength'] return { 'maxlength': int(real_maxlength)*3, # set fake maxlength. otherwise browser would cut pasted values too early 'data-type': 'number', # used by jquery selector 'data-maxlength': real_maxlength, # save real maxlength } # ----------------------------------------------------------------------------- class UserProfileForm(MyBaseModelForm): """Общая форма редактирования профиля пользователя. Специализированные формы для редактирования профилей ИП и Организаций - ищи ниже в классах IpUserProfileForm и OrgUserProfileForm соответственно. Форму для админки ищи ниже в классе UserProfileAdminForm. """ tmb_logo = forms.CharField(required=False, widget=forms.HiddenInput) tmb_boss_sign = forms.CharField(required=False, widget=forms.HiddenInput) tmb_glavbuh_sign = forms.CharField(required=False, widget=forms.HiddenInput) tmb_stamp = forms.CharField(required=False, widget=forms.HiddenInput) class Meta: model = models.UserProfile def __init__(self, *args, **kwargs): super(UserProfileForm, self).__init__(*args, **kwargs) if 'ip_reg_date' in self.fields: self.fields['ip_reg_date'].widget.attrs['class'] = 'has-datepicker' # self.fields['inn'].widget.attrs.update(_numeric(self.fields['inn'])) self.fields['ogrn'].widget.attrs.update(_numeric(self.fields['ogrn'])) self.fields['okpo'].widget.attrs.update(_numeric(self.fields['okpo'])) if 'kpp' in self.fields: self.fields['kpp'].widget.attrs.update(_numeric(self.fields['kpp'])) def _check_file_size(self, image): """Ограничить максимальный размер загружаемого файла.""" if image and image.size > FILE_UPLOAD_MAX_MEMORY_SIZE: raise forms.ValidationError( u'Размер изображения превышает %i Мб' % (FILE_UPLOAD_MAX_MEMORY_SIZE / (1024*1024))) return image def clean_boss_sign(self): image = self.cleaned_data.get('boss_sign') return self._check_file_size(image) def clean_glavbuh_sign(self): image = self.cleaned_data.get('glavbuh_sign') return self._check_file_size(image) def clean_stamp(self): image = self.cleaned_data.get('stamp') return self._check_file_size(image) def clean_logo(self): image = self.cleaned_data.get('logo') return self._check_file_size(image) class IpUserProfileForm(UserProfileForm): """Форма редактирования профиля - ИП.""" change_labels = {'ogrn': u'ОГРНИП'} class Meta(UserProfileForm.Meta): fields = ( # фио ип 'boss_surname', 'boss_name', 'boss_midname', # инн, огрнип, окпо 'inn', 'ogrn', 'okpo', # свид-во гос. регистрации и дата 'svid_gos_reg', 'ip_reg_date', # фио главбуха 'glavbuh_surname', 'glavbuh_name', 'glavbuh_midname', # контактная информация - адреса, телефон, факс, почта, сайт 'address', 'jur_address', 'real_address', 'phone_code', 'phone', 'fax_code', 'fax', 'email', 'site', # подписи, печать и логотип 'boss_sign', 'glavbuh_sign', 'stamp', 'logo', 'tmb_logo', 'tmb_boss_sign', 'tmb_glavbuh_sign', 'tmb_stamp', ) class OrgUserProfileForm(UserProfileForm): """Форма редактирования профиля - Организация.""" unset_required = {'ogrn': u'ОГРН'} change_labels = {'ogrn': u'ОГРН'} class Meta(UserProfileForm.Meta): fields = ( # краткое и полное названия организации 'name', 'full_name', # инн, кпп, огрн, окпо 'inn', 'kpp', 'ogrn', 'okpo', # должность руководителя, его фио и на каком основании он действует 'boss_title', 'boss_surname', 'boss_name', 'boss_midname', 'na_osnovanii', # фио главбуха 'glavbuh_surname', 'glavbuh_name', 'glavbuh_midname', # контактная информация - адреса, телефон, факс, почта, сайт 'address', 'jur_address', 'real_address', 'phone_code', 'phone', 'fax_code', 'fax', 'email', 'site', # подписи, печать и логотип 'boss_sign', 'glavbuh_sign', 'stamp', 'logo', 'tmb_logo', 'tmb_boss_sign', 'tmb_glavbuh_sign', 'tmb_stamp', ) class UserProfileAdminForm(UserProfileForm): """Форма редактирования профиля - для админки.""" # условно-обязательные поля, проверять отдельно - могут быть обязательны в зависимости от типа профиля unset_required = [ # для ИП 'kpp', 'name' # для Организаций ] def clean(self): super(UserProfileAdminForm, self).clean() cleaned_data = self.cleaned_data # тип профиля - ИП или Организация profile_type = cleaned_data.get('profile_type') if profile_type == consts.IP_PROFILE: # поля, обязательные для ИП pass elif profile_type == consts.ORG_PROFILE: # поля, обязательные для Организаций org_boss_name = cleaned_data.get('org_boss_name') kpp = cleaned_data.get('kpp') if not org_boss_name: set_field_error(self, 'org_boss_name') if not kpp: set_field_error(self, 'kpp') return cleaned_data # ----------------------------------------------------------------------------- class BankAccountForm(forms.ModelForm): """Форма редактирования расчетных счетов.""" # search_bank = forms.CharField(label=u'Поиск банка', required=False, initial='') class Meta: model = models.BankAccount # fields = ('search_bank', 'bik', 'name', 'short_name', 'korr_account', 'account', 'is_main', 'company') fields = ('bik', 'name', 'short_name', 'korr_account', 'account', 'is_main', 'company') _textarea = forms.Textarea(attrs={'cols': 80, 'rows': 3}) widgets = { 'bik': forms.HiddenInput(), 'name': forms.HiddenInput(), 'short_name': forms.HiddenInput(), 'korr_account': forms.HiddenInput(), 'company': forms.HiddenInput(), } def __init__(self, *args, **kwargs): super(BankAccountForm, self).__init__(*args, **kwargs) # self.fields['bik'].widget.attrs.update(_numeric(self.fields['bik'])) # self.fields['korr_account'].widget.attrs.update(_numeric(self.fields['korr_account'])) self.fields['account'].widget.attrs.update(_numeric(self.fields['account'])) # self.fields['search_bank'].widget.attrs['class'] = 'search-bank' class BankAccountAdminForm(BankAccountForm): """Форма редактирования расчетных счетов - для админки.""" class Meta(BankAccountForm.Meta): fields = None exclude = ('address',) class BankAccountListForm(forms.Form): """Форма со списком всех расчетных счетов пользователя.""" bank_account = forms.ModelChoiceField(queryset=models.BankAccount.objects.get_all(None), empty_label=u'все контрагенты', required=False) def __init__(self, user, *args, **kwargs): super(BankAccountListForm, self).__init__(*args, **kwargs) self.fields['bank_account'].queryset = models.BankAccount.objects.get_all(user.profile) # ----------------------------------------------------------------------------- class ClientForm(forms.ModelForm): """Форма редактирования контрагентов.""" class Meta: model = models.Client fields = ('name', 'inn', 'kpp', 'ogrn', 'okpo', 'address', # банковские реквизиты 'bank_bik', 'bank_name', 'bank_korr_account', 'bank_account', # контакты 'contact_name', 'contact_email', 'contact_phone', 'contact_skype', 'contact_other', ) _textarea = forms.Textarea(attrs={'cols': 80, 'rows': 3}) widgets = { 'bank_bik': forms.HiddenInput(), 'bank_name': forms.HiddenInput(), 'short_name': forms.HiddenInput(), 'bank_korr_account': forms.HiddenInput(), } def __init__(self, *args, **kwargs): super(ClientForm, self).__init__(*args, **kwargs) self.fields['inn'].widget.attrs.update(_numeric(self.fields['inn'])) self.fields['kpp'].widget.attrs.update(_numeric(self.fields['kpp'])) self.fields['ogrn'].widget.attrs.update(_numeric(self.fields['ogrn'])) self.fields['okpo'].widget.attrs.update(_numeric(self.fields['okpo'])) # self.fields['bank_bik'].widget.attrs.update(_numeric(self.fields['bank_bik'])) # self.fields['bank_korr_account'].widget.attrs.update(_numeric(self.fields['bank_korr_account'])) # self.fields['bank_account'].widget.attrs.update(_numeric(self.fields['bank_account'])) class ClientAdminForm(ClientForm): """Форма редактирования контрагентов - для админки.""" class Meta(ClientForm.Meta): fields = None exclude = ('bank_address',) class ClientsListForm(forms.Form): """Форма со списком всех контрагентов пользователя.""" client = forms.ModelChoiceField(queryset=models.Client.objects.get_all(None), empty_label=u'все контрагенты', required=False) def __init__(self, user, *args, **kwargs): super(ClientsListForm, self).__init__(*args, **kwargs) self.fields['client'].queryset = models.Client.objects.get_all(user.profile) # ----------------------------------------------------------------------------- class UserProfileFiltersForm(MyBaseModelForm): """Общая форма фильтрации реквизитов.""" _profile_type = None # задать в наследнике! _is_admin = False _user = None class Meta: model = models.UserProfileFilters widgets = { 'bank_account': forms.RadioSelect(), } def __init__(self, profile=None, accounts=None, *args, **kwargs): instance = kwargs.get('instance') initial = kwargs.get('initial') new_initial = { # всегда включены 'show_ip_boss_fio': True, 'show_name': True, } # TODO 1. переписать проверки в стиле new_initial['show_inn'] = bool(profile.inn) # TODO 2. загнать условия в словарь вида {'show_inn': 'inn'}. потом в цикле обработать if profile: # сбросить чекбоксы, если не заполнены определенные поля в профиле или нет расчетных счетов if instance: new_initial['show_inn'] = bool(profile.inn) new_initial['show_ogrn'] = bool(profile.ogrn) new_initial['show_okpo'] = bool(profile.okpo) new_initial['show_glavbuh'] = bool(profile.get_glavbuh_fio()) new_initial['show_address'] = bool(profile.address) new_initial['show_jur_address'] = bool(profile.jur_address) new_initial['show_real_address'] = bool(profile.real_address) new_initial['show_phone'] = bool(profile.get_full_phone()) new_initial['show_fax'] = bool(profile.get_full_fax()) new_initial['show_email'] = bool(profile.email) new_initial['show_site'] = bool(profile.site) new_initial['show_bank_account'] = bool(accounts) new_initial['show_logo'] = bool(profile.logo) if self._profile_type == consts.IP_PROFILE: new_initial['show_svid_gos_reg'] = bool(profile.svid_gos_reg) new_initial['show_ip_reg_date'] = bool(profile.ip_reg_date) elif self._profile_type == consts.ORG_PROFILE: new_initial['show_full_name'] = bool(profile.full_name) new_initial['show_kpp'] = bool(profile.kpp) new_initial['show_na_osnovanii'] = bool(profile.na_osnovanii) else: new_initial['show_inn'] = bool(profile.inn) new_initial['show_ogrn'] = bool(profile.ogrn) new_initial['show_okpo'] = bool(profile.okpo) new_initial['show_glavbuh'] = bool(profile.get_glavbuh_fio()) new_initial['show_address'] = bool(profile.address) new_initial['show_jur_address'] = bool(profile.jur_address) new_initial['show_real_address'] = bool(profile.real_address) new_initial['show_phone'] = bool(profile.get_full_phone()) new_initial['show_fax'] = bool(profile.get_full_fax()) new_initial['show_email'] = bool(profile.email) new_initial['show_site'] = bool(profile.site) new_initial['show_bank_account'] = bool(accounts) new_initial['show_logo'] = bool(profile.logo) if self._profile_type == consts.IP_PROFILE: new_initial['show_svid_gos_reg'] = bool(profile.svid_gos_reg) new_initial['show_ip_reg_date'] = bool(profile.ip_reg_date) elif self._profile_type == consts.ORG_PROFILE: new_initial['show_full_name'] = bool(profile.full_name) new_initial['show_kpp'] = bool(profile.kpp) new_initial['show_na_osnovanii'] = bool(profile.na_osnovanii) if initial: initial.update(new_initial) else: kwargs['initial'] = new_initial super(UserProfileFiltersForm, self).__init__(*args, **kwargs) # для админки if self._is_admin: # попробовать взять user из kwargs['instance'], а потом из self.data try: self._user = getattr(kwargs.get('instance'), 'user') except AttributeError: self._user = self.data.get('user') if not accounts: accounts = models.BankAccount.objects.get_all(self._user.profile) f = self.fields # только расчетные счета пользователя f_acc = f['bank_account'] # TODO вынести настройку расчетных счетов в mixin? f_acc.queryset = accounts f_acc.empty_label = None f_acc.label_from_instance = lambda obj: mark_safe( force_unicode('%s
%s' % (obj.account, obj.name,))) # исправить метку # заблокировать чекбоксы, если: не заполнены определенные поля в профиле или нет расчетных счетов if profile: if not profile.inn: f['show_inn'].widget.attrs['disabled'] = 'disabled' if not profile.ogrn: f['show_ogrn'].widget.attrs['disabled'] = 'disabled' if not profile.okpo: f['show_okpo'].widget.attrs['disabled'] = 'disabled' if not profile.get_glavbuh_fio(): f['show_glavbuh'].widget.attrs['disabled'] = 'disabled' if not profile.address: f['show_address'].widget.attrs['disabled'] = 'disabled' if not profile.jur_address: f['show_jur_address'].widget.attrs['disabled'] = 'disabled' if not profile.real_address: f['show_real_address'].widget.attrs['disabled'] = 'disabled' if not profile.get_full_phone(): f['show_phone'].widget.attrs['disabled'] = 'disabled' if not profile.get_full_fax(): f['show_fax'].widget.attrs['disabled'] = 'disabled' if not profile.email: f['show_email'].widget.attrs['disabled'] = 'disabled' if not profile.site: f['show_site'].widget.attrs['disabled'] = 'disabled' if not profile.logo: f['show_logo'].widget.attrs['disabled'] = 'disabled' if not accounts: f['show_bank_account'].widget.attrs['disabled'] = 'disabled' if self._profile_type == consts.IP_PROFILE: if not profile.svid_gos_reg: f['show_svid_gos_reg'].widget.attrs['disabled'] = 'disabled' if not profile.ip_reg_date: f['show_ip_reg_date'].widget.attrs['disabled'] = 'disabled' elif self._profile_type == consts.ORG_PROFILE: if not profile.name: f['show_name'].widget.attrs['disabled'] = 'disabled' if not profile.full_name: f['show_full_name'].widget.attrs['disabled'] = 'disabled' if not profile.kpp: f['show_kpp'].widget.attrs['disabled'] = 'disabled' if not profile.boss_title: f['show_org_boss_title_and_fio'].widget.attrs['disabled'] = 'disabled' if not profile.na_osnovanii: f['show_na_osnovanii'].widget.attrs['disabled'] = 'disabled' # блокировать чекбоксы, т.к.эти реквизиты юзеру выключать нельзя if self._profile_type == consts.IP_PROFILE: f['show_ip_boss_fio'].widget.attrs['disabled'] = 'disabled' elif self._profile_type == consts.ORG_PROFILE: f['show_name'].widget.attrs['disabled'] = 'disabled' class IpUserProfileFiltersForm(UserProfileFiltersForm): """Форма фильтрации реквизитов - для ИП.""" _profile_type = consts.IP_PROFILE change_labels = { 'show_profile_type': dict(consts.PROFILE_TYPES)[_profile_type], 'show_ogrn': u'ОГРНИП', } class Meta(UserProfileFiltersForm.Meta): fields = ( 'show_profile_type', 'show_ip_boss_fio', 'show_inn', 'show_ogrn', 'show_okpo', 'show_svid_gos_reg', 'show_ip_reg_date', 'show_glavbuh', 'show_bank_account', 'bank_account', 'show_contact_info', 'show_address', 'show_jur_address', 'show_real_address', 'show_phone', 'show_fax', 'show_email', 'show_site', 'show_logo', ) class OrgUserProfileFiltersForm(UserProfileFiltersForm): """Форма фильтрации реквизитов - для Организаций.""" _profile_type = consts.ORG_PROFILE change_labels = { 'show_profile_type': dict(consts.PROFILE_TYPES)[_profile_type], 'show_ogrn': u'ОГРН', } class Meta(UserProfileFiltersForm.Meta): fields = ( 'show_profile_type', 'show_name', 'show_full_name', 'show_inn', 'show_kpp', 'show_ogrn', 'show_okpo', 'show_org_boss_title_and_fio', 'show_na_osnovanii', 'show_glavbuh', 'show_bank_account', 'bank_account', 'show_contact_info', 'show_address', 'show_jur_address', 'show_real_address', 'show_phone', 'show_fax', 'show_email', 'show_site', 'show_logo', ) # ----------------------------------------------------------------------------- class EmailProfileForm(forms.Form): """Форма отправки реквизитов пользователя по email.""" to = forms.EmailField(label=u'E-mail получателя') body = forms.CharField(label=u'Текст сообщения', max_length=1000, required=False, widget=forms.Textarea(attrs={'cols': 80, 'rows': 3})) class LicenseForm(forms.Form): """Форма продления лицензии """ term = forms.ModelChoiceField(queryset=models.LicensePrice.objects.all(), widget=forms.RadioSelect, label=u'Срок лицензии', empty_label = None) payform = forms.ChoiceField(choices=consts.PAYFORMS[1:], widget=forms.RadioSelect, label=u'Форма оплаты') class YaForm(PaymentForm): def get_display_field_names(self): return ()