При добавлении временного комплекта теперь явно вызывается событие
select2:select, которое запускает автосохранение черновика заказа.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Временный комплект теперь заполняет первую пустую форму товара вместо создания новой. Это позволяет корректно сохранять комплект при автосохранении.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Черновик теперь создаётся ТОЛЬКО при выборе клиента, а не при добавлении товаров или изменении других полей. Это логично, так как:
- Без клиента черновик не может быть создан
- После переадресации на страницу редактирования работает полноценное автосохранение
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Изменен с order-items-formset на order-items-container для корректной работы отслеживания товаров при создании заказа.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Исправлен ID контейнера формсета (order-items-container)
- Добавлена поддержка событий Select2 для полей выбора товара
- Добавлен MutationObserver для отслеживания новых форм товаров
- Удалены отладочные console.log
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Добавлен параметр format для виджетов DateInput и TimeInput, что позволяет корректно отображать сохраненные значения даты и времени в HTML5 полях формы.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Добавлен парсинг строковых значений в объекты date и time для полей delivery_date, delivery_time_start и delivery_time_end, чтобы форма корректно отображала сохраненные значения.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Добавлена конвертация строковых значений в Decimal для полей delivery_cost и discount_amount, чтобы избежать ошибки типа при автосохранении.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Добавлена правильная обработка ForeignKey полей (customer, delivery_address, pickup_shop)
при обновлении черновика. Теперь ID конвертируются в объекты моделей перед присваиванием.
Исправляет ошибку: Cannot assign "1": "Order.customer" must be a "Customer" instance.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Заменил form[action*="edit"] на #order-form для корректной работы.
Добавлено дополнительное логирование для отладки.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Поля с Select2 не генерируют стандартные события 'change',
поэтому добавлено прослушивание событий 'select2:select'.
Также добавлено логирование для отладки.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Заменил form[action*="create"] на #order-form, т.к. у формы нет атрибута action.
Добавлены дополнительные проверки и логирование для отладки.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
При любом изменении формы создания заказа автоматически создается черновик
и пользователь перенаправляется на страницу редактирования, где работает
стандартное автосохранение.
Изменения:
- Добавлен AJAX endpoint create_draft_from_form в views.py
- Создан JavaScript модуль draft-creator.js для автосоздания черновика
- Обновлен order_form.html для подключения соответствующих скриптов
- Добавлен URL маршрут /orders/create-draft/
Работает с задержкой 2 секунды после первого изменения формы.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Проблема:
- Над секцией "Товары в заказе" отображался странный dropdown
- Шаблон формы использовал <div style="display: none;"> вместо <template>
Исправление:
- Заменен <div id="empty-form-template" style="display: none;"> на <template>
- Добавлен id для select в шаблоне
- Обновлен JavaScript для работы с HTML5 <template> element
- Используется template.content для правильного клонирования
Теперь шаблон полностью невидим и не влияет на layout
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Проблемы:
- Отображались лишние пустые формы (extra=1)
- Новые формы не инициализировали Select2 корректно
- Неудобное удаление через checkbox
Исправления:
1. forms.py:
- Изменен OrderItemFormSet: extra=0, min_num=0
- Формы добавляются только через JavaScript
2. order_form.html:
- Добавлен шаблон пустой формы (#empty-form-template)
- Заменен checkbox "Удалить" на кнопку с иконкой
- Полностью переписана логика добавления/удаления форм
- Добавлена валидация: нельзя удалить единственную позицию
- Скрытые формы (DELETE=true) визуально помечаются
- Автодобавление первой формы при пустом formset
- Валидация перед отправкой: минимум 1 товар
Результат:
- При создании заказа отображается только 1 пустая форма
- Кнопка "Добавить товар" корректно создает новые формы
- Select2 работает в каждой новой форме
- Кнопка "Удалить" работает корректно
- Единственную позицию удалить нельзя
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
JavaScript:
- Создан autosave.js: модуль автосохранения черновиков
- Debouncing с задержкой 3 секунды
- Визуальный индикатор статуса сохранения
- Автоматическое отслеживание изменений в полях формы и formset
UI обновления:
- order_form.html: добавлен data-атрибут is-draft и подключение autosave.js
- order_list.html: добавлен badge "Черновик" для черновиков в списке заказов
Management команда:
- cleanup_draft_orders: очистка старых черновиков (по умолчанию 30 дней)
- Поддержка --dry-run для предпросмотра
- Автоматическое удаление связанных временных комплектов
Использование:
- python manage.py cleanup_draft_orders --days=30
- python manage.py cleanup_draft_orders --days=7 --dry-run
Система черновиков полностью готова к использованию!
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Добавлены AJAX endpoints:
- autosave_draft_order: endpoint для автосохранения черновиков
Модифицированы views:
- order_create: поддержка создания черновиков через кнопку 'save_as_draft'
- order_update: поддержка обновления и финализации черновиков через DraftOrderService
Добавлены URL:
- /orders/<pk>/autosave/ для автосохранения черновиков
Следующий этап: JavaScript модуль автосохранения и UI
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Реализован базовый функционал для работы с черновиками заказов.
Это первый этап из трех для полной реализации автосохранения.
Изменения:
1. Модель Order (orders/models.py):
- Добавлен статус 'draft' в STATUS_CHOICES
- Добавлено поле last_autosave_at для отслеживания автосохранения
- Добавлен метод is_draft() для проверки статуса черновика
2. Миграция (0005_add_draft_support.py):
- Добавление поля last_autosave_at в Order
- Добавление статуса 'draft' в choices
3. Service Layer (orders/services/draft_service.py):
- Класс DraftOrderService с методами:
* create_draft() - создание нового черновика
* update_draft() - обновление существующего черновика
* add_item_to_draft() - добавление товара в черновик
* remove_item_from_draft() - удаление товара из черновика
* finalize_draft() - завершение черновика (draft → new)
* get_user_drafts() - получение черновиков пользователя
* delete_old_drafts() - очистка старых черновиков
- Вся бизнес-логика инкапсулирована в сервисный слой
Архитектурные решения:
- Использование service layer pattern для изоляции бизнес-логики
- Транзакционность всех операций с черновиками
- Автоматический пересчет итоговой суммы при изменении товаров
- Связь временных комплектов с черновиками через FK
Следующие этапы (в следующих коммитах):
- Этап 2: AJAX endpoints и модификация views
- Этап 3: JavaScript автосохранение и UI
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Проблема:
- Поле 'notes' было удалено из модели KitItem миграцией 0005
- Админка и другие части кода продолжали ссылаться на это поле
- Это вызывало FieldError при попытке редактирования ProductKit в админке
Решение:
Удалены все 6 упоминаний поля 'notes' из кода:
1. admin.py (2 места):
- KitItemInline: удалено 'notes' из fields
- KitItemAdmin: удалено 'notes' из fields
2. productkit_detail.html (2 места):
- Удален заголовок колонки "Примечание"
- Удален блок отображения item.notes
3. demo_variants.py (2 места):
- Удалено 'notes' из defaults для премиум букета
- Удалено 'notes' из defaults для эконом букета
Результат:
- Админка ProductKit теперь работает корректно
- Шаблоны не обращаются к несуществующим полям
- Демо-команды создания вариантов работают без ошибок
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Проблема:
- После создания временного комплекта он не отображался корректно в Select2
- Опция добавлялась в select после инициализации Select2
Решение:
- Добавлена задержка (setTimeout) для корректной инициализации формы
- Используется Select2 API (.append().trigger('change')) для добавления опции
- Это обеспечивает правильное отображение названия комплекта в выпадающем списке
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Проблема:
- Код пытался найти кнопку с ID 'add-order-item-btn'
- Реальный ID кнопки в шаблоне: 'add-item-btn'
- Это приводило к ошибке: Cannot read properties of null (reading 'click')
Решение:
- Исправлен ID кнопки с 'add-order-item-btn' на 'add-item-btn'
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Проблема:
- JavaScript вызывал несуществующую функцию addOrderItem()
- Это приводило к ошибке и комплект не добавлялся в заказ
Решение:
- Заменен вызов addOrderItem() на программный клик по кнопке добавления формы
- После добавления формы заполняем её данными созданного комплекта
- Добавлена очистка формы модального окна после успешного создания
- Улучшена обработка ошибок с детальным логированием
Изменения:
- Добавлено логирование статуса ответа и данных для отладки
- Добавлена проверка HTTP статуса перед парсингом JSON
- Реализовано корректное добавление комплекта в список позиций заказа
- Добавлена очистка полей модального окна после создания
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Шаблон order_form.html:
- Кнопка "Создать и добавить комплект" рядом с "Добавить товар"
- Модальное окно с формой создания временного комплекта:
* Поле названия комплекта
* Поле описания (опционально)
* Динамическое добавление/удаление товаров с Select2
* Поле количества для каждого товара
JavaScript функциональность:
- addTempKitComponent() - добавление товара в комплект
- Select2 с AJAX поиском только товаров (type='product')
- Валидация (название обязательно, минимум 1 товар)
- AJAX запрос к /orders/temporary-kits/create/
- Автоматическое добавление созданного комплекта в форму заказа
- Закрытие модального окна после успешного создания
Теперь флорист может:
1. Нажать "Создать и добавить комплект"
2. Ввести название (например "Букет для Анны")
3. Добавить товары с количествами через Select2
4. Нажать "Создать и добавить в заказ"
5. Комплект создается и автоматически добавляется в заказ
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Добавлен ProductKitMakePermanentView в:
- products/views/__init__.py импорты
- __all__ экспорт
Теперь view доступен через products.views и сервер запускается без ошибок.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Views (products/views/productkit_views.py):
- ProductKitMakePermanentView: view для преобразования временного комплекта
* Доступен только для временных комплектов (is_temporary=True)
* Позволяет отредактировать название, описание, категории, теги, цену
* Вызывает метод make_permanent() модели
* Перенаправляет на детальную страницу комплекта после успеха
URLs (products/urls.py):
- /products/kits/<pk>/make-permanent/ - страница преобразования
Templates:
- productkit_make_permanent.html: форма преобразования с составом и ценой
- order_detail.html: добавлена кнопка "Сделать постоянным" для временных комплектов
Теперь флорист может:
1. Увидеть временный комплект в заказе с badge "Временный"
2. Нажать "Сделать постоянным"
3. Отредактировать название, добавить категории
4. Сохранить - комплект появится в каталоге
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
В order_detail.html:
- Добавлен badge "Временный" для временных комплектов
- Добавлена подсказка "Создан специально для этого заказа"
Теперь флорист видит какие комплекты в заказе являются временными.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Forms (orders/forms.py):
- TemporaryKitForm: упрощенная форма для временного комплекта (название + описание)
- TemporaryKitItemForm: форма для компонента временного комплекта
- TemporaryKitItemFormSet: formset для управления компонентами
Views (orders/views.py):
- create_temporary_kit: AJAX endpoint для создания временного комплекта
* Принимает JSON с названием, описанием и списком компонентов
* Создает комплект с is_temporary=True
* Связывает с заказом если указан order_id
* Автоматически пересчитывает цену
* Возвращает JSON с данными созданного комплекта
URLs (orders/urls.py):
- /orders/temporary-kits/create/ - endpoint для создания
Теперь можно создавать временные комплекты через AJAX запрос.
Следующий шаг - UI в форме заказа.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Views:
- ProductKitListView: фильтр is_temporary=False
- CombinedProductListView: фильтр is_temporary=False для комплектов
- API search: фильтр is_temporary=False в поиске и популярных
Admin:
- Добавлен фильтр по is_temporary
- Добавлено отображение статуса временного комплекта в списке
- Добавлена ссылка на заказ для временных комплектов
- Добавлен раздел "Временный комплект" в fieldsets
Теперь временные комплекты не показываются в общем каталоге,
но доступны в админке и по прямой ссылке (для заказов).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Добавлено поле is_temporary для пометки временных комплектов
- Добавлено поле order для связи с заказом
- Добавлены индексы для производительности
- Добавлен метод make_permanent() для преобразования в постоянный комплект
Временные комплекты создаются для конкретных заказов и не показываются
в общем каталоге, но хранятся в БД для истории и анализа.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add check_stock.py: script to view Stock records with reservations
- Add refresh_stock_reservations.py: standalone script to recalculate quantity_reserved for all Stock records
- Both scripts work with 'grach' tenant schema
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add management command to recalculate quantity_reserved for all Stock records
- Add signals to automatically update Stock when Reservation changes
- Implement post_save signal for Reservation creation/updates
- Implement post_delete signal for Reservation deletion
- Both signals call Stock.refresh_from_batches() to recalculate quantities
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
PROBLEM ANALYSIS:
- SQL script created orders bypassing Django ORM
- Django signals (post_save) didn't trigger
- No reservations were created automatically
- Found 51 orders with 102 items and 0 reservations
SOLUTION IMPLEMENTED:
1. Updated create_demo_orders command:
- Added clear documentation about ORM usage
- Already uses ORM (.save()) which triggers signals
- Added informative messages about automatic reservations
2. Created fix_missing_reservations command:
- Finds OrderItems without reservations
- Creates missing Reservation records
- Supports --dry-run mode for safety
- Handles missing warehouses gracefully
3. Created SQL fix script:
- Direct SQL approach for existing data
- Creates reservations for all 102 items
- Status: 'reserved'
- Verified: All items now have reservations
4. Added verification scripts:
- check_orders.py: Shows orders/items/reservations count
- run_fix_reservations.py: Executes SQL fix
RESULTS:
- ✓ 102 reservations created for existing orders
- ✓ Future orders will use ORM and create reservations automatically
- ✓ System now works correctly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Created management command for generating demo orders
- Added SQL script to create 25 orders with random dates (±15 days)
- Added Python runner script for executing SQL
- Demo orders include varied statuses, payment methods, and delivery types
- Orders distributed across different dates for testing date filter
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed label from "Дата доставки" to "Дата доставки/самовывоза"
- Moved "Сегодня" button from right to left side (next to label)
- Removed justify-content-between to keep button aligned with label
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Selected date now stays at its clicked position instead of jumping to center
- Fixed timezone issue in localStorage causing dates to shift by one day
- Carousel position is preserved across page reloads
- Simplified date selection logic by removing complex offset calculations
- Added updateSelectedState() method to update selection without re-rendering
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Расширен календарь с 9 до 19 дней (±9 от центра)
- Календарь теперь занимает всю ширину страницы
- Исправлены метки "Вчера/Сегодня/Завтра" - теперь привязаны к реальным датам, а не к позициям в ленте
- Добавлена автоматическая отправка формы при выборе даты
- Обновлён дизайн:
* Сегодняшний день выделен светло-голубым цветом (более мягкий оттенок)
* Выбранная дата обведена красной рамкой (как на настенном календаре)
- Добавлен блок extra_css в base.html для подключения дополнительных стилей
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Основные изменения:
**Компонент date_range_filter.html:**
- Заменены простые кнопки на горизонтальную ленту из 9 дней
- Добавлены стрелки навигации влево/вправо
- Скрытые поля дат для работы с django-filter
**Стили date_filter.css:**
- Дизайн календарной ленты с карточками дней
- Выделение сегодняшнего дня синим цветом
- Выделение выбранной даты зеленым цветом
- Hover-эффекты и анимации
- Адаптивность для мобильных устройств
- Стили для стрелок навигации
**Логика date_filter.js:**
- Класс DateCarousel для управления лентой
- Генерация 9 дней (±4 от центральной даты)
- Определение "Вчера/Сегодня/Завтра" для центральных 3 кнопок
- Отображение числа (01-31) и дня недели (ПН-ВС)
- Навигация стрелками (сдвиг на 1 день)
- Клик по дню устанавливает дату в оба поля фильтра
- Визуальная индикация выбранной даты
**Формат каждой кнопки:**
┌─────────┐
│ Сегодня │ ← Текст (если вчера/сегодня/завтра)
│ 07 │ ← Число месяца
│ ЧТ │ ← День недели
└─────────┘
**Поведение:**
- По умолчанию: сегодня в центре (5-я кнопка)
- Сегодняшний день выделен синим
- Клик по дню фильтрует заказы за эту конкретную дату
- Стрелки сдвигают весь диапазон на 1 день вперед/назад
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Изменения:
- Фильтры теперь расположены горизонтально в одной строке над таблицей
- Кнопка "Создать заказ" перенесена в правый верхний угол рядом с заголовком
- Календарный фильтр дат вынесен во вторую строку для лучшей читаемости
- Убрана двухколоночная компоновка, таблица теперь занимает всю ширину
- Улучшена компактность интерфейса - больше места для таблицы данных
Преимущества новой компоновки:
- Таблица заказов использует всю ширину экрана
- Фильтры компактно организованы сверху
- Улучшена видимость данных
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Основные изменения:
- Установлен и настроен django-filter==24.3
- Создан OrderFilter с фильтрами по дате доставки, статусу, типу, оплате и поиску
- Реализован переиспользуемый компонент календарного фильтра date_range_filter.html
- Добавлены быстрые кнопки выбора дат (Сегодня, Завтра, Неделя)
- Создан templatetag param_replace для сохранения фильтров при пагинации
- Обновлен order_list view для использования django-filter
- Полностью переработан шаблон order_list.html с интеграцией фильтров
- Добавлены стили (date_filter.css) и логика (date_filter.js) для календаря
Структура новых файлов:
- orders/filters.py - FilterSet для заказов
- orders/templatetags/filter_tags.py - кастомные теги для фильтров
- orders/templates/orders/components/date_range_filter.html - компонент календаря
- orders/static/orders/css/date_filter.css - стили
- orders/static/orders/js/date_filter.js - JavaScript логика
- requirements.txt - зависимости проекта
Преимущества:
- Чистая архитектура фильтрации
- Автоматическое сохранение параметров при навигации
- Переиспользуемый календарный компонент
- Улучшенный UX с быстрыми фильтрами
- Готовность к масштабированию на другие модели
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Заказы:
- Добавлены миграции для исторических записей с полями оплаты и получателя
- Расширен admin для заказов с инлайнами товаров/комплектов
- Реализованы представления списка, создания, редактирования и удаления заказов
- Добавлен шаблон подтверждения удаления заказа
- Настроены URL-маршруты для работы с заказами
Клиенты:
- Добавлена миграция с новыми полями адресов и подтверждений
- Обновлена модель клиентов с дополнительными полями
- Улучшен admin для работы с клиентами
Товары:
- Значительно улучшен API поиска товаров с поддержкой фильтрации
- Добавлен Select2 виджет для динамического поиска товаров
- Создан статический JS файл для интеграции Select2
- Оптимизирована обработка запросов и ответов API
Прочее:
- Добавлены новые настройки в settings.py
- Обновлена навигация в navbar.html
- Обновлены URL-маршруты проекта
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Изменена структура страницы /orders/:
- Создана двухколоночная компоновка (фильтры слева, таблица справа)
- Кнопка "Создать заказ" перенесена из верхней части под фильтры в левую панель
- Фильтры преобразованы в вертикальный макет для лучшей организации
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>