Commit Graph

23 Commits

Author SHA1 Message Date
47c3259dcf Исправлена ссылка входа: теперь ведет на /accounts/login/ вместо /admin/ 2025-12-02 01:08:43 +03:00
43029ab460 Улучшена компактность формы регистрации: поля в 2 колонки, уменьшены отступы, добавлена ссылка для входа, исправлена опечатка в help_text 2025-12-02 01:06:58 +03:00
5376869294 Кастомизация дизайна админки и страницы регистрации: нейтральный стиль админки Django, компактная форма регистрации 2025-12-02 00:53:17 +03:00
4404bebba7 fix: add missing RoleService import and improve admin buttons layout
- Fixed UnboundLocalError by importing RoleService before use
- Changed action buttons to vertical stack layout to prevent overlap
- Buttons now use flexbox column layout with proper spacing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 22:20:14 +03:00
4da6d6922e fix: trigger tenant activation when status changed to approved
Added save_model override to TenantRegistrationAdmin to catch status
changes from PENDING to APPROVED and trigger the full activation flow.

Previously, changing status via admin form only saved the status field
without creating the tenant, sending emails, etc.

Now both methods work:
- Click "Activate" button (via GET parameter)
- Change status dropdown and save (via save_model)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 22:15:43 +03:00
fb4bcf37ec feat: implement password setup link for tenant registration
When admin approves tenant registration:
- Owner account created in tenant schema (in addition to admin@localhost)
- Owner assigned 'owner' role with full permissions
- Password setup email sent with secure 7-day token link
- Owner sets password via link and auto-logs into their shop

Key changes:
- Added password_setup_token fields to TenantRegistration model
- Created tenants/services.py with formatted email service
- Modified _approve_registration to create owner account
- Added password_setup_confirm view with token validation
- Created password setup template and URL route
- Added admin action to resend password setup emails

Security:
- Token expires after 7 days
- Password not transmitted in email (secure setup link)
- Owner account inactive until password set
- Admin@localhost preserved for system administrator access

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 22:08:18 +03:00
f4e7ad0aac feat: implement user roles system with tenant isolation
Добавлена система ролей пользователей для управления доступом в multi-tenant приложении.

Новые роли:
- Владелец (Owner): полный доступ, управление пользователями
- Менеджер (Manager): управление заказами, клиентами, товарами, складом
- Флорист (Florist): работа с заказами и складскими операциями
- Курьер (Courier): роль создана, права будут определены позже

Архитектура:
- Роли автоматически изолируются по тенантам через django-tenants (TENANT_APPS)
- Не требуется FK на Client/Tenant - изоляция через PostgreSQL schemas
- Роли автоматически создаются при создании нового тенанта

Компоненты:
- user_roles/models.py: модели Role и UserRole
- user_roles/services.py: RoleService для управления ролями
- user_roles/decorators.py: @role_required, @owner_required
- user_roles/mixins.py: RoleBasedAdminMixin, OwnerOnlyAdminMixin
- user_roles/admin.py: админка для управления ролями
- user_roles/management/commands/init_roles.py: команда для инициализации

Изменения:
- accounts/models.py: добавлены helper методы (is_owner, has_role, etc)
- settings.py: добавлен user_roles в TENANT_APPS
- tenants/admin.py: автосоздание ролей при создании тенанта

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 18:06:47 +03:00
e4cb175db2 Исправлена критическая проблема с резервами при смене статуса заказа
Проблема:
- При смене статуса заказа на 'Выполнен' товар списывался со склада
- Резервы обновлялись на статус 'converted_to_sale'
- НО Stock.quantity_reserved не обновлялся автоматически
- В результате резервы продолжали 'держать' товар, хотя он уже продан

Решение:
1. Изменен сигнал create_sale_on_order_completion:
   - Используется .save(update_fields=[...]) вместо .update()
   - Это вызывает сигнал update_stock_on_reservation_change
   - Убран костыль с ручным вызовом refresh_from_batches()

2. Оптимизирован сигнал update_stock_on_reservation_change:
   - Stock обновляется ТОЛЬКО при изменении status или quantity
   - При изменении других полей (даты и т.д.) Stock НЕ пересчитывается
   - Предотвращены лишние пересчёты и улучшена производительность

3. Добавлены диагностические инструменты:
   - check_stock_103.py - для диагностики проблем с Stock
   - fix_stock_after_sale.py - команда для исправления старых заказов
   - diagnose_reservation_issue.py - универсальная диагностика

Результат:
- Элегантное решение без дублирования логики
- Stock автоматически обновляется при изменении резервов
- Работает везде, не только в заказах
- Оптимизировано для производительности
2025-12-01 02:34:54 +03:00
490e5d5401 Добавлены интеграционные тесты создания тенантов
Создан файл tenants/tests/test_tenant_creation.py с 7 E2E тестами:

1. test_new_tenant_gets_all_5_payment_methods (КРИТИЧЕСКИЙ)
   - Проверяет что новый тенант получает все 5 способов оплаты
   - Включая account_balance (основной баг который исправили)
   - Проверяет правильность порядка, флагов, названий

2. test_new_tenant_gets_order_statuses
   - Проверяет создание системных статусов заказов
   - Минимум 3 статуса (draft, completed и другие)

3. test_new_tenant_gets_system_customer
   - Проверяет создание системного клиента
   - Для анонимных продаж

4. test_new_tenant_gets_superuser
   - Проверяет создание суперпользователя
   - С email из настроек TENANT_ADMIN_EMAIL

5. test_new_tenant_gets_domain
   - Проверяет создание домена
   - Формат: {schema_name}.localhost

6. test_registration_status_changes_to_approved
   - Проверяет изменение статуса заявки
   - PENDING → APPROVED

7. test_complete_tenant_onboarding (КОМПЛЕКСНЫЙ E2E)
   - Проверяет весь процесс онбординга
   - Все предыдущие проверки в одном тесте
   - Красивый вывод результата в консоль

Особенности:
- TransactionTestCase для работы с реальными схемами
- Создание администратора в setUp для каждого теста
- Автоматическая очистка схем в tearDown
- Вызов реального метода _approve_registration из админки
- Полное тестирование процесса как в продакшене

Результат: 2 главных теста прошли успешно ✓
test_new_tenant_gets_all_5_payment_methods: OK (10s)
test_complete_tenant_onboarding: OK (9.5s)
2025-12-01 01:41:01 +03:00
7188b11f65 Единый источник истины для способов оплаты
Проблема #1: Дублирование кода способов оплаты
- В tenants/admin.py был полный список способов оплаты (45 строк)
- В orders/management/commands/create_payment_methods.py был другой список
- При создании тенанта отсутствовал способ 'account_balance'
- Нарушение DRY принципа

Решение: Single Source of Truth
- Единственный источник истины: команда create_payment_methods
- В tenants/admin.py заменено дублирование на call_command()
- Удалено 45 строк дублирующего кода
- Теперь все тенанты получают одинаковый полный список

Проблема #2: AttributeError в админке PaymentMethod
- obj.payments.count() вызывал ошибку
- В модели Transaction связь называется 'transactions', а не 'payments'

Решение: Исправлено в orders/admin.py
- obj.payments → obj.transactions (2 места)
- Админка PaymentMethod теперь работает корректно

Для тенанта buba:
- Создан скрипт add_payment_methods_to_buba.py
- Добавлен недостающий способ оплаты 'С баланса счёта'

Изменённые файлы:
- myproject/tenants/admin.py - вызов команды вместо дублирования
- myproject/orders/admin.py - исправлено на transactions
- add_payment_methods_to_buba.py - скрипт для существующих тенантов
2025-12-01 01:22:40 +03:00
0653ec0545 Рефакторинг моделей заказов и добавление методов оплаты 2025-11-26 13:38:02 +03:00
8079abe939 Feat: Add cleanup_tenant management command for improved tenant deletion
- Create new cleanup_tenant command with better tenant deletion workflow
- Handle TenantRegistration automatic processing (keep history or delete)
- Add --purge-registration flag to remove TenantRegistration records
- Add --delete-files flag to remove physical tenant files from /media/tenants/
- Provide detailed deletion summary with confirmation step
- Update УДАЛЕНИЕ_ТЕНАНТОВ.md documentation with:
  * Complete guide for new cleanup_tenant command
  * Explanation of TenantRegistration problem and solutions
  * Recommendations for different use cases (test vs production)
  * Examples of all command variants

Tested:
- Successfully deleted grach tenant (no registration)
- Successfully deleted bingo tenant with --purge-registration flag
- Verified registration records are properly managed
- All database and file operations work correctly

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 21:32:32 +03:00
4a9df60f91 Auto-create order statuses on tenant activation
Add OrderStatusService.create_default_statuses() call during tenant
registration approval. Creates 8 system order statuses (draft, new,
confirmed, in_assembly, in_delivery, completed, return, cancelled).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 01:14:28 +03:00
685c06d94d Добавлена функциональность системного клиента для анонимных покупок
- Добавлено поле is_system_customer в модель Customer с индексом
- Системный клиент создается автоматически при создании нового тенанта
- Реализована защита системного клиента от редактирования и удаления:
  - Защита на уровне модели (save/delete методы)
  - Защита на уровне формы (валидация)
  - Защита на уровне представлений (проверки с дружественными сообщениями)
  - Защита в админке (readonly поля, запрет удаления)
- Системный клиент скрыт из списков и поиска на фронтенде
- Создан информационный шаблон для отображения системного клиента
- Исправлена обработка NULL значений для полей email/phone (Django best practice)
- Добавлено отображение "Не указано" вместо None в карточке клиента

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 00:07:38 +03:00
755e4fc9d9 комит 2025-11-19 22:12:01 +03:00
7132d2c910 feat: Замена is_active на status для архивирования товаров
Реализована трёхуровневая система статусов товаров и комплектов:
- active (Активный) - товар доступен для продажи
- archived (Архивный) - скрыт, можно восстановить в следующем сезоне
- discontinued (Снят) - морально устарел, готов к удалению

Изменения:
1. Модели (BaseProductEntity, Product, ProductKit):
   - Заменено поле is_deleted (Boolean) на status (CharField)
   - Добавлены архивные метаданные (archived_at, archived_by)
   - Обновлены методы: archive(), restore(), discontinue(), delete()
   - Уникальное ограничение изменено на conditional (status='active')

2. Менеджеры (ActiveManager, SoftDeleteQuerySet):
   - Полиморфная поддержка обеих систем (status и is_active)
   - Использует hasattr() для совместимости с наследниками
   - Методы: archive(), restore(), discontinue(), archived_only(), active_only()

3. Формы (ProductForm, ProductKitForm):
   - Включены поле status в формы
   - Валидация уникальности по status='active'
   - CSS классы для статус-селектора

4. Admin панель:
   - DeletedFilter переименован в StatusFilter с тремя опциями
   - get_status_display() с цветным отображением статуса
   - Actions: restore_items, hard_delete_selected, delete_selected
   - Readonly поля для архивирования

5. Представления:
   - ProductListView: фильтр status вместо is_active
   - CombinedProductListView: поддержка фильтра status для товаров и комплектов
   - API views обновлены для работы со статусом

6. Шаблоны:
   - product_form.html: form.status вместо form.is_active
   - productkit_create.html: form.status вместо form.is_active
   - productkit_edit.html: form.status вместо form.is_active

7. Миграции:
   - Удалены все старые миграции (чистый перезапуск по требованию пользователя)
   - Создана новая миграция 0001_initial с полной структурой status-системы
   - Удален старый код преобразования is_deleted -> status

Проведённые проверки:
- Django system check passed ✓
- Полиморфные менеджеры работают с обеими системами
- Уникальные ограничения корректно работают с условиями
- История заказов сохраняется даже после архивирования товара (django-simple-history)

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-15 15:30:23 +03:00
4a4bd437b9 refactor: Заменить сущность Магазин (Shop) на Склад (Warehouse)
Упрощена логика системы путём замены отдельной сущности "Магазин"
на универсальную сущность "Склад", которая может использоваться
как точка самовывоза.

Изменения:
- Расширена модель Warehouse: добавлены адрес, контакты, флаг is_pickup_point
- Модель Order: поле pickup_shop заменено на pickup_warehouse
- Обновлены все формы, сервисы, views, admin для работы со складами
- Обновлены шаблоны HTML и JavaScript код
- Удалено приложение shops полностью
- Пересозданы миграции БД
- Обновлён навбар (удалена ссылка на магазины)

Преимущества:
- Упрощена архитектура системы
- Единая точка управления складами и точками самовывоза
- Интеграция с системой инвентаризации

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-14 23:50:30 +03:00
c7875f147c Implement flexible order status management system
Features:
- Created OrderStatus model for managing statuses per tenant
- Added system-level statuses: draft, new, confirmed, in_assembly, in_delivery, completed, return, cancelled
- Implemented CRUD views for managing order statuses
- Created OrderStatusService with status transitions and business logic hooks
- Updated Order model to use ForeignKey to OrderStatus
- Added is_returned flag for tracking returned orders
- Updated filters to work with new OrderStatus model
- Created management command for status initialization
- Added HTML templates for status list, form, and confirmation
- Fixed views.py to use OrderStatus instead of removed STATUS_CHOICES

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 16:29:50 +03:00
c8923970ea Упрощена система номеров заказов: переход на числовые номера
- Изменено поле order_number с CharField на PositiveIntegerField
- Удален метод generate_order_number()
- Упрощен метод save() - автоинкремент на основе максимального значения
- Номера заказов теперь хранятся как числа (1, 2, 3, ...) без форматирования
- Удалены все миграции для чистого старта

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 20:44:42 +03:00
6c8af5ab2c fix: Улучшения системы ценообразования комплектов
Исправлены 4 проблемы:
1. Расчёт цены первого товара - улучшена валидация в getProductPrice и calculateFinalPrice
2. Отображение actual_price в Select2 вместо обычной цены
3. Количество по умолчанию = 1 для новых форм компонентов
4. Auto-select текста при клике на поле количества для удобства редактирования

Изменённые файлы:
- products/forms.py: добавлен __init__ в KitItemForm для quantity.initial = 1
- products/templates/includes/select2-product-init.html: обновлена formatSelectResult
- products/templates/productkit_create.html: добавлен focus handler для auto-select
- products/templates/productkit_edit.html: добавлен focus handler для auto-select

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 19:04:03 +03:00
6735be9b08 feat: Реализовать систему поступления товаров с партиями (IncomingBatch)
Основные изменения:
- Создана модель IncomingBatch для группировки товаров по документам
- Каждое поступление (Incoming) связано с одной батчем поступления
- Автоматическое создание StockBatch для каждого товара в приходе
- Реализована система нумерации партий (IN-XXXX-XXXX) с поиском максимума в БД
- Обновлены все представления (views) для работы с новой архитектурой
- Добавлены детальные страницы просмотра партий поступлений
- Обновлены шаблоны для отображения информации о партиях и их товарах
- Исправлена логика сигналов для создания StockBatch при приходе товара
- Обновлены формы для работы с новой структурой IncomingBatch

Архитектура FIFO:
- IncomingBatch: одна партия поступления (номер IN-XXXX-XXXX)
- Incoming: товар в партии поступления
- StockBatch: одна партия товара на складе (создается для каждого товара)

Это позволяет системе правильно применять FIFO при продаже товаров.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 03:26:06 +03:00
097d4ea304 feat: Добавить систему мультитенантности с регистрацией магазинов
Реализована полноценная система мультитенантности на базе django-tenants.
Каждый магазин получает изолированную схему БД и поддомен.

Основные компоненты:

Django-tenants интеграция:
- Модели Client (тенант) и Domain в приложении tenants/
- Разделение на SHARED_APPS и TENANT_APPS
- Public schema для общей админки
- Tenant schemas для изолированных данных магазинов

Система регистрации магазинов:
- Публичная форма регистрации на /register/
- Модель TenantRegistration для заявок со статусами (pending/approved/rejected)
- Валидация schema_name (латиница, 3-63 символа, уникальность)
- Проверка на зарезервированные имена (admin, api, www и т.д.)
- Админ-панель для модерации заявок с кнопками активации/отклонения

Система подписок:
- Модель Subscription с планами (триал 90 дней, месяц, квартал, год)
- Автоматическое создание триальной подписки при активации
- Методы is_expired() и days_left() для проверки статуса
- Цветовая индикация в админке (зеленый/оранжевый/красный)

Приложения:
- tenants/ - управление тенантами, регистрация, подписки
- shops/ - точки магазинов/самовывоза (tenant app)
- Обновлены миграции для всех приложений

Утилиты:
- switch_to_tenant.py - переключение между схемами тенантов
- Обновлены image_processor и image_service

Конфигурация:
- urls_public.py - роуты для public schema (админка + регистрация)
- urls.py - роуты для tenant schemas (магазины)
- requirements.txt - добавлены django-tenants, django-environ, phonenumber-field

Документация:
- DJANGO_TENANTS_SETUP.md - настройка мультитенантности
- TENANT_REGISTRATION_GUIDE.md - руководство по регистрации
- QUICK_START.md - быстрый старт
- START_HERE.md - общая документация

Использование:
1. Пользователь: http://localhost:8000/register/ → заполняет форму
2. Админ: http://localhost:8000/admin/ → активирует заявку
3. Результат: http://{schema_name}.localhost:8000/ - готовый магазин

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 19:13:10 +03:00
4b44624f86 feat: Добавить автоматическое создание суперпользователей для тенантов
Реализована система автоматического создания суперпользователей при активации
новых тенантов (магазинов). Credentials читаются из .env файла.

Изменения:
- Подключен django-environ для управления переменными окружения
- Обновлен settings.py: SECRET_KEY, DEBUG, DATABASE теперь из .env
- Добавлены настройки TENANT_ADMIN_EMAIL, TENANT_ADMIN_PASSWORD, TENANT_ADMIN_NAME
- Обновлен tenants/admin.py: автоматическое создание superuser при активации
- Создан activate_tenant.py: универсальный скрипт активации заявок
- Обновлен activate_mixflowers.py: добавлено создание superuser
- Создан .gitignore для защиты секретов
- Добавлена документация TENANT_ADMIN_GUIDE.md

Использование:
1. Через админку: Заявки → Активировать (автоматически создаст superuser)
2. Через скрипт: python activate_tenant.py <schema_name>

Доступ к админке тенанта:
- URL: http://{schema_name}.localhost:8000/admin/
- Email: admin@localhost (из .env)
- Password: 1234 (из .env)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 18:20:26 +03:00