Рефакторинг: отделение 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:
@@ -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
|
||||
Reference in New Issue
Block a user