diff --git a/archilance/settings/base.py b/archilance/settings/base.py index b275586..61049ad 100644 --- a/archilance/settings/base.py +++ b/archilance/settings/base.py @@ -173,8 +173,8 @@ AUTHENTICATION_BACKENDS = ( # SOCIAL_AUTH_FACEBOOK_KEY = '222531191461451' # SOCIAL_AUTH_FACEBOOK_SECRET = '95e88f7ef396c5b803375f8476cf2ba4' -SOCIAL_AUTH_FACEBOOK_KEY = '1030546170341186' -SOCIAL_AUTH_FACEBOOK_SECRET = '1b22e95040b209c5d2f2d7f69462bf95' +SOCIAL_AUTH_FACEBOOK_KEY = '1047362798683484' +SOCIAL_AUTH_FACEBOOK_SECRET = '98fedcccb1cb941c2289692bd4de84da' SOCIAL_AUTH_FACEBOOK_SCOPE = ['email'] SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = { diff --git a/assets/js/chat.js b/assets/js/chat.js index eb7c649..392092f 100644 --- a/assets/js/chat.js +++ b/assets/js/chat.js @@ -168,7 +168,27 @@ $(function () { $("#paymentfromSite").on('click',function(){ var sum = $("#stageSumPay").val(); - alert(sum); + var stages = $("#stagesIds").val(); + var orderId = $("#ordermodalId").val(); + $.ajax({ + url: '/wallets/payfromscore/', + type: 'POST', + data: { + csrfmiddlewaretoken: csrftoken, + sum: sum, + stages_id: stages, + }, + dataType: 'json', + success: function (json) { + if(json.status == 'ok'){ + $("#reserve-stage-modal").modal('hide'); + $("#orderBlock" + orderId).trigger('click'); + } + }, + error: function(e, jqxhr){ + console.log(e); + } + }) }); diff --git a/chat/templates/chat_customer.html b/chat/templates/chat_customer.html index aea0348..9d1669d 100644 --- a/chat/templates/chat_customer.html +++ b/chat/templates/chat_customer.html @@ -286,12 +286,17 @@ $("#stagesSelect").html(outputValues); $(".totalSum").text(totalSum); + if(json.results.length>notPaidCount && notPaidCount>0){ $("#choiceWayOrder").hide(); } - $("#choiceWayOrder").val(totalSum) + + $("#choiceWayOrder").val(totalSum); + $("#ordermodalId").val(orderId); + $("#stages-pay-form #stageSumPay").val(totalSum); $("#stages-pay-form #stagesIds").val(stagesIds); + $("#choiceWayOrder").attr('data-stages-ids',stagesIds); } @@ -455,7 +460,6 @@ $("#stagesWork").html(stageWork); } - if (!data.secure){ $("#reserveSpace").hide(); } diff --git a/chat/templates/reverse_stage_modal.html b/chat/templates/reverse_stage_modal.html index 0074668..e761baf 100644 --- a/chat/templates/reverse_stage_modal.html +++ b/chat/templates/reverse_stage_modal.html @@ -55,6 +55,7 @@ + diff --git a/projects/migrations/0025_merge.py b/projects/migrations/0025_merge.py new file mode 100644 index 0000000..6a42e6a --- /dev/null +++ b/projects/migrations/0025_merge.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-02 07:45 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0024_auto_20160901_1247'), + ('projects', '0024_auto_20160901_1548'), + ] + + operations = [ + ] diff --git a/projects/serializers.py b/projects/serializers.py index a78bf2f..92f9b83 100755 --- a/projects/serializers.py +++ b/projects/serializers.py @@ -104,6 +104,7 @@ class ProjectSerializer(ModelSerializer): class OrderSerializer(ModelSerializer): stages = StageSerializer(many=True, read_only=True) project = ProjectSerializer(read_only=True) + has_user_review = serializers.SerializerMethodField(read_only=True) class Meta: model = Order @@ -116,10 +117,16 @@ class OrderSerializer(ModelSerializer): 'project', 'secure', 'status', + 'has_user_review', 'stages', 'project', ) + def get_has_user_review(self,obj): + # obj.project. + print(self.context['request'].user) + return "yes" + class PortfolioPhotoSerializer(ModelSerializer): img = ImageField() diff --git a/users/models.py b/users/models.py index ef4187d..6eba910 100644 --- a/users/models.py +++ b/users/models.py @@ -220,7 +220,7 @@ class User(AbstractBaseUser, PermissionsMixin): def get_popular_specialization(self): from ratings.models import SpecializationRating - return SpecializationRating.objects.filter(user=self).order_by('position').first().specialization.name + # return SpecializationRating.objects.filter(user=self).order_by('position').first().specialization.name class Team(models.Model): diff --git a/users/templates/contractor_office_chat_projects.html b/users/templates/contractor_office_chat_projects.html new file mode 100644 index 0000000..f3b1c54 --- /dev/null +++ b/users/templates/contractor_office_chat_projects.html @@ -0,0 +1,632 @@ +{% extends 'partials/base.html' %} + +{% load project_tags %} +{% load specializtions_tags %} +{% load thumbnail %} + + +{% block content %} + {% include 'partials/header.html' %} + +
+
+
+

Личный кабинет

+
+ + {% include 'partials/contractor_profile_tabs.html' %} + + +
+ + + +
+
+
+

Заказы

+ {% for order in orders %} +
+ +

{{ order }}

+
+

+ Исполнитель: + {% if order.order.contractor %} + {{ order.order.contractor.get_full_name }} + {% else %} + {{ order.order.team.name }} + {% endif %} +

+ + + Полное описание заказа + +
+
+ {% endfor %} +
+
+
+
+
+ + + + + +
+
+ +

Прикрепить файл

+
+
+ отправить +
+
+
+
+

Этапы работы

+
+

1 / Согласование условий

+

+ Обсуджение задания и условий выполнения работы. Подтверждение заказа исполнителем. +

+
+ +
+ + + + + {% include 'reverse_stage_modal.html' %} + + +
+

3 / Выполнение работы

+

+ Процесс выполнения задания в заказе до получения + заказчиком итогового результата работы. +

+
+
+ + + +
+

Входящие документы

+
    + {# #} + {# Распечатать с помощью ресурса#} + {# #} +
    + +
    +

    Для заметок

    + + сохранить +
    + + + {% include 'review_add_modal.html' %} + + + + {% include 'arbitration_modal.html' %} + + + + {% include 'order_info.html' %} + + + +
    +
    + + +
    + + {% include 'partials/footer.html' %} +
    +
    +{% endblock %} + + +{% block js_block %} + + + +{% endblock %} + diff --git a/users/templates/partials/contractor_profile_tabs.html b/users/templates/partials/contractor_profile_tabs.html index 23fc9ec..aa7d6cd 100644 --- a/users/templates/partials/contractor_profile_tabs.html +++ b/users/templates/partials/contractor_profile_tabs.html @@ -1,5 +1,6 @@ {% url 'users:contractor-office' pk=contractor.pk as contractor_office_url %} {% url 'users:contractor-office-open-projects' pk=contractor.pk as contractor_office_open_projects_url %} +{% url 'users:contractor-office-chat-projects' pk=contractor.pk as contractor_office_chat_projects_url %}
    -
  • - Проекты в работе +
  • + Проекты в работе
    0
    diff --git a/users/urls.py b/users/urls.py index 7868d83..9f0405d 100755 --- a/users/urls.py +++ b/users/urls.py @@ -16,6 +16,7 @@ from .views import ( TeamCreateView, UserFinancialInfoEditView, UserProfileEditView, + ContractorChatProjectsView, ) @@ -37,4 +38,5 @@ urlpatterns = [ urls.url(r'^contractors/(?P\d+)/$', ContractorProfileDetailView.as_view(), name='contractor-profile'), urls.url(r'^contractor-office/(?P\d+)/$', ContractorOfficeView.as_view(), name='contractor-office'), urls.url(r'^contractor-office/(?P\d+)/open-projects/$', ContractorOfficeProjectsView.as_view(), name='contractor-office-open-projects'), + urls.url(r'^contractor-office/(?P\d+)/work-projects/$', ContractorChatProjectsView.as_view(), name='contractor-office-chat-projects'), ] diff --git a/users/views.py b/users/views.py index 103ccf4..fa853d8 100644 --- a/users/views.py +++ b/users/views.py @@ -21,11 +21,12 @@ from .forms import TeamForm, ContractorResumeFilesForm, ContractorResumeForm from archilance import util from archilance.mixins import BaseMixin from projects.forms import PortfolioForm -from projects.models import Project, Portfolio +from projects.models import Project, Portfolio, Order from reviews.models import Review from specializations.models import Specialization from work_sell.forms import WorkSellForm from work_sell.models import WorkSell, Picture +from chat.models import Message from .forms import ( ContractorFilterForm, @@ -399,6 +400,38 @@ class ContractorOfficeView(DetailView): return context +class ContractorChatProjectsView(BaseMixin, View): + template_name = 'contractor_office_chat_projects.html' + + def get(self, request, *args, **kwargs): + context = self.get_context_data(**kwargs) + contractor = get_object_or_404(User.contractor_objects, pk=kwargs.get('pk')) + context['contractor'] = contractor + team_ids = [] + if request.user.is_owner_team(): + team_ids.append(request.user.team.pk) + team_orders = request.user.team.orders.all() + else: + teams = Team.objects.filter(contractors__id=request.user.pk).all() + team_orders = Order.objects.filter(team_id__in=[team.pk for team in teams]).all() + + orders = Order.objects.filter(Q(contractor=request.user) | Q(team_id__in=team_ids)).all() + contractor_contacts = Message.objects.values_list('sender_id', 'recipent_id').filter( + Q(recipent_id=request.user.pk) | Q(sender_id=request.user.pk)).filter(Q(team_id=None)).distinct() + users_ids = [] + for msg in contractor_contacts: + a, b = msg + if a != request.user.pk: + users_ids.append(a) + if b != request.user.pk: + users_ids.append(b) + # contacts_users = User.objects.filter(pk__in=users_ids) + chat_messages = Message.objects.filter(Q(sender=request.user.pk) | Q(recipent=request.user.pk)).order_by( + 'created') + context['orders'] = orders + return render(request, self.template_name, context) + + class ContractorOfficeProjectsView(BaseMixin, View): template_name = 'contractor_office_open_projects.html' diff --git a/wallets/admin.py b/wallets/admin.py index 2fd0bf9..1a4724b 100644 --- a/wallets/admin.py +++ b/wallets/admin.py @@ -2,7 +2,7 @@ from django.contrib import admin from import_export import resources from import_export.admin import ImportExportModelAdmin -from .models import InvoiceHistory, WithDraw, Transaction, Wallet +from .models import InvoiceHistory, WithDraw, Transaction, Wallet, PayFromScore class InvoiceHistoryAdmin(admin.ModelAdmin): @@ -28,3 +28,4 @@ admin.site.register(InvoiceHistory, InvoiceHistoryAdmin) admin.site.register(WithDraw, WithDrawAdmin) admin.site.register(Transaction, TransactionAdmin) admin.site.register(Wallet) +admin.site.register(PayFromScore) diff --git a/wallets/forms.py b/wallets/forms.py index d8afe1a..6433ffe 100644 --- a/wallets/forms.py +++ b/wallets/forms.py @@ -1,7 +1,7 @@ from django import forms from django.conf import settings -from .models import WithDraw +from .models import WithDraw, PayFromScore class WithDrawForm(forms.ModelForm): @@ -15,6 +15,16 @@ class WithDrawForm(forms.ModelForm): ) +class PayFromScoreForm(forms.ModelForm): + class Meta: + model = PayFromScore + + fields = ( + 'sum', + 'stages_id', + ) + + class TmpCheckOrderForm(forms.Form): action = forms.CharField() # Has to be "checkOrder" md5 = forms.CharField() diff --git a/wallets/migrations/0013_merge.py b/wallets/migrations/0013_merge.py new file mode 100644 index 0000000..2e5d621 --- /dev/null +++ b/wallets/migrations/0013_merge.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-02 07:45 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('wallets', '0012_auto_20160901_1247'), + ('wallets', '0012_auto_20160901_1548'), + ] + + operations = [ + ] diff --git a/wallets/migrations/0014_payfromscore.py b/wallets/migrations/0014_payfromscore.py new file mode 100644 index 0000000..4f37e19 --- /dev/null +++ b/wallets/migrations/0014_payfromscore.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-02 09:25 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('wallets', '0013_merge'), + ] + + operations = [ + migrations.CreateModel( + name='PayFromScore', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('sum', models.DecimalField(decimal_places=0, default=0, max_digits=20)), + ('stages_id', models.CharField(blank=True, max_length=100, null=True)), + ('created_at', models.DateTimeField(default=django.utils.timezone.now, editable=False)), + ('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='customer_payfromscore', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/wallets/models.py b/wallets/models.py index e97ead3..4687761 100644 --- a/wallets/models.py +++ b/wallets/models.py @@ -104,3 +104,18 @@ class Transaction(models.Model): def __str__(self): return str(self.pk) + + +class PayFromScore(models.Model): + customer = models.ForeignKey(User, related_name='customer_payfromscore') + sum = models.DecimalField(max_digits=20, decimal_places=0, default=0) + stages_id = models.CharField(max_length=100, null=True, blank=True) + created_at = models.DateTimeField(default=timezone.now, editable=False) + + def __str__(self): + return str(self.pk) + + class Meta: + ordering = ('-created_at',) + verbose_name = 'Оплата со счета' + verbose_name_plural = 'Оплата со счета' diff --git a/wallets/signals.py b/wallets/signals.py index e1fe37d..9b72b54 100644 --- a/wallets/signals.py +++ b/wallets/signals.py @@ -3,7 +3,7 @@ from django.dispatch import receiver from django.core.mail import send_mail, EmailMultiAlternatives from django.template.loader import get_template, render_to_string -from .models import WithDraw, InvoiceHistory, Transaction +from .models import WithDraw, InvoiceHistory, Transaction, PayFromScore from projects.models import Stage @@ -69,6 +69,28 @@ def reserve_stages(sender, instance, created, **kwargs): inv_history.save() +@receiver(post_save, sender=PayFromScore) +def reserve_stages(sender, instance, created, **kwargs): + order = None + stages_names = [] + stages_ids_raw = instance.stages_id + if stages_ids_raw: + stages_ids = [s for s in stages_ids_raw.split(';') if s] + for pk in stages_ids: + stage = Stage.objects.get(pk=pk) + stages_names.append(stage.name) + stage.is_paid = True + order = stage.order + stage.save() + + inv_history = InvoiceHistory() + inv_history.comment = 'Резервирование средств за этапы ' + ' , '.join(stages_names) + ' заказа' + str(order) + inv_history.sum = -instance.sum + inv_history.user = instance.customer + inv_history.type = "score" + inv_history.save() + + diff --git a/wallets/templates/score-test.html b/wallets/templates/score-test.html new file mode 100644 index 0000000..6abfb9f --- /dev/null +++ b/wallets/templates/score-test.html @@ -0,0 +1 @@ +

    Ваш счет: {{ score }}

    diff --git a/wallets/urls.py b/wallets/urls.py index 082abeb..42d5f3b 100755 --- a/wallets/urls.py +++ b/wallets/urls.py @@ -1,7 +1,7 @@ from django.conf import urls, settings from django.views.generic import TemplateView -from .views import ScoreDetailView, WithDrawCreate, ScoreView +from .views import PayFromScore, WithDrawCreate, ScoreView app_name = 'wallets' @@ -10,7 +10,8 @@ urlpatterns = [ # urls.url(r'^score/(?P\d+)/$', ScoreDetailView.as_view(), name='score-detail'), urls.url(r'^score/(?P\d+)/$', ScoreView.as_view(), name='score-detail'), urls.url(r'^withdraw/create/$', WithDrawCreate.as_view(), name='withdraw-create'), - + urls.url(r'^payfromscore/$', PayFromScore.as_view(), name='payfromscore'), + urls.url( r'^tmp-yamoney-req/$', TemplateView.as_view(template_name='tmp_yandex_money_request_example.html'), diff --git a/wallets/views.py b/wallets/views.py index 5211b51..37baf39 100644 --- a/wallets/views.py +++ b/wallets/views.py @@ -13,8 +13,34 @@ from django.views.generic.base import View import logging from users.models import User -from .forms import WithDrawForm, TmpCheckOrderForm, TmpPaymentAvisoForm -from .models import InvoiceHistory, WithDraw, Transaction +from .forms import WithDrawForm, TmpCheckOrderForm, TmpPaymentAvisoForm, PayFromScoreForm +from .models import InvoiceHistory, WithDraw, Transaction, PayFromScore + + +class PayFromScore(CreateView): + model = PayFromScore + form_class = PayFromScoreForm + + def form_valid(self, form): + if self.request.is_ajax(): + self.object = form.save(commit=False) + self.object.customer = self.request.user + self.object.save() + data = { + 'pk': self.object.pk, + 'status': 'ok', + } + return JsonResponse(data) + return super().form_valid(form) + + def form_invalid(self, form): + if self.request.is_ajax(): + data = { + 'errors': form.errors, + 'status': 'error', + } + return JsonResponse(data) + return super().form_invalid(form) class ScoreDetailView(DetailView): diff --git a/work_sell/migrations/0010_merge.py b/work_sell/migrations/0010_merge.py new file mode 100644 index 0000000..3c72952 --- /dev/null +++ b/work_sell/migrations/0010_merge.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-02 07:45 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('work_sell', '0009_auto_20160901_1548'), + ('work_sell', '0009_auto_20160901_1247'), + ] + + operations = [ + ]