Рефакторинг: отделение Delivery от Order, обязательные поля доставки, исправление доменов

- Отделена модель Delivery от Order (OneToOne связь)
- Добавлены обязательные поля delivery_date, time_from, time_to в Delivery
- Delivery обязательна при создании заказа (кроме черновиков)
- Добавлены методы calculate_total() и reset_delivery_cost() в Order
- Добавлена валидация полей доставки в OrderForm
- Исправлено создание доменов - убран порт из домена в БД
- Исправлен редирект после установки пароля (правильный формат URL)
- Исправлена ошибка NoReverseMatch в navbar для public схемы
- Удалены все старые миграции (база создается с нуля)
- Обновлены views для работы с новой моделью Delivery
This commit is contained in:
2025-12-23 23:52:59 +03:00
parent d29c736252
commit 94fe363cb1
61 changed files with 1342 additions and 2189 deletions

View File

@@ -1,95 +0,0 @@
# -*- coding: utf-8 -*-
"""
Сервис для расчета стоимости доставки.
Содержит расширяемую логику вычисления на основе различных условий.
"""
from decimal import Decimal
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from orders.models import Order
class DeliveryCostCalculator:
"""
Калькулятор стоимости доставки.
Применяет различные правила для автоматического расчета.
"""
# Константы для правил расчета
FREE_DELIVERY_THRESHOLD = Decimal('100.00') # Бесплатная доставка от суммы
BASE_DELIVERY_COST = Decimal('15.00') # Базовая стоимость доставки
MIN_DELIVERY_COST = Decimal('0.00') # Минимальная стоимость
@classmethod
def calculate(cls, order: 'Order') -> Decimal:
"""
Рассчитывает стоимость доставки на основе условий заказа.
Args:
order: Заказ для расчета
Returns:
Decimal: Рассчитанная стоимость доставки
"""
# Самовывоз - доставка бесплатная
if not order.is_delivery:
return cls.MIN_DELIVERY_COST
# Рассчитываем сумму товаров
items_total = sum(
item.get_total_price()
for item in order.items.all()
)
# Применяем правила расчета
cost = cls._apply_calculation_rules(order, items_total)
return cost
@classmethod
def _apply_calculation_rules(cls, order: 'Order', items_total: Decimal) -> Decimal:
"""
Применяет правила расчета стоимости доставки.
Этот метод легко расширить для добавления новых правил.
Args:
order: Заказ
items_total: Сумма товаров в заказе
Returns:
Decimal: Стоимость доставки
"""
# Правило 1: Бесплатная доставка при заказе от определенной суммы
if items_total >= cls.FREE_DELIVERY_THRESHOLD:
return cls.MIN_DELIVERY_COST
# Правило 2: Базовая стоимость доставки
cost = cls.BASE_DELIVERY_COST
# Правило 3: Можно добавить расчет по адресу
# if order.delivery_address:
# cost += cls._calculate_distance_cost(order.delivery_address)
# Правило 4: Можно добавить надбавку за срочность
# if cls._is_urgent_delivery(order):
# cost *= Decimal('1.5')
return cost
@classmethod
def _calculate_distance_cost(cls, address) -> Decimal:
"""
Рассчитывает надбавку за расстояние.
Placeholder для будущей реализации с геокодингом.
"""
# TODO: Интеграция с картами для расчета расстояния
return Decimal('0.00')
@classmethod
def _is_urgent_delivery(cls, order: 'Order') -> bool:
"""
Проверяет, является ли доставка срочной.
"""
# TODO: Логика определения срочности
return False