# -*- 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