#ARC-7 Add email send for accountant in signals.py

remotes/origin/setup
Mukhtar 10 years ago
parent 7c39828a4f
commit 833491f8c1
  1. 2
      archilance/settings/base.py
  2. 2
      chat/testapp.py
  3. 20
      common/migrations/0005_settings_accountant_send_email.py
  4. 1
      common/models.py
  5. 2
      common/views.py
  6. 6
      users/mixins.py
  7. 14
      wallets/admin.py
  8. 13
      wallets/forms.py
  9. 20
      wallets/migrations/0004_invoicehistory_balance.py
  10. 43
      wallets/migrations/0005_auto_20160809_1727.py
  11. 28
      wallets/models.py
  12. 20
      wallets/signals.py
  13. 169
      wallets/templates/score-detail.html
  14. 1
      wallets/templates/send_for_accountant.html
  15. 2
      wallets/templates/send_for_accountant.txt
  16. 5
      wallets/urls.py
  17. 66
      wallets/views.py

@ -111,7 +111,7 @@ WSGI_APPLICATION = 'archilance.wsgi.application'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', 'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'archilance', 'NAME': 'archilance2',
'USER': 'postgres', 'USER': 'postgres',
'PASSWORD': 'postgres', 'PASSWORD': 'postgres',
'HOST': 'localhost', 'HOST': 'localhost',

@ -92,7 +92,7 @@ if __name__ == '__main__':
ioloop = IOLoop.instance() ioloop = IOLoop.instance()
application.db = momoko.Pool( application.db = momoko.Pool(
dsn='dbname=archilance user=postgres password=postgres host=localhost', dsn='dbname=archilance2 user=postgres password=postgres host=localhost',
size=1, size=1,
ioloop=ioloop, ioloop=ioloop,
) )

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-09 16:56
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('common', '0004_auto_20160808_1557'),
]
operations = [
migrations.AddField(
model_name='settings',
name='accountant_send_email',
field=models.EmailField(default='muhtarzubanchi05@gmail.com', max_length=100),
),
]

@ -38,6 +38,7 @@ class MainPage(models.Model):
class Settings(models.Model): class Settings(models.Model):
time_notification = models.IntegerField(default=180) time_notification = models.IntegerField(default=180)
document_send_email = models.EmailField(max_length=100, default="muhtarzubanchi05@gmail.com") document_send_email = models.EmailField(max_length=100, default="muhtarzubanchi05@gmail.com")
accountant_send_email = models.EmailField(max_length=100, default="muhtarzubanchi05@gmail.com")
document_send_description = models.TextField(blank=True) document_send_description = models.TextField(blank=True)
document_send_time_remove = models.IntegerField(default=14) document_send_time_remove = models.IntegerField(default=14)
recalculation_spec_time = models.TimeField() recalculation_spec_time = models.TimeField()

@ -46,7 +46,7 @@ class PrintDocumentCreate(BaseMixin, View):
} }
settings = Settings.objects.all().first().doc settings = Settings.objects.all().first()
subject, from_email, to = 'Заявка на распечатку', 'mukhtar@mukhtar', settings.document_send_email subject, from_email, to = 'Заявка на распечатку', 'mukhtar@mukhtar', settings.document_send_email
text_content = render_to_string('document_email.txt', ctx_dict) text_content = render_to_string('document_email.txt', ctx_dict)
html_content = get_template('document_email.html').render(ctx_dict) html_content = get_template('document_email.html').render(ctx_dict)

@ -12,3 +12,9 @@ class CheckForUserMixin(object):
else: else:
return HttpResponseForbidden('403 Forbidden') return HttpResponseForbidden('403 Forbidden')
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
class OwnershipMixin(object):
def dispatch(self, request, *args, **kwargs):
pass

@ -1,5 +1,15 @@
from django.contrib import admin from django.contrib import admin
from .models import InvoiceHistory from .models import InvoiceHistory, WithDraw
admin.site.register(InvoiceHistory)
class InvoiceHistoryAdmin(admin.ModelAdmin):
list_display = ('comment', 'sum', 'user','balance',)
class WithDrawAdmin(admin.ModelAdmin):
list_display = ('sum','created','user',)
admin.site.register(InvoiceHistory, InvoiceHistoryAdmin)
admin.site.register(WithDraw, WithDrawAdmin)

@ -0,0 +1,13 @@
from django import forms
from .models import WithDraw
class WithDrawForm(forms.ModelForm):
class Meta:
model = WithDraw
fields = (
'sum',
'yandex_card',
'user',
)

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-09 09:22
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wallets', '0003_auto_20160729_1209'),
]
operations = [
migrations.AddField(
model_name='invoicehistory',
name='balance',
field=models.DecimalField(decimal_places=0, default=0, max_digits=10),
),
]

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-09 14:27
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', '0004_invoicehistory_balance'),
]
operations = [
migrations.CreateModel(
name='WithDraw',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sum', models.DecimalField(decimal_places=0, max_digits=10)),
('created', models.DateTimeField(default=django.utils.timezone.now)),
('yandex_card', models.CharField(max_length=30)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='with_draw', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name_plural': 'Заявки на вывод средств',
'ordering': ('-created',),
'verbose_name': 'Заявка на вывод средств',
},
),
migrations.AlterModelOptions(
name='invoicehistory',
options={'ordering': ('-created',), 'verbose_name': 'Счет(История)', 'verbose_name_plural': 'Счет(История)'},
),
migrations.AlterField(
model_name='invoicehistory',
name='type',
field=models.CharField(blank=True, max_length=20, null=True),
),
]

@ -1,4 +1,5 @@
from django.db import models from django.db import models
from django.db.models import Sum
from django.utils import timezone from django.utils import timezone
from users.models import User from users.models import User
@ -14,13 +15,36 @@ class InvoiceHistory(models.Model):
comment = models.TextField(blank=True) comment = models.TextField(blank=True)
created = models.DateTimeField(default=timezone.now) created = models.DateTimeField(default=timezone.now)
sum = models.DecimalField(max_digits=10, decimal_places=0, default=0, null=True, blank=True) sum = models.DecimalField(max_digits=10, decimal_places=0, default=0, null=True, blank=True)
type = models.CharField(max_length=20) balance = models.DecimalField(max_digits=10, decimal_places=0, default=0)
type = models.CharField(max_length=20, blank=True, null=True)
user = models.ForeignKey(User, related_name='invoice_history') user = models.ForeignKey(User, related_name='invoice_history')
def __str__(self): def __str__(self):
return self.pk return self.comment
def save(self, *args, **kwargs):
if self.pk is None:
current_sum_info = InvoiceHistory.objects.filter(user=self.user).aggregate(Sum('sum'))
current_sum = current_sum_info['sum__sum'] or 0
self.balance = current_sum + self.sum
super().save(*args, **kwargs)
class Meta: class Meta:
verbose_name = 'Счет(История)' verbose_name = 'Счет(История)'
verbose_name_plural = 'Счет(История)' verbose_name_plural = 'Счет(История)'
ordering = ('-created',)
class WithDraw(models.Model):
sum = models.DecimalField(max_digits=10, decimal_places=0)
created = models.DateTimeField(default=timezone.now)
yandex_card = models.CharField(max_length=30)
user = models.ForeignKey(User, related_name='with_draw')
def __str__(self):
return self.yandex_card
class Meta:
verbose_name = 'Заявка на вывод средств'
verbose_name_plural = 'Заявки на вывод средств'
ordering = ('-created',)

@ -0,0 +1,20 @@
from django.db.models.signals import post_save
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
@receiver(post_save, sender=WithDraw)
def send_for_accountant(sender, instance, created, **kwargs):
if created:
ctx_dict = {
'username': instance.user.username,
}
subject, from_email, to = 'Заявка на распечатку', 'mukhtar@mukhtar', 'muhtarzubanchi05@gmail.com'
text_content = render_to_string('send_for_accountant.txt', ctx_dict)
html_content = get_template('send_for_accountant.html').render(ctx_dict)
msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
msg.send()

@ -5,61 +5,122 @@
{% block content %} {% block content %}
{% include 'partials/header.html' %} {% include 'partials/header.html' %}
<div class="container mainScore"> <div class="container mainScore">
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<p class="titleScore">Ваш счет</p> <p class="titleScore">Ваш счет</p>
</div> </div>
<div class="col-lg-12"> <div class="col-lg-12">
<div class="scoreButtons disTab"> <div class="scoreButtons disTab">
<div class="triangle1"></div> <div class="triangle1"></div>
<p>35 000 <i class="fa fa-rub"></i></p> <p>{{ user_score_balance }} <i class="fa fa-rub"></i></p>
<div class="col-lg-6">
<a href="javascript:void(0)" class="linkS linkS1">пополнить</a> {% if user_score.is_customer %}
</div> <div class="col-lg-6">
<div class="col-lg-6"> <a href="javascript:void(0)" class="linkS linkS1">пополнить</a>
<a href="javascript:void(0)" class="linkS linkS2">вывести средства</a> </div>
</div> {% endif %}
<table>
<tr> <div class="col-lg-6">
<th>Дата</th> <a href="javascript:void(0)" data-toggle="modal" data-target="#withdraw-money"
<th>Описание</th> class="linkS linkS2">вывести средства</a>
<th>Поступление/Списание</th> </div>
<th>Баланс</th>
</tr> <div id="withdraw-money" class="modal fade" role="dialog">
<tr> <div class="modal-dialog" role="document" style="width:900px;">
<td>23.01.2016</td> <div class="modal-content">
<td>
Оплата этапа 1 по заказу <b>«Сложный долгий заказ»</b> <div class="modal-header">
</td> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×
<td> </button>
+35 000 <h4 class="modal-title">Вывод денег</h4>
<i class="fa fa-rub"></i> </div>
</td> <form id="withdraw-form" action="{% url 'wallets:withdraw-create' %}" method="POST">{% csrf_token %}
<td> <div class="modal-body">
53 000 <div style="height: 150px;">
<i class="fa fa-rub"></i> <div class="textAreaBlock2 text-nn box-sizing disTab">
</td> <p>Кол-во денег</p>
</tr> <input type="text" name="{{ form.sum.html_name }}">
<tr> </div>
<td>23.01.2016</td>
<td> <div class="textAreaBlock2 text-nn box-sizing disTab">
Оплата этапа 1 по заказу <b>«Сложный долгий заказ»</b> <p>Номер Яндекс кошелька</p>
</td> <input type="text" name="{{ form.yandex_card.html_name }}">
<td> <input type="hidden" name="{{ form.user.html_name }}" value="{{ user_score.pk }}">
+35 000 </div>
<i class="fa fa-rub"></i> </div>
</td> </div>
<td>
53 000 <div class="modal-footer">
<i class="fa fa-rub"></i> <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</button>
</td> <button type="submit" class="btn btn-primary">Вывести</button>
</tr> </div>
</table> </form>
</div>
</div> </div>
</div>
</div>
<table>
<tr>
<th>Дата</th>
<th>Описание</th>
<th>Поступление/Списание</th>
<th>Баланс</th>
</tr>
{% for history in user_score.invoice_history.all %}
<tr>
<td>{{ history.created }}</td>
<td>
{{ history.comment }}
</td>
<td>
{{ history.sum }}
<i class="fa fa-rub"></i>
</td>
<td>
{{ history.balance }}
<i class="fa fa-rub"></i>
</td>
</tr>
{% endfor %}
</table>
</div>
</div>
{% include 'partials/footer.html' %} {% include 'partials/footer.html' %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
{% block js_block %}
<script type="text/javascript">
$(function () {
$('#withdraw-form').on('submit', function (e) {
e.preventDefault();
var dataSerializer = $(this).serialize()
$.ajax({
url: '/wallets/withdraw/create/',
method: 'POST',
data: dataSerializer,
dataType: 'json',
success: function (data) {
console.log(data);
if (data.status == 'ok') {
location.reload();
}
},
error: function (jqXHR, exception) {
console.log(jqXHR);
console.log(exception);
console.log(jqXHR.statusCode);
}
})
});
});
</script>
{% endblock %}

@ -0,0 +1 @@
Заявка на вывод средств от {{ username }}!

@ -0,0 +1,2 @@
Заявка на распечатку от {{ username }}!

@ -1,9 +1,10 @@
from django.conf import urls from django.conf import urls
from django.conf.urls import include from .views import ScoreDetailView, WithDrawCreate
from .views import ScoreDetailView
app_name = 'wallets' app_name = 'wallets'
urlpatterns = [ urlpatterns = [
urls.url(r'^score/(?P<pk>\d+)/$', ScoreDetailView.as_view(), name='score-detail'), urls.url(r'^score/(?P<pk>\d+)/$', ScoreDetailView.as_view(), name='score-detail'),
urls.url(r'^withdraw/create/$', WithDrawCreate.as_view(), name='withdraw-create'),
] ]

@ -1,9 +1,69 @@
from django.shortcuts import render from django.http import JsonResponse
from django.views.generic import DetailView from django.contrib import messages
from django.db.models import Sum
from django.views.generic import DetailView, CreateView
from users.models import User from users.models import User
from users.mixins import CheckForUserMixin
from .models import InvoiceHistory, WithDraw
from .forms import WithDrawForm
class ScoreDetailView(DetailView): class ScoreDetailView(CheckForUserMixin, DetailView):
model = User model = User
template_name = 'score-detail.html' template_name = 'score-detail.html'
context_object_name = 'user_score'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
user_score_balance = InvoiceHistory.objects.filter(user=self.get_object()).aggregate(Sum('sum'))
context['user_score_balance'] = user_score_balance['sum__sum'] or 0
context['form'] = WithDrawForm
return context
class AjaxableResponseMixin(object):
def form_invalid(self, form):
response = super().form_invalid(form)
if self.request.is_ajax():
return JsonResponse(form.errors, status=400)
else:
return response
def form_valid(self, form):
# import code; code.interact(local=dict(globals(), **locals()))
response = super(AjaxableResponseMixin, self).form_valid(form)
if self.request.is_ajax():
messages.info(self.request, 'Ваша заявка на вывод средств принята!')
data = {
'pk': self.object.pk,
'status': 'ok',
}
return JsonResponse(data)
else:
return response
# class WithDrawCreate(AjaxableResponseMixin, CreateView):
# model = WithDraw
# form_class = WithDrawForm
# success_url = '/'
class WithDrawCreate(CreateView):
model = WithDraw
form_class = WithDrawForm
def form_valid(self, form):
if self.request.is_ajax():
self.object = form.save()
messages.info(self.request, 'Ваша заявка на вывод средств принята!')
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():
return JsonResponse(form.errors, status=400)
return super().form_invalid(form)

Loading…
Cancel
Save