diff --git a/myproject/orders/static/orders/js/order_form_cleanup.js b/myproject/orders/static/orders/js/order_form_cleanup.js
new file mode 100644
index 0000000..7ba4bd0
--- /dev/null
+++ b/myproject/orders/static/orders/js/order_form_cleanup.js
@@ -0,0 +1,138 @@
+/**
+ * Order Form Cleanup Module
+ * Автоматическая очистка пустых позиций заказа перед отправкой формы
+ */
+
+(function(window) {
+ 'use strict';
+
+ /**
+ * Инициализирует автоочистку пустых форм при submit
+ * @param {Element|string} formElement - DOM элемент формы или селектор
+ */
+ function initOrderFormCleanup(formElement) {
+ var form = typeof formElement === 'string'
+ ? document.querySelector(formElement)
+ : formElement;
+
+ if (!form) {
+ console.error('[OrderFormCleanup] Form not found');
+ return;
+ }
+
+ // Обработчик submit - очищаем пустые строки перед валидацией
+ form.addEventListener('submit', function(e) {
+ console.log('[Form Cleanup] Начало очистки пустых форм товаров');
+
+ // Находим все формы товаров
+ var itemForms = Array.from(document.querySelectorAll('.order-item-form'));
+ console.log('[Form Cleanup] Найдено форм:', itemForms.length);
+
+ // Собираем формы для удаления
+ var formsToRemove = [];
+
+ itemForms.forEach(function(itemForm, formIndex) {
+ // Пропускаем уже удалённые формы
+ if (itemForm.classList.contains('deleted')) {
+ console.log('[Form Cleanup] Форма ' + formIndex + ': уже удалена, пропуск');
+ return;
+ }
+
+ // Находим поля
+ var productField = itemForm.querySelector('[name$="-product"]');
+ var kitField = itemForm.querySelector('[name$="-product_kit"]');
+ var quantityField = itemForm.querySelector('[name$="-quantity"]');
+ var priceField = itemForm.querySelector('[name$="-price"]');
+ var idField = itemForm.querySelector('[name$="-id"]');
+
+ // Проверяем значения (пустота = нет значения или значение пустое)
+ var hasProduct = productField && productField.value && productField.value.trim();
+ var hasKit = kitField && kitField.value && kitField.value.trim();
+ var hasQuantity = quantityField && quantityField.value && quantityField.value.trim();
+ var hasPrice = priceField && priceField.value && priceField.value.trim();
+
+ console.log('[Form Cleanup] Форма ' + formIndex + ':');
+ console.log(' - product: ' + (hasProduct || '(пусто)'));
+ console.log(' - kit: ' + (hasKit || '(пусто)'));
+ console.log(' - quantity: ' + (hasQuantity || '(пусто)'));
+ console.log(' - price: ' + (hasPrice || '(пусто)'));
+
+ // Если ВСЁ пусто — это мусорная строка, удаляем
+ var isCompletelyEmpty = !hasProduct && !hasKit && !hasQuantity && !hasPrice;
+
+ console.log(' - Полностью пустая? ' + isCompletelyEmpty);
+
+ if (isCompletelyEmpty) {
+ // Если есть ID (сохранённая позиция) — помечаем на удаление
+ if (idField && idField.value) {
+ console.log(' - Действие: помечаем DELETE (есть ID: ' + idField.value + ')');
+ var deleteCheckbox = itemForm.querySelector('input[name$="-DELETE"]');
+ if (deleteCheckbox) {
+ deleteCheckbox.checked = true;
+ }
+ itemForm.classList.add('deleted');
+ itemForm.style.display = 'none';
+ } else {
+ console.log(' - Действие: помечаем для удаления из formset (нет ID)');
+ // Новая несохранённая форма — помечаем для удаления
+ formsToRemove.push(itemForm);
+ }
+ } else {
+ console.log(' - Действие: оставляем (не пустая, пойдёт на валидацию)');
+ }
+ });
+
+ // Удаляем помеченные формы и пересчитываем индексы
+ if (formsToRemove.length > 0) {
+ console.log('[Form Cleanup] Удаление ' + formsToRemove.length + ' пустых форм...');
+
+ // Удаляем формы из DOM
+ formsToRemove.forEach(function(itemForm) {
+ itemForm.remove();
+ });
+
+ // Обновляем TOTAL_FORMS
+ var totalFormsInput = document.querySelector('[name="items-TOTAL_FORMS"]');
+ if (totalFormsInput) {
+ var oldTotal = parseInt(totalFormsInput.value);
+ var newTotal = oldTotal - formsToRemove.length;
+ console.log('[Form Cleanup] Обновление TOTAL_FORMS: ' + oldTotal + ' → ' + newTotal);
+ totalFormsInput.value = newTotal;
+ }
+
+ // Пересчитываем индексы оставшихся форм
+ var remainingForms = Array.from(document.querySelectorAll('.order-item-form:not(.deleted)'));
+ console.log('[Form Cleanup] Пересчёт индексов для ' + remainingForms.length + ' оставшихся форм...');
+
+ remainingForms.forEach(function(itemForm, newIndex) {
+ // Находим все поля с name="items-N-..."
+ var fields = itemForm.querySelectorAll('[name^="items-"]');
+ fields.forEach(function(field) {
+ var name = field.getAttribute('name');
+ // Меняем индекс: items-СТАРЫЙ-поле → items-НОВЫЙ-поле
+ var newName = name.replace(/^items-\d+/, 'items-' + newIndex);
+ if (name !== newName) {
+ console.log('[Form Cleanup] Переименование: ' + name + ' → ' + newName);
+ field.setAttribute('name', newName);
+
+ // Обновляем ID тоже (для связи с label)
+ if (field.id) {
+ var newId = field.id.replace(/^id_items-\d+/, 'id_items-' + newIndex);
+ field.setAttribute('id', newId);
+ }
+ }
+ });
+ });
+ }
+
+ console.log('[Form Cleanup] Очистка завершена');
+ // Всё остальное идёт на валидацию Django как есть
+ });
+
+ console.log('[OrderFormCleanup] Initialized for form:', form.id || form);
+ }
+
+ // Экспорт
+ window.initOrderFormCleanup = initOrderFormCleanup;
+
+})(window);
diff --git a/myproject/orders/templates/orders/order_form.html b/myproject/orders/templates/orders/order_form.html
index d60d2f4..d39c305 100644
--- a/myproject/orders/templates/orders/order_form.html
+++ b/myproject/orders/templates/orders/order_form.html
@@ -875,119 +875,11 @@
+
+