from ast import Or from datetime import datetime, timedelta from data.repositories.protocols.customer_repository_protocol import CustomerRepositoryProtocol from data.repositories.protocols.order_repository_protocol import OrderRepositoryProtocol from domain.exceptions.order_exceptions import OrderAlreadyDeliveredException, OrderNotFoundException from domain.entities.order import Order, OrderWithStatus class OrderService: DELIVERY_DELAY_MINUTES = 45 WARNING_THRESHOLD_MINUTES = 30 FREE_DELIVERY_THRESHOLD = 25.0 PREMIUM_THRESHOLD = 10 def __init__( self, order_repo: OrderRepositoryProtocol, customer_repo: CustomerRepositoryProtocol ): self.order_repo = order_repo self.customer_repo = customer_repo def get_orders_with_status(self, customer_id: int): orders = self.order_repo.find_by_customer_id(customer_id) customer = self.customer_repo.find_by_id(customer_id) result = [] for order in orders: result.append( OrderWithStatus( order_id= order.id, restaurant_name= order.restaurant_name, total_amount= order.amount(), is_late= order.is_late(), free_delivery= order.amount() >= self.FREE_DELIVERY_THRESHOLD, is_premium_customer= customer.order_count >= self.PREMIUM_THRESHOLD, status= order.status(), urgency_level= order.urgency_level(self.DELIVERY_DELAY_MINUTES, self.WARNING_THRESHOLD_MINUTES) ) ) return result def mark_order_as_delivered(self, order_id: int): order = self.order_repo.find_by_id(order_id) if order is None: raise OrderNotFoundException(order_id) if order.delivery_at is not None: raise OrderAlreadyDeliveredException(order_id) order.delivery_at = datetime.now() self.order_repo.update(order) customer = self.customer_repo.find_by_id(order.customer_id) return OrderWithStatus( order_id= order.id, restaurant_name= order.restaurant_name, total_amount= order.amount(), is_late= order.is_late(), free_delivery= order.amount() >= self.FREE_DELIVERY_THRESHOLD, is_premium_customer= customer.order_count >= self.PREMIUM_THRESHOLD, status= order.status(), urgency_level= order.urgency_level(self.DELIVERY_DELAY_MINUTES, self.WARNING_THRESHOLD_MINUTES) )