diff --git a/archilance/management/commands/generate_portfolios.py b/archilance/management/commands/generate_portfolios.py index abd307c..2945567 100644 --- a/archilance/management/commands/generate_portfolios.py +++ b/archilance/management/commands/generate_portfolios.py @@ -7,7 +7,7 @@ import random from archilance import util from common.models import Location -from projects.models import Portfolio, PortfolioPhoto, CURRENCIES, TERMS, BuildingClassfication , ConstructionType +from projects.models import Portfolio, PortfolioPhoto, CURRENCIES, TERM_TYPES, BuildingClassfication , ConstructionType from specializations.models import Specialization from users.models import User, Team, GENDERS @@ -42,7 +42,7 @@ class Command(BaseCommand): budget=util.random_amount(), currency=_.sample(CURRENCIES)[0], term=_.random(0, 20), - term_type=_.sample(TERMS)[0], + term_type=_.sample(TERM_TYPES)[0], worksell=_.sample((True, False)), ) diff --git a/archilance/management/commands/generate_projects.py b/archilance/management/commands/generate_projects.py index 49daa9b..18ad4b2 100644 --- a/archilance/management/commands/generate_projects.py +++ b/archilance/management/commands/generate_projects.py @@ -6,7 +6,7 @@ import pydash as _; _.map = _.map_; _.filter = _.filter_ import random from archilance import util -from projects.models import Project, Order, CURRENCIES, TERMS, Specialization, Realty +from projects.models import Project, Order, CURRENCIES, TERM_TYPES, Specialization, Realty from users.models import User @@ -62,7 +62,7 @@ class Command(BaseCommand): price_and_term_required=_.sample((True, False)), deal_type=_.sample(Project.DEAL_TYPES)[0], term=_.random(0, 20), - term_type=_.sample(TERMS)[0], + term_type=_.sample(TERM_TYPES)[0], text=util.lorem(_.random(5, 30)), work_type=_.sample(Project.WORK_TYPES)[0], state='active', diff --git a/archilance/management/commands/generate_work_sells.py b/archilance/management/commands/generate_work_sells.py index daef0ec..9992356 100644 --- a/archilance/management/commands/generate_work_sells.py +++ b/archilance/management/commands/generate_work_sells.py @@ -7,7 +7,7 @@ import random from archilance import util from common.models import Location -from projects.models import TERMS, CURRENCIES, BuildingClassfication, ConstructionType +from projects.models import TERM_TYPES, CURRENCIES, BuildingClassfication, ConstructionType from specializations.models import Specialization from users.models import User from work_sell.models import WorkSell, WorkSellPhoto @@ -27,7 +27,7 @@ class Command(BaseCommand): description=util.lorem(), name=util.lorem(words=_.random(2, 20), sentences=1), term=_.random(0, 20), - term_type=_.sample(TERMS)[0], + term_type=_.sample(TERM_TYPES)[0], ) ws.save() diff --git a/archilance/management/commands/tmp.py b/archilance/management/commands/tmp.py index 751c975..8583603 100644 --- a/archilance/management/commands/tmp.py +++ b/archilance/management/commands/tmp.py @@ -7,7 +7,7 @@ import random from archilance import util from common.models import Location -from projects.models import Project, Order, CURRENCIES, TERMS, Specialization, Realty +from projects.models import Project, Order, CURRENCIES, TERM_TYPES, Specialization, Realty from users.models import User, Team diff --git a/archilance/mixins.py b/archilance/mixins.py index f55cc5e..0a80895 100644 --- a/archilance/mixins.py +++ b/archilance/mixins.py @@ -17,7 +17,8 @@ class BaseMixin(ContextMixin): c['domain'] = Site.objects.get_current().domain - c['TEMPLATE_DEBUG'] = settings.TEMPLATE_DEBUG + c['TEMPLATE_DEBUG'] = getattr(settings, 'TEMPLATE_DEBUG', None) + c['TESTING'] = getattr(settings, 'TESTING', None) return c diff --git a/archilance/settings/base.py b/archilance/settings/base.py index 494299f..40003c7 100644 --- a/archilance/settings/base.py +++ b/archilance/settings/base.py @@ -14,7 +14,6 @@ SECRET_KEY = 'vb6@b9zj7^f!^+x*e8=e!oundyu1!e*&0i(3gu2xwo4%fx4h&n' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -TEMPLATE_DEBUG = True # Show debug info in templates. See `projects/templates/project_filter.html` ALLOWED_HOSTS = [] diff --git a/archilance/settings/dev.py b/archilance/settings/dev.py index a3da647..b095fbd 100644 --- a/archilance/settings/dev.py +++ b/archilance/settings/dev.py @@ -1,8 +1,5 @@ from .base import * -# AUTH_PASSWORD_VALIDATORS = [] - -# INSTALLED_APPS += ['debug_toolbar',] try: from .local import * except ImportError: diff --git a/archilance/settings/prod.py b/archilance/settings/prod.py index 4acb948..62f15c6 100644 --- a/archilance/settings/prod.py +++ b/archilance/settings/prod.py @@ -14,7 +14,6 @@ DATABASES = { DEBUG = True -TEMPLATE_DEBUG = True THUMBNAIL_DEBUG = True SECRET_KEY = 'vb6@b9zj7^f!^+x*e8=e!oundyu1!e*&0i(3gu2xwo4%fx4h&n' diff --git a/archilance/urls.py b/archilance/urls.py index 8c7bfa5..c50d9fd 100644 --- a/archilance/urls.py +++ b/archilance/urls.py @@ -5,7 +5,7 @@ from django.contrib import admin from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.views.generic import TemplateView -from .views import HomeTemplateView, TestChatTemplateView +from .views import HomeTemplateView, TestChatTemplateView, TestView from wallets.views import TmpCheckOrderView, TmpPaymentAvisoView from wagtail.wagtailadmin import urls as wagtailadmin_urls @@ -17,7 +17,7 @@ urlpatterns = [ url('', include('social.apps.django_app.urls', namespace='social')), url(r'^chattest/$', TestChatTemplateView.as_view()), url(r'^work_sell/', include('work_sell.urls')), - url(r'^test/$', TemplateView.as_view(template_name='test.html'), name='test'), + url(r'^test/$', TestView.as_view(), name='test'), url(r'^projects/', include('projects.urls')), url(r'^reviews/', include('reviews.urls')), url(r'^wallets/', include('wallets.urls')), diff --git a/archilance/views.py b/archilance/views.py index 6f4a147..963d02d 100644 --- a/archilance/views.py +++ b/archilance/views.py @@ -1,9 +1,15 @@ +from django.conf import settings +from django.contrib import messages +from django.core.exceptions import PermissionDenied from django.core.files.base import ContentFile -from django.shortcuts import render -from django.template.loader import render_to_string +from django.core.urlresolvers import reverse, reverse_lazy +from django.http import HttpResponseForbidden, JsonResponse, HttpResponseRedirect, HttpResponse, Http404 +from django.shortcuts import render, get_object_or_404, redirect from django.views.generic import TemplateView, View +from pprint import pprint, pformat import logging +from .mixins import BaseMixin from chat.models import Documents from common.models import MainPage, PrintDocuments from projects.models import Order @@ -11,12 +17,16 @@ from users.models import ContractorResumeFiles from work_sell.models import Picture -class HomeTemplateView(View): +class HomeTemplateView(BaseMixin, View): template_name = 'home.html' def get(self, request, *args, **kwargs): + context = self.get_context_data(**kwargs) + main_settings = MainPage.objects.get(pk=1) - return render(request, self.template_name, {'main_settings': main_settings}) + context['main_settings'] = main_settings + + return render(request, self.template_name, context) class TestChatTemplateView(View): @@ -36,3 +46,13 @@ class TestChatTemplateView(View): document.file = temp_file document.save() + +class TestView(BaseMixin, View): + template_name = 'test.html' + + def get(self, request, *args, **kwargs): + # context = self.get_context_data(**kwargs) + # context['foo'] = 'bar' + # return render(request, self.template_name, context) + + return redirect('projects:detail', pk=153) diff --git a/common/templatetags/common_tags.py b/common/templatetags/common_tags.py index 662f289..1f03ba0 100644 --- a/common/templatetags/common_tags.py +++ b/common/templatetags/common_tags.py @@ -115,4 +115,19 @@ def morph(number, words_string): return '%s %s' % (number, util.morph(number, words)) +@register.simple_tag +def fa_currency_classes(currency): + CURRENCIES = {'rur': 'rub', 'eur': 'eur', 'usd': 'usd'} + currency_class = CURRENCIES.get(currency) + + if currency_class: + return 'fa fa-%s' % currency_class + + +@register.filter +def get(dic, key): + if isinstance(dic, dict): + return dic.get(key) + + # import code; code.interact(local=dict(globals(), **locals())) diff --git a/projects/models.py b/projects/models.py index 95aff66..5136c1e 100644 --- a/projects/models.py +++ b/projects/models.py @@ -17,13 +17,20 @@ CURRENCIES = ( ('eur', 'EUR'), ) -TERMS = ( - ('project', 'За проект'), - ('hour', 'За час'), +TERM_TYPES = ( ('day', 'За день'), + ('hour', 'За час'), ('month', 'За месяц'), + ('project', 'За проект'), ) +TERM_TYPE_MORPHS = { + 'day': 'день,дня,дней', + 'hour': 'час,часа,часов', + 'month': 'месяц,месяца,месяцев', + 'project': 'проект,проекта,проектов' +} + class BuildingClassfication(models.Model): name = models.CharField(max_length=255) @@ -92,7 +99,7 @@ class Project(models.Model, HitCountMixin): 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') + term_type = models.CharField(max_length=20, choices=TERM_TYPES, default='hour') text = models.TextField(blank=True) work_type = models.IntegerField(default=1, choices=WORK_TYPES) @@ -131,7 +138,7 @@ class Answer(models.Model): 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) + term_type = models.CharField(max_length=10, choices=TERM_TYPES, blank=True, null=True) is_archive = models.BooleanField(default=False) rejected = models.BooleanField(default=False) @@ -141,15 +148,6 @@ class Answer(models.Model): 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) @@ -252,7 +250,7 @@ class Stage(models.Model): order = models.ForeignKey(Order, related_name='stages') result = models.CharField(max_length=255) term = models.DateField() - term_type = models.CharField(max_length=10, choices=TERMS, default='hour') + term_type = models.CharField(max_length=10, choices=TERM_TYPES, 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) @@ -270,8 +268,8 @@ class Stage(models.Model): class Candidate(models.Model): - answer = models.ForeignKey(Answer, related_name='candidates') - project = models.ForeignKey(Project, related_name='candidates') + answer = models.ForeignKey(Answer, related_name='candidates') # TODO: Swap to "OneToOneField" + project = models.ForeignKey(Project, related_name='candidates') # TODO: Remove this redundant field at all (we've got "candidate.answer.project") status = models.BooleanField(default=False) position = models.PositiveIntegerField(default=0) @@ -295,7 +293,7 @@ class Portfolio(models.Model): 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) + term_type = models.CharField(max_length=20, choices=TERM_TYPES, default='hour', null=True, blank=True) user = models.ForeignKey(User, related_name='portfolios', null=True, blank=True) worksell = models.BooleanField(default=False) diff --git a/projects/templates/comparison.html b/projects/templates/comparison.html index 2d3c835..eef4d49 100644 --- a/projects/templates/comparison.html +++ b/projects/templates/comparison.html @@ -33,20 +33,27 @@ {% for cand in object.candidates.all %} {{ cand.position }} + - {{ cand.answer.author.username }} + {% if cand.answer.author|class_name == 'User' %} + {{ cand.answer.author.get_full_name }} + {% elif cand.answer.author|class_name == 'Team' %} + {{ cand.answer.author.name }} + {% endif %} - {{ cand.answer.budget }} + {{ cand.answer.budget }} - {{ cand.answer.term }}
- {% morph_words cand.answer.term cand.answer.get_term_type_labels %} - + {% if cand.answer.term_type == 'project' %} + За проект + {% else %} + {% morph cand.answer.term TERM_TYPE_MORPHS|get:cand.answer.term_type %} + {% endif %} - + @@ -89,8 +96,9 @@
{% csrf_token %}
+ -
+
diff --git a/projects/templates/project_detail.html b/projects/templates/project_detail.html index 1801247..8015dfe 100644 --- a/projects/templates/project_detail.html +++ b/projects/templates/project_detail.html @@ -19,7 +19,7 @@ {% if request.user.is_contractor %}
-

{{ project.budget|intcomma }}

+

{{ project.budget|intcomma }}

{% endif %} @@ -237,10 +237,14 @@

Цена: {{ answer.budget|intcomma }} - +

- Срок: {{ answer.term }} {{ answer.get_currency_display }} {{ answer.get_term_type_display|decap }} + {% if answer.term_type == 'project' %} + Срок: За проект + {% else %} + Срок: {% morph answer.term TERM_TYPE_MORPHS|get:answer.term_type %} + {% endif %}

Опубликован: {{ answer.created|date:'M d, Y' }}

@@ -563,10 +567,14 @@

Цена: {{ answer.budget|intcomma }} - +

- Срок: {{ answer.term }} {{ answer.get_currency_display }} {{ answer.get_term_type_display|decap }} + {% if answer.term_type == 'project' %} + Срок: За проект + {% else %} + Срок: {% morph answer.term TERM_TYPE_MORPHS|get:answer.term_type %} + {% endif %}

Опубликован: {{ answer.created|date:'M d, Y' }}

@@ -695,7 +703,7 @@
{% if answer.author|class_name == 'User' %} - {% ratings_widget answer.author.pk 'restList2' %} + {% ratings_widget answer.author.pk 'restList2' %} {% elif answer.author|class_name == 'Team'%} {% ratings_team_widget answer.author.pk 'restList2' %} {% endif %} @@ -719,15 +727,25 @@

Цена: {{ answer.budget|intcomma }} - +

- Срок: {{ answer.term }} {{ answer.get_currency_display }} {{ answer.get_term_type_display|decap }} + {% if answer.term_type == 'project' %} + Срок: За проект + {% else %} + Срок: {% morph answer.term TERM_TYPE_MORPHS|get:answer.term_type %} + {% endif %}

Опубликован: {{ answer.created|date:'M d, Y' }}

+ {% if TESTING %} + + Кандидат + + {% endif %} + {% if not project.order.contractor and not project.order.team %}
{% csrf_token %} @@ -867,10 +885,14 @@

Цена: {{ answer.budget|intcomma }} - +

- Срок: {{ answer.term }} {{ answer.get_currency_display }} {{ answer.get_term_type_display|decap }} + {% if answer.term_type == 'project' %} + Срок: За проект + {% else %} + Срок: {% morph answer.term TERM_TYPE_MORPHS|get:answer.term_type %} + {% endif %}

Опубликован: {{ answer.created|date:'M d, Y' }}

diff --git a/projects/templates/project_filter.html b/projects/templates/project_filter.html index 8c446cf..45fcbff 100644 --- a/projects/templates/project_filter.html +++ b/projects/templates/project_filter.html @@ -214,7 +214,7 @@

- {{ project.budget }} + {{ project.budget }}