Рефакторинг моделей заказов и добавление методов оплаты

This commit is contained in:
2025-11-26 13:38:02 +03:00
parent 08e8409a66
commit 0653ec0545
20 changed files with 1720 additions and 873 deletions

View File

@@ -141,7 +141,6 @@
'input[name="delivery_time_start"]',
'input[name="delivery_time_end"]',
'input[name="delivery_cost"]',
'select[name="payment_method"]',
'textarea[name="special_instructions"]',
'input[name="discount_amount"]',
'input[type="checkbox"]',
@@ -176,6 +175,9 @@
// Слушаем изменения в формах товаров (formset)
observeFormsetChanges();
// Слушаем изменения в формах платежей (payment formset)
observePaymentFormsetChanges();
}
/**
@@ -232,6 +234,55 @@
});
}
/**
* Наблюдает за изменениями в формсете платежей
*/
function observePaymentFormsetChanges() {
const paymentsContainer = document.getElementById('payments-container');
if (!paymentsContainer) {
return;
}
// Наблюдаем за добавлением/удалением форм платежей
const observer = new MutationObserver(() => {
attachPaymentFormsetEventListeners();
});
observer.observe(paymentsContainer, {
childList: true,
subtree: true
});
// Прикрепляем обработчики к существующим формам
attachPaymentFormsetEventListeners();
}
/**
* Прикрепляет обработчики к полям в формах платежей
*/
function attachPaymentFormsetEventListeners() {
const paymentForms = document.querySelectorAll('.payment-form');
paymentForms.forEach(form => {
// Если уже прикреплены обработчики, пропускаем
if (form.dataset.autosavePaymentAttached === 'true') {
return;
}
const fields = form.querySelectorAll('select, input[type="number"], input[type="text"], textarea, input[type="checkbox"]');
fields.forEach(field => {
if (field.tagName === 'SELECT' || field.type === 'checkbox') {
field.addEventListener('change', scheduleAutosave);
} else {
field.addEventListener('input', scheduleAutosave);
}
});
form.dataset.autosavePaymentAttached = 'true';
});
}
/**
* Планирует автосохранение с задержкой (debouncing)
*/
@@ -327,11 +378,6 @@
data.delivery_cost = deliveryCostField.value;
}
const paymentMethodField = form.querySelector('select[name="payment_method"]');
if (paymentMethodField && paymentMethodField.value) {
data.payment_method = paymentMethodField.value;
}
const specialInstructionsField = form.querySelector('textarea[name="special_instructions"]');
if (specialInstructionsField) {
data.special_instructions = specialInstructionsField.value;
@@ -425,6 +471,11 @@
data.items = orderItemsData.items;
data.deleted_item_ids = orderItemsData.deletedItemIds;
// Собираем платежи
const paymentsData = collectPayments();
data.payments = paymentsData.payments;
data.deleted_payment_ids = paymentsData.deletedPaymentIds;
// Флаг для пересчета итоговой суммы
data.recalculate = true;
@@ -489,6 +540,53 @@
return { items, deletedItemIds };
}
/**
* Собирает данные о платежах
*/
function collectPayments() {
const payments = [];
const deletedPaymentIds = [];
const paymentForms = document.querySelectorAll('.payment-form');
paymentForms.forEach(form => {
// Проверяем, помечена ли форма на удаление
const deleteCheckbox = form.querySelector('input[name$="-DELETE"]');
const idField = form.querySelector('input[name$="-id"]');
if (deleteCheckbox && deleteCheckbox.checked) {
// Если форма помечена на удаление и имеет ID, добавляем в список удалённых
if (idField && idField.value) {
deletedPaymentIds.push(parseInt(idField.value));
}
return; // Не добавляем в payments
}
// Получаем способ оплаты и сумму
const paymentMethodSelect = form.querySelector('select[name$="-payment_method"]');
const amountInput = form.querySelector('input[name$="-amount"]');
const notesInput = form.querySelector('textarea[name$="-notes"]');
if (!paymentMethodSelect || !paymentMethodSelect.value || !amountInput || !amountInput.value) {
return; // Пропускаем пустые платежи
}
const payment = {
payment_method_id: parseInt(paymentMethodSelect.value),
amount: (amountInput.value || '0').replace(',', '.'),
notes: notesInput ? notesInput.value : ''
};
// Если есть ID (существующий платеж), добавляем его
if (idField && idField.value) {
payment.id = parseInt(idField.value);
}
payments.push(payment);
});
return { payments, deletedPaymentIds };
}
/**
* Получает CSRF токен из cookies или meta тега
*/