Source code for salesman.orders.status

from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import gettext_lazy as _

from .models import Order


[docs]class BaseOrderStatus(models.TextChoices): """ Base order status enum, actuall choices must extend this class. """
[docs] @classmethod def get_payable(cls) -> list: """ Returns list of statuses from which an order is eligible for payment. """ return []
[docs] @classmethod def get_transitions(cls) -> list: """ Returns a dict of statuses with their transitions. If not specified for status, any transition is valid. """ return {}
[docs] @classmethod def validate_transition(cls, status: str, order: Order) -> None: """ Validate a given status transition for the order. By default check status is defined in transitions. Args: status (str): New status order (Order): Order instance Raises: ValidationError: If transition not valid """ transitions = cls.get_transitions().get(order.status, [status]) transitions.append(order.status) if status not in transitions: current, new = cls[order.status].label, cls[status].label msg = _(f"Can't change order with status '{current}' to '{new}'.") raise ValidationError(msg)
[docs]class OrderStatus(BaseOrderStatus): """ Default order choices enum. Can be overriden by providing a dotted path to a class in ``SALESMAN_ORDER_STATUS`` setting. Required choices are NEW, CREATED, COMPLETED and REFUNDED. """ NEW = 'NEW', _("New") # Order with reference created, items are in the basket. CREATED = 'CREATED', _("Created") # Created with items and pending payment. HOLD = 'HOLD', _("Hold") # Stock reduced but still awaiting payment. FAILED = 'FAILED', _("Failed") # Payment failed, retry is available. CANCELLED = 'CANCELLED', _("Cancelled") # Cancelled by seller, stock increased. PROCESSING = 'PROCESSING', _("Processing") # Payment confirmed, processing order. SHIPPED = 'SHIPPED', _("Shipped") # Shipped to customer. COMPLETED = 'COMPLETED', _("Completed") # Completed and received by customer. REFUNDED = 'REFUNDED', _("Refunded") # Fully refunded by seller. @classmethod def get_payable(cls) -> list: """ Returns default payable statuses. """ return [cls.CREATED, cls.HOLD, cls.FAILED] @classmethod def get_transitions(cls) -> list: """ Returns default status transitions. """ return { 'NEW': [cls.CREATED], 'CREATED': [cls.HOLD, cls.FAILED, cls.CANCELLED, cls.PROCESSING], 'HOLD': [cls.FAILED, cls.CANCELLED, cls.PROCESSING], 'FAILED': [cls.CANCELLED, cls.PROCESSING], 'CANCELLED': [], 'PROCESSING': [cls.SHIPPED, cls.COMPLETED, cls.REFUNDED], 'SHIPPED': [cls.COMPLETED, cls.REFUNDED], 'COMPLETED': [cls.REFUNDED], 'REFUNDED': [], }