""" Сервис для управления статусами заказов. Содержит бизнес-логику для работы со статусами и их переходами. """ from django.db import transaction from orders.models import OrderStatus, Order class OrderStatusService: """Сервис для работы со статусами заказов""" @staticmethod def get_default_status(): """ Возвращает статус по умолчанию для новых заказов ('new') """ try: return OrderStatus.objects.get(code='new', is_system=True) except OrderStatus.DoesNotExist: return None @staticmethod def get_draft_status(): """Возвращает системный статус 'draft' (черновик)""" try: return OrderStatus.objects.get(code='draft', is_system=True) except OrderStatus.DoesNotExist: return None @staticmethod def get_new_status(): """Возвращает системный статус 'new' (новый заказ)""" status, created = OrderStatus.objects.get_or_create( code='new', defaults={ 'name': 'Новый', 'label': 'Новый', 'is_system': True, 'color': '#0d6efd', 'order': 10, } ) return status @staticmethod def get_system_status(code): """Получить системный статус по коду""" try: return OrderStatus.objects.get(code=code, is_system=True) except OrderStatus.DoesNotExist: return None @staticmethod def create_default_statuses(): """ Создает системные статусы для тенанта. Вызывается при первом использовании или миграции. """ default_statuses = [ { 'code': 'draft', 'name': 'Черновик', 'label': 'Черновик', 'is_system': True, 'order': 0, 'color': '#9E9E9E', 'description': 'Заказ находится в процессе создания/редактирования' }, { 'code': 'new', 'name': 'Новый', 'label': 'Новый', 'is_system': True, 'order': 10, 'color': '#2196F3', 'description': 'Новый заказ, ожидающий обработки' }, { 'code': 'confirmed', 'name': 'Подтвержден', 'label': 'Подтвержден', 'is_system': True, 'order': 20, 'color': '#FF9800', 'description': 'Заказ подтвержден и одобрен' }, { 'code': 'in_assembly', 'name': 'В сборке', 'label': 'В сборке', 'is_system': True, 'order': 30, 'color': '#FF9800', 'description': 'Заказ находится в процессе сборки/подготовки' }, { 'code': 'partially_assembled', 'name': 'Частично собран', 'label': 'Частично собран', 'is_system': True, 'order': 35, 'color': '#FFC107', 'description': 'Заказ частично собран, некоторые позиции готовы' }, { 'code': 'fully_assembled', 'name': 'Полностью собран', 'label': 'Полностью собран', 'is_system': True, 'order': 38, 'color': '#8BC34A', 'description': 'Заказ полностью собран и готов к отгрузке/доставке' }, { 'code': 'in_delivery', 'name': 'В доставке', 'label': 'В доставке', 'is_system': True, 'order': 40, 'color': '#9C27B0', 'description': 'Заказ в пути к клиенту' }, { 'code': 'completed', 'name': 'Выполнен', 'label': 'Выполнен', 'is_system': True, 'is_positive_end': True, 'order': 50, 'color': '#4CAF50', 'description': 'Заказ успешно доставлен/выполнен' }, { 'code': 'return', 'name': 'Возврат', 'label': 'Возврат', 'is_system': True, 'order': 60, 'color': '#FF5722', 'description': 'Заказ возвращен клиентом' }, { 'code': 'cancelled', 'name': 'Отменен', 'label': 'Отменен', 'is_system': True, 'is_negative_end': True, 'order': 70, 'color': '#F44336', 'description': 'Заказ отменен' }, ] for status_data in default_statuses: OrderStatus.objects.get_or_create( code=status_data['code'], defaults=status_data ) @staticmethod @transaction.atomic def change_order_status(order, new_status, user, notes=""): """ Меняет статус заказа и выполняет соответствующую бизнес-логику. Args: order (Order): Экземпляр заказа new_status (OrderStatus): Новый статус user (CustomUser): Пользователь, делающий изменение notes (str): Опциональные заметки Returns: Order: Обновленный экземпляр заказа Raises: ValueError: Если статус не может быть применен """ old_status = order.status order.status = new_status order.modified_by = user order.save() # Запустить бизнес-логику в зависимости от нового статуса if new_status.code == 'completed': _handle_order_completion(order, user) elif new_status.code == 'cancelled': _handle_order_cancellation(order, old_status, user) elif new_status.code == 'return': _handle_order_return(order, user) return order @staticmethod def get_all_statuses(): """Возвращает все статусы, отсортированные по порядку""" return OrderStatus.objects.all().order_by('order', 'name') @staticmethod def get_system_statuses(): """Возвращает только системные статусы""" return OrderStatus.objects.filter(is_system=True).order_by('order') @staticmethod def get_custom_statuses(): """Возвращает только пользовательские статусы""" return OrderStatus.objects.filter(is_system=False).order_by('order', 'name') def _handle_order_completion(order, user): """ Обработка при переводе в статус 'Выполнен'. Здесь происходит списание товаров со склада. TODO: Интеграция с inventory приложением """ # from inventory.services import InventoryService # InventoryService.process_order_completion(order) pass def _handle_order_cancellation(order, old_status, user): """ Обработка при переводе в статус 'Отменен'. Если заказ был выполнен - возвращаем товары и деньги. """ if old_status and old_status.code == 'completed': # Заказ был выполнен - нужно вернуть товары и деньги order.is_returned = True order.save() # TODO: Интеграция с inventory - возврат товаров # InventoryService.process_order_return(order) # TODO: Интеграция с платежами - создать возврат # PaymentService.create_refund(order) else: # Заказ отменен до выполнения - просто отменить резервы # TODO: InventoryService.cancel_order_reservation(order) pass def _handle_order_return(order, user): """ Обработка при переводе в статус 'Возврат'. Это промежуточный статус перед окончательной отменой. """ order.is_returned = True order.save() # TODO: Интеграция с inventory - вернуть товары на склад # InventoryService.process_order_return(order)