Рефакторинг моделей заказов и добавление методов оплаты
This commit is contained in:
@@ -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 тега
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user