Исправлена проблема с сохранением платежей и автоматический пересчёт статуса оплаты

- Добавлен префикс 'payments' для PaymentFormSet во всех представлениях
- Добавлен атрибут form='order-form' для динамически создаваемых полей платежей
- Убрано переопределение has_changed() в PaymentForm (использует стандартную логику Django)
- Автоматическая установка created_by для новых платежей
- Автоматический пересчёт payment_status при изменении суммы заказа
- Автоматическая обработка переплаты с возвратом в кошелёк клиента
- Убран весь отладочный код
This commit is contained in:
2025-11-29 00:48:04 +03:00
parent a101d2919c
commit 9415aca63d
3 changed files with 116 additions and 38 deletions

View File

@@ -670,14 +670,14 @@
<!-- Скрытый шаблон для новых платежей -->
<template id="empty-payment-form-template">
<div class="payment-form border rounded p-3 mb-3" data-form-index="__prefix__">
<input type="hidden" name="payments-__prefix__-id" id="id_payments-__prefix__-id">
<input type="checkbox" name="payments-__prefix__-DELETE" id="id_payments-__prefix__-DELETE" style="display: none;">
<input type="hidden" name="payments-__prefix__-id" id="id_payments-__prefix__-id" form="order-form">
<input type="checkbox" name="payments-__prefix__-DELETE" id="id_payments-__prefix__-DELETE" form="order-form" style="display: none;">
<div class="row align-items-end">
<div class="col-md-4">
<div class="mb-2">
<label class="form-label">Способ оплаты</label>
<select name="payments-__prefix__-payment_method" class="form-select" id="id_payments-__prefix__-payment_method">
<select name="payments-__prefix__-payment_method" class="form-select" id="id_payments-__prefix__-payment_method" form="order-form">
<option value="">---------</option>
{% for pm in payment_formset.forms.0.fields.payment_method.queryset %}
<option value="{{ pm.id }}">{{ pm.name }}</option>
@@ -688,13 +688,13 @@
<div class="col-md-3">
<div class="mb-2">
<label class="form-label">Сумма</label>
<input type="number" name="payments-__prefix__-amount" step="0.01" min="0" class="form-control" placeholder="Сумма платежа" id="id_payments-__prefix__-amount">
<input type="number" name="payments-__prefix__-amount" step="0.01" min="0" class="form-control" placeholder="Сумма платежа" id="id_payments-__prefix__-amount" form="order-form">
</div>
</div>
<div class="col-md-4">
<div class="mb-2">
<label class="form-label">Примечания</label>
<textarea name="payments-__prefix__-notes" class="form-control" rows="1" placeholder="Примечания к платежу (опционально)" id="id_payments-__prefix__-notes"></textarea>
<textarea name="payments-__prefix__-notes" class="form-control" rows="1" placeholder="Примечания к платежу (опционально)" id="id_payments-__prefix__-notes" form="order-form"></textarea>
</div>
</div>
<div class="col-md-1">
@@ -1745,11 +1745,16 @@ document.addEventListener('DOMContentLoaded', function() {
// Функция для добавления нового платежа
function addNewPayment() {
console.log('[addNewPayment] START, paymentFormCount:', paymentFormCount);
// ВАЖНО: Получаем HTML из template.content и заменяем __prefix__
const tempContainer = document.createElement('div');
tempContainer.appendChild(paymentFormTemplate.content.cloneNode(true));
const templateHtml = tempContainer.innerHTML;
console.log('[addNewPayment] templateHtml (first 200 chars):', templateHtml.substring(0, 200));
const replacedHtml = templateHtml.replace(/__prefix__/g, paymentFormCount);
console.log('[addNewPayment] replacedHtml (first 200 chars):', replacedHtml.substring(0, 200));
// Создаем элемент из обработанного HTML
const tempDiv = document.createElement('div');
@@ -1760,6 +1765,14 @@ document.addEventListener('DOMContentLoaded', function() {
// Добавляем в контейнер
paymentsContainer.appendChild(newPaymentDiv);
console.log('[addNewPayment] Added payment form, index:', paymentFormCount);
// DEBUG: Проверяем что поля действительно в DOM
const allInputs = newPaymentDiv.querySelectorAll('input, select, textarea');
console.log('[addNewPayment] Total inputs in new form:', allInputs.length);
allInputs.forEach((inp, idx) => {
console.log(` [${idx}] name="${inp.name}", type="${inp.type || inp.tagName}"`);
});
// Обновляем счетчик форм
paymentFormCount++;
@@ -2222,7 +2235,46 @@ if (!document.getElementById('notification-styles')) {
// При отправке формы - отключаем предупреждение
const form = document.getElementById('order-form');
if (form) {
form.addEventListener('submit', function() {
form.addEventListener('submit', function(e) {
console.log('[FORM SUBMIT] Form is being submitted');
console.log('[FORM SUBMIT] TOTAL_FORMS:', document.querySelector('[name="payments-TOTAL_FORMS"]')?.value);
// Проверяем payment поля в DOM ПЕРЕД submit
console.log('[FORM SUBMIT] Checking payments container...');
const paymentsContainer = document.getElementById('payments-container');
console.log('[FORM SUBMIT] payments-container exists:', !!paymentsContainer);
console.log('[FORM SUBMIT] payments-container childElementCount:', paymentsContainer?.childElementCount);
console.log('[FORM SUBMIT] form.contains(paymentsContainer):', form.contains(paymentsContainer));
// Проверяем что внутри контейнера
if (paymentsContainer && paymentsContainer.childElementCount > 0) {
const firstChild = paymentsContainer.firstElementChild;
console.log('[FORM SUBMIT] First child of container:', firstChild);
const inputs = firstChild.querySelectorAll('input, select, textarea');
console.log('[FORM SUBMIT] Inputs in first child:', inputs.length);
inputs.forEach((inp, idx) => {
console.log(` [${idx}] name="${inp.name}", value="${inp.value}", form="${inp.form?.id}"`);
});
}
console.log('[FORM SUBMIT] Payment fields in DOM (via form.querySelectorAll):');
const paymentInputs = form.querySelectorAll('[name^="payments-"]');
console.log('[FORM SUBMIT] Found payment inputs:', paymentInputs.length);
paymentInputs.forEach(inp => {
const isDisabled = inp.disabled ? ' [DISABLED]' : '';
const val = inp.type === 'checkbox' ? inp.checked : inp.value;
console.log(` ${inp.name} = "${val}"${isDisabled}`);
});
// Логируем все payment поля в FormData
const formData = new FormData(form);
console.log('[FORM SUBMIT] Payment fields in FormData:');
for (let [key, value] of formData.entries()) {
if (key.startsWith('payments-')) {
console.log(` ${key} = ${value}`);
}
}
isSubmitting = true;
});
}