fix(orders): исправить удаление позиций заказа в формсете

- Исправлена логика удаления inline-форм для позиций заказа
- Добавлена обработка удаления сохранённых и новых форм
- Добавлено поле id и DELETE в OrderItemForm для корректной работы формсета
- Добавлена проверка на null для created_by на странице отладки
- Расширены права доступа к отладочной странице: теперь доступна owner и manager
- Добавлено логирование для отладки процесса обновления заказа
This commit is contained in:
2026-01-18 17:16:34 +03:00
parent ab1e8ebd18
commit 0d882781da
6 changed files with 150 additions and 25 deletions

View File

@@ -1542,6 +1542,22 @@ document.addEventListener('DOMContentLoaded', function() {
});
}
// Убедимся, что все поля имеют правильные имена и ID
const fields = newForm.querySelectorAll('[name]');
fields.forEach(field => {
const name = field.getAttribute('name');
if (name && name.includes('__prefix__')) {
const newName = name.replace(/__prefix__/g, formCount);
field.setAttribute('name', newName);
}
const id = field.getAttribute('id');
if (id && id.includes('__prefix__')) {
const newId = id.replace(/__prefix__/g, formCount);
field.setAttribute('id', newId);
}
});
updateTotalDisplay();
return newForm;
@@ -1560,6 +1576,10 @@ document.addEventListener('DOMContentLoaded', function() {
// Сохранённая форма - помечаем на удаление
console.log('[removeForm] Помечаем сохранённую форму на удаление (ID:', idField.value, ')');
deleteCheckbox.checked = true;
// Также добавляем скрытое поле, чтобы гарантировать удаление
if (!deleteCheckbox.value) {
deleteCheckbox.value = 'on';
}
form.classList.add('deleted');
form.style.display = 'none';
updateTotalDisplay();
@@ -1569,10 +1589,10 @@ document.addEventListener('DOMContentLoaded', function() {
} else {
// Новая форма - удаляем из DOM
console.log('[removeForm] Удаление новой формы из DOM');
// Удаляем форму
form.remove();
// Обновляем TOTAL_FORMS
const totalFormsInput = document.querySelector('[name="items-TOTAL_FORMS"]');
if (totalFormsInput) {
@@ -1581,14 +1601,17 @@ document.addEventListener('DOMContentLoaded', function() {
console.log(`[removeForm] Обновление TOTAL_FORMS: ${oldTotal}${newTotal}`);
totalFormsInput.value = newTotal;
}
// Пересчитываем индексы оставшихся форм
const remainingForms = Array.from(document.querySelectorAll('.order-item-form:not(.deleted)'));
console.log(`[removeForm] Пересчёт индексов для ${remainingForms.length} оставшихся форм...`);
remainingForms.forEach((currentForm, newIndex) => {
// Находим все поля с name="items-N-..."
const fields = currentForm.querySelectorAll('[name^="items-"]');
// Обновляем data-атрибут индекса формы
currentForm.setAttribute('data-form-index', newIndex);
// Находим все поля с name="items-N-..." и select элементы
const fields = currentForm.querySelectorAll('[name^="items-"], select[name^="items-"]');
fields.forEach(field => {
const name = field.getAttribute('name');
// Меняем индекс: items-СТАРЫЙ-поле → items-НОВЫЙ-поле
@@ -1596,16 +1619,51 @@ document.addEventListener('DOMContentLoaded', function() {
if (name !== newName) {
console.log(`[removeForm] Переименование: ${name}${newName}`);
field.setAttribute('name', newName);
// Обновляем ID тоже (для связи с label)
if (field.id) {
const newId = field.id.replace(/^id_items-\d+/, `id_items-${newIndex}`);
field.setAttribute('id', newId);
}
// Обновляем for атрибут у label, если есть
const label = document.querySelector(`label[for="${field.id}"]`);
if (label) {
label.setAttribute('for', newId);
}
}
// Обновляем data-атрибут у select2 элементов
if (field.classList.contains('select2-order-item')) {
field.setAttribute('data-form-index', newIndex);
}
});
// Обновляем select элементы, если есть
const selects = currentForm.querySelectorAll('select');
selects.forEach(select => {
const name = select.getAttribute('name');
if (name && name.startsWith('items-')) {
const newName = name.replace(/^items-\d+/, `items-${newIndex}`);
if (name !== newName) {
select.setAttribute('name', newName);
// Обновляем ID тоже (для связи с label)
if (select.id) {
const newId = select.id.replace(/^id_items-\d+/, `id_items-${newIndex}`);
select.setAttribute('id', newId);
// Обновляем for атрибут у label, если есть
const label = document.querySelector(`label[for="${select.id}"]`);
if (label) {
label.setAttribute('for', newId);
}
}
}
}
});
});
updateTotalDisplay();
}
}
@@ -1656,6 +1714,17 @@ document.addEventListener('DOMContentLoaded', function() {
// Валидация перед отправкой
document.getElementById('order-form').addEventListener('submit', function(e) {
// Убедимся, что все удаленные формы действительно отмечены для удаления
const deletedForms = document.querySelectorAll('.order-item-form.deleted');
deletedForms.forEach(form => {
const deleteCheckbox = form.querySelector('input[name$="-DELETE"]');
if (deleteCheckbox) {
deleteCheckbox.checked = true;
// Убедимся, что значение установлено
deleteCheckbox.value = 'on';
}
});
// Заказ можно сохранить без товаров
});