# -*- coding: utf-8 -*- import os from PIL import Image from django.db import models from django.contrib.auth.models import User from . import consts, managers PROFILE_IMAGES_UPLOAD_DIR = 'customer/profile/' # куда сохранять загруженные изображения BOSS_SIGN_IMG_SIZE = (100, 75) GLAVBUH_SIGN_IMG_SIZE = (100, 75) STAMP_IMG_SIZE = (180, 180) def get_profile(user): """Возвращает профиль пользователя или None.""" try: return UserProfile.objects.get(user=user) except UserProfile.DoesNotExist: return None def upload_to(path, new_filename=None): """Куда и под каким именем сохранить загруженный файл.""" def get_upload_path(instance, filename): filename = new_filename or filename return os.path.join(path, instance.user.username, filename) return get_upload_path class UserProfile(models.Model): """Профиль пользователя.""" user = models.OneToOneField(User, related_name='profile', primary_key=True) profile_type = models.PositiveSmallIntegerField(u'Тип профиля', choices=consts.PROFILE_TYPES) # общие поля boss_surname = models.CharField(u'Фамилия', max_length=30, default='', help_text=u'Используется для строки "подпись" в документах.') boss_name = models.CharField(u'Имя', max_length=30, default='') boss_midname = models.CharField(u'Отчество', max_length=30, default='') inn = models.CharField(u'ИНН', max_length=12, default='') # длина: 10 для организаций, 12 для ИП ogrn = models.CharField(u'ОГРН/ОГРНИП', max_length=15, default='') # длина: 13 для организаций, 15 для ИП okpo = models.CharField(u'ОКПО', max_length=10, blank=True, default='') # длина: 8 для организаций, 8 или 10 для ИП glavbuh_surname = models.CharField(u'Фамилия', max_length=30, blank=True, default='', help_text=u'Используется для строки "подпись" в документах.') glavbuh_name = models.CharField(u'Имя', max_length=30, blank=True, default='') glavbuh_midname = models.CharField(u'Отчество', max_length=30, blank=True, default='') address = models.CharField(u'Адрес для документов', max_length=256, default='', help_text=u'Будет подставляться в создаваемые счета, акты и накладные.') real_address = models.CharField(u'Фактический адрес', max_length=256, blank=True, default='', help_text=u'Используется только для карточки компании.') phone_code = models.CharField(u'Код города', max_length=10, blank=True, default='') phone = models.CharField(u'Номер телефона', max_length=20, blank=True, default='') fax_code = models.CharField(u'Код города', max_length=10, blank=True, default='') fax = models.CharField(u'Номер телефона', max_length=20, blank=True, default='') email = models.EmailField(u'Электронная почта', max_length=75, blank=True, default='') site = models.CharField(u'Сайт', max_length=256, blank=True, default='') # поля, только для ИП svid_gos_reg = models.CharField(u'Свид-во о гос. регистрации', max_length=256, blank=True, default='', help_text=u'Требуется для счет-фактуры.') ip_reg_date = models.DateField(u'Дата регистрации ИП', blank=True, null=True) # поля, только для Организации name = models.CharField(u'Краткое название организации', max_length=256, default='', help_text=u'Будет подставляться в создаваемые документы.') full_name = models.CharField(u'Полное название организации', max_length=256, blank=True, default='', help_text=u'Как в учредительных документах.') kpp = models.CharField(u'КПП', max_length=9, default='') jur_address = models.CharField(u'Юридический (почтовый) адрес', max_length=256, blank=True, default='', help_text=u'Как в учредительных документах.') boss_title = models.CharField(u'Должность руководителя', max_length=256, blank=True, default='') na_osnovanii = models.CharField(u'Действует на основании', max_length=256, blank=True, default='') # подписи, печать и логотип boss_sign = models.ImageField(u'Подпись руководителя', blank=True, default='', upload_to=upload_to(PROFILE_IMAGES_UPLOAD_DIR, 'boss_sign.bmp')) glavbuh_sign = models.ImageField(u'Подпись бухгалтера', blank=True, default='', upload_to=upload_to(PROFILE_IMAGES_UPLOAD_DIR, 'glavbuh_sign.bmp')) stamp = models.ImageField(u'Печать', blank=True, default='', upload_to=upload_to(PROFILE_IMAGES_UPLOAD_DIR, 'stamp.bmp')) logo = models.ImageField(u'Логотип', blank=True, default='', upload_to=upload_to(PROFILE_IMAGES_UPLOAD_DIR, 'logo.bmp')) created_at = models.DateTimeField(u'Создан', auto_now_add=True) updated_at = models.DateTimeField(u'Изменен', auto_now=True) objects = managers.UserProfileManager() class Meta: verbose_name = u'Реквизиты (профиль)' verbose_name_plural = u'Реквизиты (профили)' def __unicode__(self): return u'%s, %s, ИНН %s' % (self.user.email, self.get_company_name()[0:30], self.inn or u'не указан') def save(self, *args, **kwargs): def process_img(orig_img, size): w = orig_img.width h = orig_img.height if w > size[0] or h > size[1]: filename = str(orig_img.path) img = Image.open(filename).convert("RGB") img.thumbnail(size, Image.ANTIALIAS) img.save(filename, 'bmp') super(UserProfile, self).save(*args, **kwargs) if self.boss_sign: process_img(self.boss_sign, size=BOSS_SIGN_IMG_SIZE) if self.glavbuh_sign: process_img(self.glavbuh_sign, size=GLAVBUH_SIGN_IMG_SIZE) if self.stamp: process_img(self.stamp, size=STAMP_IMG_SIZE) def is_ip(self): return self.profile_type == consts.IP_PROFILE def is_org(self): return self.profile_type == consts.ORG_PROFILE def get_company_name(self): """`ИП ФИО` или `Название Организации`.""" if self.profile_type == consts.IP_PROFILE: return u'ИП %s' % self.get_boss_full_fio() elif self.profile_type == consts.ORG_PROFILE: return self.name.strip() return u'' def get_inn_and_kpp(self): """Возвращает пару ИНН/КПП или только ИНН, если это ИП или КПП не заполнен.""" if self.profile_type == consts.ORG_PROFILE: kpp = self.kpp.strip() if kpp: return u'%s/%s' % (self.inn, kpp,) return self.inn def get_boss_title(self): """Текст 'Индивидуальный предприниматель' или 'Руководитель организации'.""" if self.profile_type == consts.IP_PROFILE: return u'Индивидуальный предприниматель' elif self.profile_type == consts.ORG_PROFILE: return u'Руководитель организации' return u'' def get_boss_fio(self): """Фамилия и инициалы руководителя ИП/организации.""" if self.boss_surname and self.boss_name and self.boss_midname: return u'%s %s.%s.' % (self.boss_surname, self.boss_name[0], self.boss_midname[0],) return u'' def get_boss_full_fio(self): """Полное ФИО руководителя ИП/организации.""" return (u'%s %s %s' % (self.boss_surname, self.boss_name, self.boss_midname,)).strip() def get_glavbuh_fio(self): """Фамилия и инициалы главного бухгалтера.""" if self.glavbuh_surname and self.glavbuh_name and self.glavbuh_midname: return (u'%s %s. %s.' % (self.glavbuh_surname, self.glavbuh_name[0], self.glavbuh_midname[0],)).strip() return u'' def get_glavbuh_full_fio(self): """Полное ФИО главного бухгалтера.""" return (u'%s %s %s' % (self.glavbuh_surname, self.glavbuh_name, self.glavbuh_midname,)).strip() def get_full_phone(self): """(Код города) Номер телефона.""" phone_code = self.phone_code.strip('() ') phone_code = u'(%s)' % phone_code if phone_code else phone_code return (u'%s %s' % (phone_code, self.phone,)).strip() def get_full_fax(self): """(Код города) Номер факса.""" fax_code = self.fax_code.strip('() ') fax_code = u'(%s)' % fax_code if fax_code else fax_code return (u'%s %s' % (fax_code, self.fax,)).strip() class BankAccount(models.Model): """Расчетные счета.""" user = models.ForeignKey(User, related_name='bank_accounts') bik = models.CharField(u'БИК', max_length=10) name = models.CharField(u'Наименование банка', max_length=256) address = models.CharField(u'Местонахождение', max_length=256) korr_account = models.CharField(u'Корр. счет', max_length=20) account = models.CharField(u'Расчетный счет', max_length=20) is_main = models.BooleanField(u'Основной счет', default=False) created_at = models.DateTimeField(u'Создан', auto_now_add=True) updated_at = models.DateTimeField(u'Изменен', auto_now=True) objects = managers.BankAccountManager() class Meta: verbose_name = u'Расчётный счет' verbose_name_plural = u'Расчётные счета' ordering = ['-created_at'] def __unicode__(self): return (u'%s, %s' % (self.account, self.name[0:30],)).strip() def save(self, *args, **kwargs): super(BankAccount, self).save(*args, **kwargs) if self.is_main: # если задано, что это будет основной счет, то сбросить у остальных счетов пользователя этот признак BankAccount.objects.filter(user=self.user, is_main=True).exclude(pk=self.pk).update(is_main=False) else: # если нет основного счета, то установить его принудительно BankAccount.objects.force_main(user=self.user) def delete(self, *args, **kwargs): super(BankAccount, self).delete(*args, **kwargs) # если нет основного счета, то установить его принудительно BankAccount.objects.force_main(user=self.user) class Client(models.Model): """Контрагенты.""" user = models.ForeignKey(User, related_name='clients') name = models.CharField(u'Наименование', max_length=256, db_index=True) inn = models.CharField(u'ИНН', max_length=12) kpp = models.CharField(u'КПП', max_length=9, blank=True, default='') # Организация okpo = models.CharField(u'ОКПО', max_length=10, blank=True, default='') # ИП address = models.CharField(u'Юр. адрес', max_length=256) # банковские реквизиты bank_bik = models.CharField(u'БИК', max_length=10, blank=True, default='') bank_name = models.CharField(u'Наименование банка', max_length=256, blank=True, default='') bank_address = models.CharField(u'Местонахождение', max_length=256, blank=True, default='') bank_korr_account = models.CharField(u'Корр. счет', max_length=20, blank=True, default='') bank_account = models.CharField(u'Расчетный счет', max_length=20, blank=True, default='') # контакты contact_name = models.CharField(u'Имя', max_length=50, blank=True, default='') contact_email = models.EmailField(u'E-mail', max_length=50, blank=True, default='') contact_phone = models.CharField(u'Телефон', max_length=50, blank=True, default='') contact_icq = models.CharField(u'ICQ', max_length=20, blank=True, default='') contact_skype = models.CharField(u'Skype', max_length=20, blank=True, default='') contact_other = models.CharField(u'Другое', max_length=256, blank=True, default='') created_at = models.DateTimeField(u'Создан', auto_now_add=True) updated_at = models.DateTimeField(u'Изменен', auto_now=True) objects = managers.ClientManager() class Meta: verbose_name = u'Контрагент' verbose_name_plural = u'Контрагенты' ordering = ['name', '-created_at'] def __unicode__(self): return (u'%s, ИНН %s' % (self.name[0:30], self.inn or u'не указан',)).strip() def get_inn_and_kpp(self): """Возвращает пару ИНН/КПП или только ИНН, если КПП не заполнен.""" kpp = self.kpp.strip() if kpp: return u'%s/%s' % (self.inn, kpp,) return self.inn class UserProfileFilters(models.Model): """Фильтрация реквизитов: какие данные показывать/скрывать при генерации карточки компании.""" user = models.OneToOneField(User, related_name='profile_filters', primary_key=True) # общие фильтры show_profile_type = models.BooleanField(u'Тип профиля', default=True) show_inn = models.BooleanField(u'ИНН', default=True) show_ogrn = models.BooleanField(u'ОГРН/ОГРНИП', default=True) show_okpo = models.BooleanField(u'ОКПО', default=True) show_glavbuh = models.BooleanField(u'Главный бухгалтер', default=True) show_bank_account = models.BooleanField(u'Банковские реквизиты', default=True) bank_account = models.ForeignKey(BankAccount, related_name='+', verbose_name=u'Расчетный счет', blank=True, null=True, default=None) show_contact_info = models.BooleanField(u'Контактная информация', default=True) show_real_address = models.BooleanField(u'Фактический адрес', default=True) show_phone = models.BooleanField(u'Телефон', default=True) show_fax = models.BooleanField(u'Факс', default=True) show_email = models.BooleanField(u'Электронная почта', default=True) show_site = models.BooleanField(u'Сайт', default=True) # только для ИП show_ip_boss_fio = models.BooleanField(u'Фамилия, Имя, Отчество', default=True) show_svid_gos_reg = models.BooleanField(u'Свид-во о гос. регистрации', default=True) show_ip_reg_date = models.BooleanField(u'Дата регистрации ИП', default=True) # только для Организации show_name = models.BooleanField(u'Краткое название организации', default=True) show_full_name = models.BooleanField(u'Полное название организации', default=True) show_kpp = models.BooleanField(u'КПП', default=True) show_org_boss_title_and_fio = models.BooleanField(u'Руководитель (Должность, ФИО)', default=True) show_na_osnovanii = models.BooleanField(u'Действует на основании', default=True) show_jur_address = models.BooleanField(u'Юридический адрес', default=True) objects = managers.UserProfileFiltersManager() class Meta: verbose_name = u'Фильтры реквизитов' verbose_name_plural = u'Фильтры реквизитов' def __unicode__(self): return u'%s' % self.user.email def save(self, *args, **kwargs): # всегда включены self.show_ip_boss_fio = True self.show_name = True super(UserProfileFilters, self).save(*args, **kwargs)