You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
486 lines
22 KiB
486 lines
22 KiB
# -*- 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<br /><span class="name">%s</span>' % (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 ()
|
|
|