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.
 
 
 
 
 
 

294 lines
11 KiB

from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.db.models import Q
from django.utils import timezone
from mptt.models import TreeForeignKey
import pydash as _; _.map = _.map_; _.filter = _.filter_
from users.models import User, Team
from specializations.models import Specialization
CURRENCIES = (
('rur', 'RUR'),
('usd', 'USD'),
('eur', 'EUR'),
)
TERMS = (
('project', 'За проект'),
('hour', 'За час'),
('day', 'За день'),
('month', 'За месяц'),
)
class BuildingClassfication(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
class Meta:
verbose_name = 'Тип здания'
verbose_name_plural = 'Типы зданий'
class ConstructionType(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
class Meta:
verbose_name = 'Вид строительства'
verbose_name_plural = 'Виды строительства'
class Realty(models.Model):
building_classification = models.ForeignKey(BuildingClassfication, related_name='realties')
construction_type = models.ForeignKey(ConstructionType, related_name='realties')
location = TreeForeignKey('common.Location', related_name='realties', null=True, blank=True)
name = models.CharField(max_length=255)
user = models.ForeignKey(User, related_name='realties') # Do we actually need this field?
def __str__(self):
return self.name
class Meta:
verbose_name = 'Объект'
verbose_name_plural = 'Объекты'
class Project(models.Model):
WORK_TYPES = (
(1, 'Проектирование'),
(2, 'Техническое сопровождение')
)
DEAL_TYPES = (
('secure_deal', 'Безопасная сделка'), # "Безопасная сделка (с резервированием бюджета)"
('direct_payment', 'Прямая оплата'), # "Прямая оплата Исполнителю на его кошелек/счет"
)
STATES = (
('active', 'Активный'),
('trashed', 'В корзине'),
('deleted', 'Удален'),
)
budget = models.DecimalField(max_digits=10, decimal_places=0)
budget_by_agreement = models.BooleanField(default=False)
created = models.DateTimeField(default=timezone.now)
cro = models.BooleanField(default=False)
currency = models.CharField(max_length=20, default='rur', choices=CURRENCIES)
customer = models.ForeignKey(User, related_name='projects')
deal_type = models.CharField(max_length=20, default='secure_deal', choices=DEAL_TYPES)
name = models.CharField(max_length=255)
price_and_term_required = models.BooleanField(default=False)
realty = models.ForeignKey(Realty, blank=True, null=True, related_name='projects')
rejected_answers_count = models.PositiveIntegerField(default=0)
specialization = TreeForeignKey(Specialization, related_name='projects')
state = models.CharField(default='active', max_length=20, choices=STATES)
term = models.IntegerField(default=0)
term_type = models.CharField(max_length=20, choices=TERMS, default='hour')
text = models.TextField(blank=True)
work_type = models.IntegerField(default=1, choices=WORK_TYPES)
def __str__(self):
return self.name
class Meta:
verbose_name = 'Проект'
verbose_name_plural = 'Проекты'
def secure_deal(self):
return self.deal_type == 'secure_deal'
def get_team_answers(self):
return _.filter(self.answers.all(), lambda a: isinstance(a.author, Team))
class ProjectFile(models.Model):
file = models.FileField(upload_to='projects/project_files')
project = models.ForeignKey(Project, related_name='files', blank=True, null=True)
class Meta:
verbose_name = 'Файл проекта'
verbose_name_plural = 'Файлы проектов'
def __str__(self):
return self.file and self.file.url or self.pk
class Answer(models.Model):
budget = models.DecimalField(max_digits=10, decimal_places=0, blank=True, null=True)
created = models.DateTimeField(default=timezone.now)
currency = models.CharField(max_length=5, choices=CURRENCIES, blank=True, null=True)
portfolios = models.ManyToManyField('Portfolio', related_name ='answers', blank=True)
project = models.ForeignKey(Project, related_name='answers')
secure_deal_only = models.BooleanField(default=False)
term = models.IntegerField(blank=True, null=True)
term_type = models.CharField(max_length=10, choices=TERMS, blank=True, null=True)
is_archive = models.BooleanField(default=False)
content_type = models.ForeignKey(ContentType, limit_choices_to=Q(app_label='users', model='user') | Q(app_label='users', model='team'))
object_id = models.IntegerField()
author = GenericForeignKey('content_type', 'object_id')
def get_first_message(self):
return self.messages.first().text
def get_term_type_labels(self):
term_type_labels = {
'hour': 'час,часа,часов',
'day': 'день,дня,дней',
'month': 'месяц,мксяца,месяцев',
'project': 'проект,проект,проект'
}
return term_type_labels.get(self.term_type)
def __str__(self):
return "{author}'s answer ({id})".format(author=type(self.author).__name__, id=self.pk)
class Meta:
verbose_name = 'Отклик на проект'
verbose_name_plural = 'Отклики на проекты'
ordering = ('-created',)
class AnswerMessage(models.Model):
answer = models.ForeignKey(Answer, related_name='messages')
created = models.DateTimeField(default=timezone.now)
is_sender_customer = models.BooleanField(default=False)
text = models.TextField()
content_type = models.ForeignKey(
ContentType,
limit_choices_to=Q(app_label='users', model='user') | Q(app_label='users', model='team'),
null=True,
blank=True,
)
object_id = models.IntegerField(null=True, blank=True)
contractor_or_team = GenericForeignKey('content_type', 'object_id')
def __str__(self):
return str(self.pk)
class Meta:
ordering = ['created']
verbose_name = 'Отклики на проекты -- переписка'
verbose_name_plural = 'Отклики на проекты -- переписки'
class AnswerFile(models.Model):
answer = models.ForeignKey(Answer, related_name='files', blank=True, null=True)
name = models.CharField(max_length=255)
file = models.FileField(upload_to='projects/answer_files')
class Meta:
verbose_name = 'Файл для отклика'
verbose_name_plural = 'Файлы для откликов'
def __str__(self):
return self.file and self.file.url or self.pk
class Order(models.Model):
contractor = models.ForeignKey(User, null=True, blank=True, related_name='orders')
team = models.ForeignKey(Team, null=True, blank=True, related_name='orders')
created = models.DateTimeField(default=timezone.now)
project = models.OneToOneField(Project, related_name='order')
secure = models.BooleanField(default=False)
status = models.BooleanField(default=False)
def __str__(self):
return self.project.name
class Meta:
verbose_name = 'Заказ'
verbose_name_plural = 'Заказы'
STATUSES = (
('not_agreed','Не согласован'),
('in_process','В процессе'),
('completed','Завершен'),
)
class Stage(models.Model):
cost = models.DecimalField(max_digits=10, decimal_places=0)
cost_type = models.CharField(max_length=5, choices=CURRENCIES, default='rur')
name = models.CharField(max_length=255)
order = models.ForeignKey(Order, related_name='stages')
result = models.CharField(max_length=255)
term = models.IntegerField(default=0)
term_type = models.CharField(max_length=10, choices=TERMS, default='hour')
status = models.CharField(choices=STATUSES, max_length=30, default='not_agreed')
created = models.DateTimeField(default=timezone.now)
pos = models.IntegerField(default=0, null=True, blank=True)
is_paid = models.BooleanField(default=False)
def __str__(self):
return self.name
class Meta:
ordering = ['pos']
verbose_name = 'Этап'
verbose_name_plural = 'Этапы'
class Candidate(models.Model):
answer = models.ForeignKey(Answer, related_name='candidates')
project = models.ForeignKey(Project, related_name='candidates')
status = models.BooleanField(default=False)
position = models.PositiveIntegerField(default=0)
def __str__(self):
return str(self.answer.pk)
class Meta:
ordering = ('position',)
verbose_name = 'Кандидат'
verbose_name_plural = 'Кандидаты'
class Portfolio(models.Model):
budget = models.DecimalField(max_digits=10, decimal_places=0, default=0, null=True, blank=True)
building_classification = models.ForeignKey(BuildingClassfication, related_name='portfolios', null=True, blank=True)
construction_type = models.ForeignKey(ConstructionType, related_name='portfolios', null=True, blank=True)
currency = models.CharField(max_length=20, default='rur', choices=CURRENCIES, null=True, blank=True)
description = models.TextField()
location = TreeForeignKey('common.Location', related_name='portfolios', null=True, blank=True)
name = models.CharField(max_length=255)
specialization = TreeForeignKey(Specialization, related_name='portfolios', null=True, blank=True)
term = models.IntegerField(default=0, null=True, blank=True)
term_type = models.CharField(max_length=20, choices=TERMS, default='hour', null=True, blank=True)
user = models.ForeignKey(User, related_name='portfolios', null=True, blank=True)
worksell = models.BooleanField(default=False)
def __str__(self):
return self.name
class Meta:
verbose_name = 'Портфолио'
verbose_name_plural = 'Портфолио'
def get_cover(self):
photo = self.photos.first()
return photo and photo.img
class PortfolioPhoto(models.Model):
img = models.ImageField(upload_to='projects/portfolio')
portfolio = models.ForeignKey(Portfolio, related_name='photos')
class Meta:
verbose_name = 'Фото портфолио'
verbose_name_plural = 'Фото портфолио'
def __str__(self):
return self.img and self.img.url or str(self.img)