Compare commits
5 Commits
bot_refact
...
878a1e1a49
| Author | SHA1 | Date | |
|---|---|---|---|
| 878a1e1a49 | |||
| 515f5924f3 | |||
| 0fae6ce3f6 | |||
| 422389ecfb | |||
| dd849e00f3 |
@@ -20,8 +20,6 @@ from bot.utils import create_bot_instance
|
|||||||
from .views import view_draw_results
|
from .views import view_draw_results
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from django.db.models import Q
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
logger.setLevel(logging.DEBUG)
|
logger.setLevel(logging.DEBUG)
|
||||||
if not logger.handlers:
|
if not logger.handlers:
|
||||||
@@ -54,40 +52,33 @@ def add_participants_view(request):
|
|||||||
try:
|
try:
|
||||||
dt = parse_date(created_after)
|
dt = parse_date(created_after)
|
||||||
if dt:
|
if dt:
|
||||||
qs = qs.filter(created_at__date__gte=dt)
|
qs = qs.filter(created_at__gte=dt)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
if created_before:
|
if created_before:
|
||||||
try:
|
try:
|
||||||
dt = parse_date(created_before)
|
dt = parse_date(created_before)
|
||||||
if dt:
|
if dt:
|
||||||
qs = qs.filter(created_at__date__lte=dt)
|
qs = qs.filter(created_at__lte=dt)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
if request.GET.get("without_bonus"):
|
|
||||||
qs = qs.filter(Q(bonus__isnull=True) | Q(bonus=0))
|
|
||||||
if request.GET.get("without_fd"):
|
|
||||||
qs = qs.filter(Q(start_bonus__isnull=True) | Q(start_bonus=0))
|
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
selected_ids = request.POST.getlist("invoices")
|
form = AddParticipantsForm(request.POST)
|
||||||
selected_invoices = qs.filter(id__in=selected_ids)
|
form.fields["invoices"].queryset = qs
|
||||||
added_count = 0
|
if form.is_valid():
|
||||||
for invoice in selected_invoices:
|
selected_invoices = form.cleaned_data["invoices"]
|
||||||
if not LotteryParticipant.objects.filter(lottery=lottery, invoice=invoice).exists():
|
for invoice in selected_invoices:
|
||||||
invoice.used = True
|
invoice.used = True
|
||||||
invoice.save()
|
invoice.save()
|
||||||
LotteryParticipant.objects.create(lottery=lottery, invoice=invoice)
|
LotteryParticipant.objects.create(lottery=lottery, invoice=invoice)
|
||||||
added_count += 1
|
messages.success(request, "Участники успешно добавлены.")
|
||||||
messages.success(request, f"Добавлено {added_count} участников.")
|
return redirect("admin:draw_lotteryparticipant_changelist")
|
||||||
return redirect("admin:draw_lotteryparticipant_changelist")
|
else:
|
||||||
|
form = AddParticipantsForm()
|
||||||
|
form.fields["invoices"].queryset = qs
|
||||||
|
|
||||||
context = {
|
context = {"form": form, "lottery": lottery}
|
||||||
"lottery": lottery,
|
|
||||||
"invoices": qs.order_by("-created_at"),
|
|
||||||
"invoice_count": qs.count(),
|
|
||||||
"request": request,
|
|
||||||
}
|
|
||||||
return render(request, "admin/add_participants.html", context)
|
return render(request, "admin/add_participants.html", context)
|
||||||
|
|
||||||
|
|
||||||
@@ -97,6 +88,85 @@ def get_client_by_invoice(invoice):
|
|||||||
except Client.DoesNotExist:
|
except Client.DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
# def start_draw(request, lottery_id):
|
||||||
|
# lottery = get_object_or_404(Lottery, id=lottery_id)
|
||||||
|
# logger.info("Запуск розыгрыша для лотереи: %s", lottery.name)
|
||||||
|
|
||||||
|
# if lottery.finished:
|
||||||
|
# messages.warning(request, "Розыгрыш уже завершён.")
|
||||||
|
# return redirect("..")
|
||||||
|
|
||||||
|
# notifier = NotificationService(bot=create_bot_instance())
|
||||||
|
# async_to_sync(notifier.notify_draw_start)(lottery)
|
||||||
|
|
||||||
|
# manually_assigned_invoice_ids = set()
|
||||||
|
# for prize in lottery.prizes.all():
|
||||||
|
# if prize.winner and prize.winner.invoice:
|
||||||
|
# manually_assigned_invoice_ids.add(prize.winner.invoice_id)
|
||||||
|
# prize.winner.used = True
|
||||||
|
# prize.winner.save()
|
||||||
|
|
||||||
|
# for prize in lottery.prizes.all():
|
||||||
|
# logger.info("Обработка приза: %s", prize.prize_place)
|
||||||
|
|
||||||
|
# if prize.winner:
|
||||||
|
# try:
|
||||||
|
# draw_result = lottery.draw_results.get(prize=prize)
|
||||||
|
# draw_result.participant = prize.winner
|
||||||
|
# draw_result.drawn_at = timezone.now()
|
||||||
|
# draw_result.confirmed = False
|
||||||
|
# draw_result.save()
|
||||||
|
# except DrawResult.DoesNotExist:
|
||||||
|
# DrawResult.objects.create(
|
||||||
|
# lottery=lottery,
|
||||||
|
# prize=prize,
|
||||||
|
# participant=prize.winner,
|
||||||
|
# confirmed=False,
|
||||||
|
# drawn_at=timezone.now()
|
||||||
|
# )
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# try:
|
||||||
|
# draw_result = lottery.draw_results.get(prize=prize)
|
||||||
|
# if draw_result.confirmed:
|
||||||
|
# continue
|
||||||
|
# except DrawResult.DoesNotExist:
|
||||||
|
# draw_result = None
|
||||||
|
|
||||||
|
# participants = list(
|
||||||
|
# lottery.participants.filter(used=False).exclude(invoice_id__in=manually_assigned_invoice_ids)
|
||||||
|
# )
|
||||||
|
# if not participants:
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# winner_participant = random.choice(participants)
|
||||||
|
# winner_participant.used = True
|
||||||
|
# winner_participant.save()
|
||||||
|
|
||||||
|
# if draw_result:
|
||||||
|
# draw_result.participant = winner_participant
|
||||||
|
# draw_result.drawn_at = timezone.now()
|
||||||
|
# draw_result.confirmed = False
|
||||||
|
# draw_result.save()
|
||||||
|
# else:
|
||||||
|
# DrawResult.objects.create(
|
||||||
|
# lottery=lottery,
|
||||||
|
# prize=prize,
|
||||||
|
# participant=winner_participant,
|
||||||
|
# confirmed=False,
|
||||||
|
# drawn_at=timezone.now()
|
||||||
|
# )
|
||||||
|
|
||||||
|
# draw_results = lottery.draw_results.all()
|
||||||
|
# async_to_sync(notifier.notify_draw_results)(lottery, draw_results)
|
||||||
|
|
||||||
|
# if not lottery.prizes.filter(winner__isnull=True).exists():
|
||||||
|
# lottery.finished = True
|
||||||
|
# lottery.save()
|
||||||
|
|
||||||
|
# return render(request, "admin/draw_result.html", {"lottery": lottery, "draw_results": draw_results})
|
||||||
|
|
||||||
def start_draw(request, lottery_id):
|
def start_draw(request, lottery_id):
|
||||||
lottery = get_object_or_404(Lottery, id=lottery_id)
|
lottery = get_object_or_404(Lottery, id=lottery_id)
|
||||||
logger.info("Запуск розыгрыша для лотереи: %s", lottery.name)
|
logger.info("Запуск розыгрыша для лотереи: %s", lottery.name)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ class AddParticipantsForm(forms.Form):
|
|||||||
deposit_min = forms.DecimalField(label="Минимальный депозит", required=False)
|
deposit_min = forms.DecimalField(label="Минимальный депозит", required=False)
|
||||||
deposit_max = forms.DecimalField(label="Максимальный депозит", required=False)
|
deposit_max = forms.DecimalField(label="Максимальный депозит", required=False)
|
||||||
invoices = forms.ModelMultipleChoiceField(
|
invoices = forms.ModelMultipleChoiceField(
|
||||||
queryset=Invoice.objects.none(), # устанавливается в представлении
|
queryset=Invoice.objects.none(),
|
||||||
widget=forms.CheckboxSelectMultiple,
|
widget=forms.CheckboxSelectMultiple,
|
||||||
required=False,
|
required=False,
|
||||||
label="Доступные счета"
|
label="Доступные счета"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
const selectAllCheckbox = document.getElementById("select-all");
|
const selectAllCheckbox = document.getElementById("select-all");
|
||||||
if (selectAllCheckbox) {
|
if (selectAllCheckbox) {
|
||||||
selectAllCheckbox.addEventListener("click", function(){
|
selectAllCheckbox.addEventListener("click", function(){
|
||||||
const checkboxes = document.querySelectorAll("input[name='invoices']");
|
const checkboxes = document.querySelectorAll("input[name='invoices[]']");
|
||||||
checkboxes.forEach(chk => chk.checked = selectAllCheckbox.checked);
|
checkboxes.forEach(chk => chk.checked = selectAllCheckbox.checked);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
<h1>Добавление участников лотереи: {{ lottery.name }}</h1>
|
<h1>Добавление участников лотереи: {{ lottery.name }}</h1>
|
||||||
<p>{{ lottery.description }}</p>
|
<p>{{ lottery.description }}</p>
|
||||||
|
|
||||||
|
<!-- Форма фильтрации -->
|
||||||
<form method="get" class="mb-4">
|
<form method="get" class="mb-4">
|
||||||
<input type="hidden" name="lottery_id" value="{{ lottery.id }}">
|
<input type="hidden" name="lottery_id" value="{{ lottery.id }}">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -47,18 +48,6 @@
|
|||||||
<input type="date" name="created_before" value="{{ request.GET.created_before }}" class="form-control">
|
<input type="date" name="created_before" value="{{ request.GET.created_before }}" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mt-3">
|
|
||||||
<div class="col-md-3 form-check mt-2">
|
|
||||||
<input type="checkbox" class="form-check-input" name="without_bonus" id="without_bonus" {% if request.GET.without_bonus %}checked{% endif %}>
|
|
||||||
<label class="form-check-label" for="without_bonus">Только без бонуса</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3 form-check mt-2">
|
|
||||||
<input type="checkbox" class="form-check-input" name="without_fd" id="without_fd" {% if request.GET.without_fd %}checked{% endif %}>
|
|
||||||
<label class="form-check-label" for="without_fd">Только без ФД</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-3">
|
<div class="mt-3">
|
||||||
<button type="submit" class="btn btn-primary">Применить фильтр</button>
|
<button type="submit" class="btn btn-primary">Применить фильтр</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -66,48 +55,59 @@
|
|||||||
|
|
||||||
<p><strong>Найдено подходящих счетов: {{ invoice_count }}</strong></p>
|
<p><strong>Найдено подходящих счетов: {{ invoice_count }}</strong></p>
|
||||||
|
|
||||||
<form method="post">
|
<!-- Форма добавления участников -->
|
||||||
{% csrf_token %}
|
<form method="post">
|
||||||
<div class="table-responsive">
|
{% csrf_token %}
|
||||||
<table class="table table-striped table-bordered table-sm align-middle">
|
<div class="table-responsive">
|
||||||
<thead>
|
<table class="table table-striped table-bordered table-sm">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th><input type="checkbox" id="select-all" /></th>
|
||||||
|
<th>Создан</th>
|
||||||
|
<th>Закрыт</th>
|
||||||
|
<th>Счет</th>
|
||||||
|
<th>Клиент</th>
|
||||||
|
<th>Номер клиента</th>
|
||||||
|
<th>Сумма счета</th>
|
||||||
|
<th>Бонус</th>
|
||||||
|
<th>ФД</th>
|
||||||
|
<th>Депозит</th>
|
||||||
|
<th>Примечание</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for invoice in form.fields.invoices.queryset %}
|
||||||
<tr>
|
<tr>
|
||||||
<th><input type="checkbox" id="select-all" /></th>
|
<input type="checkbox" name="invoices" value="{{ invoice.id }}">
|
||||||
<th>Создан</th>
|
<td>{{ invoice.created_at|date:"d.m.Y H:i" }}</td>
|
||||||
<th>Закрыт</th>
|
<td>
|
||||||
<th>Счёт</th>
|
{% if invoice.closed_at %}
|
||||||
<th>Клиент</th>
|
{{ invoice.closed_at|date:"d.m.Y H:i" }}
|
||||||
<th>Номер клиента</th>
|
{% else %}
|
||||||
<th>Сумма счета</th>
|
—
|
||||||
<th>Бонус</th>
|
{% endif %}
|
||||||
<th>ФД</th>
|
</td>
|
||||||
<th>Депозит</th>
|
<td>{{ invoice.ext_id|default:"—" }}</td>
|
||||||
<th>Примечание</th>
|
<td>{{ invoice.client.name|default:"Не указан" }}</td>
|
||||||
|
<td>{{ invoice.client.club_card_number|default:"—" }}</td>
|
||||||
|
<td>{{ invoice.sum|default:"—" }}</td>
|
||||||
|
<td>{{ invoice.bonus|default:"—" }}</td>
|
||||||
|
<td>{{ invoice.start_bonus|default:"—" }}</td>
|
||||||
|
<td>{{ invoice.deposit_sum|default:"—" }}</td>
|
||||||
|
<td>{{ invoice.notes|default:"—" }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
{% empty %}
|
||||||
<tbody>
|
<tr>
|
||||||
{% for invoice in invoices %}
|
<td colspan="11" class="text-center">Нет доступных счетов</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td><input type="checkbox" name="invoices" value="{{ invoice.id }}"></td>
|
{% endfor %}
|
||||||
<td>{{ invoice.created_at|date:"Y-m-d H:i" }}</td>
|
</tbody>
|
||||||
<td>{% if invoice.closed_at %}{{ invoice.closed_at|date:"Y-m-d H:i" }}{% else %}—{% endif %}</td>
|
</table>
|
||||||
<td>{{ invoice.ext_id|default:"—" }}</td>
|
</div>
|
||||||
<td>{{ invoice.client.name|default:"Не указан" }}</td>
|
<button type="submit" class="btn btn-primary">Добавить выбранные счета</button>
|
||||||
<td>{{ invoice.client.club_card_number|default:"—" }}</td>
|
</form>
|
||||||
<td>{{ invoice.sum|floatformat:2|default:"—" }}</td>
|
|
||||||
<td>{{ invoice.bonus|floatformat:2|default:"—" }}</td>
|
|
||||||
<td>{{ invoice.start_bonus|floatformat:2|default:"—" }}</td>
|
|
||||||
<td>{{ invoice.deposit_sum|floatformat:2|default:"—" }}</td>
|
|
||||||
<td>{{ invoice.notes|default:"—" }}</td>
|
|
||||||
</tr>
|
|
||||||
{% empty %}
|
|
||||||
<tr><td colspan="11" class="text-center">Нет доступных счетов</td></tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn btn-success">Добавить выбранные счета</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<a href="{% url 'admin:draw_lotteryparticipant_changelist' %}" class="btn btn-secondary mt-3">Вернуться к списку участников</a>
|
<a href="{% url 'admin:draw_lotteryparticipant_changelist' %}" class="btn btn-secondary mt-3">Вернуться к списку участников</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,35 +4,11 @@
|
|||||||
{% block object-tools %}
|
{% block object-tools %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
{% if original %}
|
{% if original %}
|
||||||
<div class="container-fluid">
|
<li>
|
||||||
<a class="btn btn-warning d-block w-100 text-center my-2"
|
<a class="button"
|
||||||
href="{% url 'admin:botconfig-restart' original.pk %}">
|
href="{% url 'admin:botconfig-restart' original.pk %}">
|
||||||
Перезапустить бота
|
🔁 Перезапустить бота
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block extrahead %}
|
|
||||||
{{ block.super }}
|
|
||||||
<style>
|
|
||||||
.container-fluid {
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block footer %}
|
|
||||||
{{ block.super }}
|
|
||||||
<script>
|
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
|
||||||
const restartButton = document.querySelector('.btn-warning');
|
|
||||||
if (restartButton) {
|
|
||||||
restartButton.addEventListener('click', function(event) {
|
|
||||||
if (!confirm('Вы уверены, что хотите перезапустить бота?')) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
Reference in New Issue
Block a user