From 6ca840079a32a070d0693dd32f579dfa58121344 Mon Sep 17 00:00:00 2001
From: Mukhtar
Date: Mon, 22 Aug 2016 16:42:14 +0300
Subject: [PATCH] #ARC-16 add fixes
---
.gitignore | 1 +
assets/js/chat.js | 68 +++++++++++++------
chat/{testapp.py => chat.py} | 16 +----
chat/settings.example.py | 19 ++++++
chat/templates/chat_contractor.html | 6 +-
chat/templates/chat_customer.html | 54 +++++++--------
chat/templates/reverse_stage_modal.html | 61 +++++++++++++++++
chat/urls.py | 2 +
chat/views.py | 18 +++--
common/management/commands/__init__.py | 0
.../management/commands/delete_old_files.py | 29 ++++++++
reviews/migrations/0005_auto_20160822_1600.py | 37 ++++++++++
wallets/admin.py | 7 +-
wallets/migrations/0008_wallet.py | 25 +++++++
wallets/models.py | 8 +++
wallets/signals.py | 18 ++++-
16 files changed, 297 insertions(+), 72 deletions(-)
rename chat/{testapp.py => chat.py} (87%)
create mode 100644 chat/settings.example.py
create mode 100644 chat/templates/reverse_stage_modal.html
create mode 100644 common/management/commands/__init__.py
create mode 100644 common/management/commands/delete_old_files.py
create mode 100644 reviews/migrations/0005_auto_20160822_1600.py
create mode 100644 wallets/migrations/0008_wallet.py
diff --git a/.gitignore b/.gitignore
index b7f1121..5ac6b08 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,5 @@ env/
ar/
archilance/settings/local.py
media/
+chat/settings.py
todo/
diff --git a/assets/js/chat.js b/assets/js/chat.js
index 1a91812..b7fca99 100644
--- a/assets/js/chat.js
+++ b/assets/js/chat.js
@@ -19,10 +19,10 @@ var SocketHandler = function () {
inbox = document.getElementById('message-chat-order-space');
} else if (message.answer_type == 'add_message_team') {
inbox = document.getElementById('message-chat-team-space');
- }else if (message.answer_type == 'approve_stages') {
+ } else if (message.answer_type == 'approve_stages') {
alert('approve stages');
}
- if(inbox) {
+ if (inbox) {
inbox.innerHTML += '';
@@ -39,7 +39,7 @@ var SocketHandler = function () {
console.log(data);
};
- this.send_stages_approve = function(data){
+ this.send_stages_approve = function (data) {
sock.send(JSON.stringify(data));
console.log(data);
};
@@ -84,26 +84,56 @@ function csrfSafeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
-$(function(){
+$(function () {
+
+ $('.deleteMess').on('click', function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ var senderId = userId;
+ var recipentId = $(this).attr('data-recipent-id');
+ var _this = $(this);
+ $.ajax({
+ url: '/chat/messages_delete/',
+ type: 'POST',
+ beforeSend: function (xhr) {
+ xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
+ },
+ data: {'sender_id':senderId, 'recipent_id': recipentId},
+ dataType: 'json',
+ success: function (json) {
+ if (json.status == 'ok'){
+ _this.parent().remove();
+ $("#message-chat-space").html("");
+ }
+
+ },
+ error: function (e) {
+ console.log('error');
+ console.log(e);
+ }
+ });
+ });
+
+
$('#add-note-contractor').on('click', function (e) {
e.preventDefault();
$.ajax({
url: '/api/note/',
- type: 'POST',
- beforeSend: function (xhr) {
- xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
- },
- data: $("#add-form-contractor-note").serialize(),
- dataType: 'json',
- success: function (json) {
- console.log(json);
- $("#add-form-contractor-note #chat2").val("");
- $('' + json.text + '').appendTo(".contractor-notes-block");
- },
- error: function (e) {
- console.log('error');
- console.log(e);
- }
+ type: 'POST',
+ beforeSend: function (xhr) {
+ xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
+ },
+ data: $("#add-form-contractor-note").serialize(),
+ dataType: 'json',
+ success: function (json) {
+ console.log(json);
+ $("#add-form-contractor-note #chat2").val("");
+ $('' + json.text + '').appendTo(".contractor-notes-block");
+ },
+ error: function (e) {
+ console.log('error');
+ console.log(e);
+ }
});
});
});
diff --git a/chat/testapp.py b/chat/chat.py
similarity index 87%
rename from chat/testapp.py
rename to chat/chat.py
index 61fe46d..bc54fe1 100644
--- a/chat/testapp.py
+++ b/chat/chat.py
@@ -3,22 +3,12 @@ from tornado import gen, web, websocket, escape, options
from tornado.ioloop import IOLoop
from tornado.httpserver import HTTPServer
from tornado.options import parse_command_line
+from settings import settings, PORT, DATABASE_DSN
import psycopg2
import momoko
import json
-settings = {
- 'cookie_secret': '__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__',
- 'template_path': os.path.join(os.path.dirname(__file__), 'templates'),
- 'static_path': os.path.join(os.path.dirname(__file__), 'static'),
- 'login_url': '/login',
- 'xsrf_cookies': True,
- 'debug': True,
- 'autoreload': True,
- 'server_traceback': True,
-}
-
class BaseHandler(web.RequestHandler):
@property
@@ -105,7 +95,7 @@ if __name__ == '__main__':
ioloop = IOLoop.instance()
application.db = momoko.Pool(
- dsn='dbname=archilance user=postgres password=postgres host=localhost',
+ dsn=DATABASE_DSN,
size=1,
ioloop=ioloop,
)
@@ -115,5 +105,5 @@ if __name__ == '__main__':
future.result()
http_server = HTTPServer(application)
- http_server.listen(8888, 'localhost')
+ http_server.listen(PORT, 'localhost')
ioloop.start()
diff --git a/chat/settings.example.py b/chat/settings.example.py
new file mode 100644
index 0000000..c846c65
--- /dev/null
+++ b/chat/settings.example.py
@@ -0,0 +1,19 @@
+import os
+
+PORT = 8888
+
+settings = {
+ 'cookie_secret': '__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__',
+ 'template_path': os.path.join(os.path.dirname(__file__), 'templates'),
+ 'static_path': os.path.join(os.path.dirname(__file__), 'static'),
+ 'login_url': '/login',
+ 'xsrf_cookies': True,
+ 'debug': True,
+ 'autoreload': True,
+ 'server_traceback': True,
+}
+
+
+DATABASE_DSN = 'dbname=archilance user=postgres password=postgres host=localhost'
+
+
diff --git a/chat/templates/chat_contractor.html b/chat/templates/chat_contractor.html
index f651d77..f41dda4 100644
--- a/chat/templates/chat_contractor.html
+++ b/chat/templates/chat_contractor.html
@@ -53,7 +53,7 @@
Контакты
0
-
+
Удалить контакт
@@ -450,9 +450,9 @@
$.each(json.results, function (i, v) {
if (v.is_paid) {
- stagesReservedHtml += 'Сумма за этап ' + i + '.Зарезервирована.';
+ stagesReservedHtml += 'Сумма за этап ' + v.pos + '.Зарезервирована.';
} else {
- stagesReservedHtml += 'Сумма за этап ' + i + '.Не зарезервирована.';
+ stagesReservedHtml += 'Сумма за этап ' + v.pos + '.Не зарезервирована.';
}
htmlInbox += '' +
'
Этап ' + v.pos + '' + v.name + '
' +
diff --git a/chat/templates/chat_customer.html b/chat/templates/chat_customer.html
index 6b3ad27..12c4df7 100644
--- a/chat/templates/chat_customer.html
+++ b/chat/templates/chat_customer.html
@@ -48,7 +48,7 @@
class="conMess">Контакты
0
-
+
Удалить контакт
@@ -159,37 +159,14 @@
-
-
+ {% include 'reverse_stage_modal.html' %}
+
3 / Выполнение работы
@@ -290,6 +267,20 @@
var form = document.getElementById('message_form');
var csrftoken = getCookie('csrftoken');
+ $("#reserve-button").on("click",function(e) {
+ e.preventDefault();
+ var orderId = $(this).attr('data-order-id');
+ $.ajax({
+ url: '/api/stages/',
+ type: 'GET',
+ data: {csrfmiddlewaretoken: csrftoken, 'order': orderId},
+ dataType: 'json',
+ success: function (json) {
+ console.log(json.results);
+ }
+ });
+ });
+
function getStages(orderId, senderId, recipentId) {
$.ajax({
@@ -318,6 +309,7 @@
'
' +
'
' +
'
' +
+ '
' +
'
';
}
var statusNotAgreed = true;
@@ -337,7 +329,7 @@
htmlInbox += '' +
'
Этап ' + v.pos + '' + v.name + '
' +
'
Результаты этапа:' + v.result + '
' +
- '
до 16.03.2015
' + v.cost + ' ';
+ 'до Дата
' + v.cost + '';
}
});
@@ -430,15 +422,17 @@
if (countStage > currentCountStage){
for(var jj=currentCountStage; jjЭтап 1
';
lastFormStage.after(addFormTemplate);
@@ -481,6 +475,7 @@
var recipentId = $(this).attr('data-recipent-id');
$("#chat-order-add #orderId").val(orderId);
$("#projectReviewId").val(orderId);
+ $("#reserve-button").attr('data-order-id', orderId);
$("#targetContractorId").val(recipentId);
$("#chat-order-add #recipentId").val(recipentId);
$(".orderStagesInput").val(orderId);
@@ -550,7 +545,6 @@
});
-
$('#contact-chat-add-message').on('click', function () {
var chatMessage = $("#chat").val();
var recipentId = $("#recipentId").val();
diff --git a/chat/templates/reverse_stage_modal.html b/chat/templates/reverse_stage_modal.html
new file mode 100644
index 0000000..2c483ff
--- /dev/null
+++ b/chat/templates/reverse_stage_modal.html
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
Сумма оплаты всего заказа
+
+ Общий бюджет заказа: 300 р.
+ Итого к оплате: 344 рубля
+
+
+
+
+
+
+
+
Оплатить этап
+
+ Бюджет Этапа 1: 300 р.
+ Итого к оплате: 344 р.
+
+
+
+
+
+
+
+
+
+
Резервирование средств
+
+
+
+
+
+
+
+
+
diff --git a/chat/urls.py b/chat/urls.py
index aa77baa..d37d00f 100644
--- a/chat/urls.py
+++ b/chat/urls.py
@@ -2,10 +2,12 @@ from django.conf import urls
from .views import (
ChatUserView,
+ messages_delete,
)
app_name = 'chat'
urlpatterns = [
urls.url(r'^$', ChatUserView.as_view(), name='chat-user'),
+ urls.url(r'^messages_delete/$', messages_delete, name='chat-messages_delete'),
]
diff --git a/chat/views.py b/chat/views.py
index 0ac8ecb..ad0fba5 100644
--- a/chat/views.py
+++ b/chat/views.py
@@ -1,12 +1,11 @@
+import json
from django.shortcuts import render
from django.views.generic import View
+from django.http import HttpResponse, Http404
from django.db.models import Q
-from django.forms import formset_factory
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Message
-from .forms import ArticleForm
-from reviews.forms import Review
from users.models import User
@@ -68,5 +67,14 @@ class ChatUserView(LoginRequiredMixin, View):
})
-
-
+def messages_delete(request):
+ if request.is_ajax():
+ sender = request.POST.get('sender_id')
+ recipent = request.POST.get('recipent_id')
+ queryset = Message.objects.all()
+ # queryset = queryset.filter(Q(sender__in=[sender,recipent]),Q(recipent__in=[sender,recipent]))
+ # queryset.delete()
+ data = {'status': 'ok'}
+ return HttpResponse(json.dumps(data), content_type='application/json')
+ else:
+ raise Http404
diff --git a/common/management/commands/__init__.py b/common/management/commands/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/common/management/commands/delete_old_files.py b/common/management/commands/delete_old_files.py
new file mode 100644
index 0000000..1bb0333
--- /dev/null
+++ b/common/management/commands/delete_old_files.py
@@ -0,0 +1,29 @@
+import os
+import datetime
+from django.core.management import BaseCommand
+from django.conf import settings
+
+
+class Command(BaseCommand):
+
+ def handle(self, *args, **options):
+ days = 20
+ directory = os.path.join(settings.MEDIA_ROOT,'common/printdocuments')
+ files_list = []
+ date_now = datetime.datetime.now()
+ for root, subfolders, files in os.walk(directory):
+ for f in files:
+ files_list.append(os.path.join(root,f))
+
+ for f in files_list:
+ try:
+ date_modify = datetime.datetime.fromtimestamp(os.path.getmtime(f))
+ days_diff = (date_now-date_modify).days
+ if days_diff > days:
+ os.remove(f)
+ except OSError as e:
+ print(e.strerror + " " + e.filename)
+
+
+
+
diff --git a/reviews/migrations/0005_auto_20160822_1600.py b/reviews/migrations/0005_auto_20160822_1600.py
new file mode 100644
index 0000000..846f6ed
--- /dev/null
+++ b/reviews/migrations/0005_auto_20160822_1600.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-08-22 13:00
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('reviews', '0004_auto_20160811_1507'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='review',
+ name='from_contractor',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='contractor_reviews', to=settings.AUTH_USER_MODEL),
+ ),
+ migrations.AlterField(
+ model_name='review',
+ name='from_customer',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='customer_reviews', to=settings.AUTH_USER_MODEL),
+ ),
+ migrations.AlterField(
+ model_name='review',
+ name='target_contractor',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reviews_by_contractor', to=settings.AUTH_USER_MODEL),
+ ),
+ migrations.AlterField(
+ model_name='review',
+ name='target_customer',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='reviews_by_customer', to=settings.AUTH_USER_MODEL),
+ ),
+ ]
diff --git a/wallets/admin.py b/wallets/admin.py
index ce2eb8f..b767137 100644
--- a/wallets/admin.py
+++ b/wallets/admin.py
@@ -1,6 +1,6 @@
from django.contrib import admin
-from .models import InvoiceHistory, WithDraw
+from .models import InvoiceHistory, WithDraw, Transaction
class InvoiceHistoryAdmin(admin.ModelAdmin):
@@ -11,5 +11,10 @@ class WithDrawAdmin(admin.ModelAdmin):
list_display = ('sum','created','user',)
+class TransactionAdmin(admin.ModelAdmin):
+ list_display = ('customer','complete',)
+
+
admin.site.register(InvoiceHistory, InvoiceHistoryAdmin)
admin.site.register(WithDraw, WithDrawAdmin)
+admin.site.register(Transaction, TransactionAdmin)
diff --git a/wallets/migrations/0008_wallet.py b/wallets/migrations/0008_wallet.py
new file mode 100644
index 0000000..b959891
--- /dev/null
+++ b/wallets/migrations/0008_wallet.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-08-22 13:00
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('users', '0011_auto_20160819_1735'),
+ ('wallets', '0007_auto_20160818_2131'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Wallet',
+ fields=[
+ ('customer', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)),
+ ('balance', models.DecimalField(decimal_places=0, default=0, max_digits=10)),
+ ],
+ ),
+ ]
diff --git a/wallets/models.py b/wallets/models.py
index 2a0d8ef..bebbc19 100644
--- a/wallets/models.py
+++ b/wallets/models.py
@@ -11,6 +11,14 @@ TYPES = (
)
+class Wallet(models.Model):
+ customer = models.OneToOneField(User, on_delete=models.CASCADE,primary_key=True)
+ balance = models.DecimalField(max_digits=10, decimal_places=0, default=0)
+
+ def __str__(self):
+ return str(self.balance)
+
+
class InvoiceHistory(models.Model):
comment = models.TextField(blank=True)
created = models.DateTimeField(default=timezone.now)
diff --git a/wallets/signals.py b/wallets/signals.py
index ec3b071..be2fbac 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
+from .models import WithDraw, InvoiceHistory, Transaction
@receiver(post_save, sender=WithDraw)
@@ -20,3 +20,19 @@ def send_for_accountant(sender, instance, created, **kwargs):
msg.send()
+@receiver(post_save, sender=Transaction)
+def add_invoice_history(sender, instance,created, **kwargs):
+ if 'add' in instance.type:
+ inv_history = InvoiceHistory()
+ inv_history.comment = 'Пополнение счета'
+ inv_history.sum = instance.sum
+ inv_history.user = instance.user
+ inv_history.save()
+
+
+@receiver(post_save, sender=Transaction)
+def reserve_stages(sender, instance, created, **kwargs):
+ if 'reservation' in instance.type:
+ pass
+
+