Repository URL to install this package:
|
Version:
0.4.184 ▾
|
import abc
import logging
from datetime import datetime, timezone
from lib_b2b.change import ChangeRecord, ChangeDataProvider
from lib_b2b.errors import VersionConflictError
from lib_b2b.financial_status import FinancialStatus
from lib_b2b.order import Order
from lib_b2b.order_change import OrderChangeRequest, SimpleOrderPredicate
from lib_b2b.order_status import OrderStatus
from lib_b2b.policy import Policy
logger = logging.getLogger(__name__)
class OrderFinancialStatusChangeDataProvider(ChangeDataProvider, metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def financial_status(self) -> FinancialStatus:
raise NotImplementedError
class OrderFinancialStatusChangeRequest(OrderChangeRequest):
# TODO: - Move these policies to be data driven
_policy = Policy(
name='financial_status_change_policy',
subject=Policy.SUBJECT_ALL,
predicates=[
SimpleOrderPredicate(
lambda o: o.status < OrderStatus.SHIPPED,
'Paid status can only be changed prior to shipping.')
]
)
def __init__(self, on_behalf_of: str, change_data_provider: OrderFinancialStatusChangeDataProvider):
super().__init__(on_behalf_of, OrderFinancialStatusChangeRequest._policy)
self.change_data_provider = change_data_provider
def will_change(self, order: Order) -> bool:
return self.change_data_provider.financial_status > order.financial_status
def apply(self, order: Order):
try:
self.changeable_object = order
if super().permitted(order):
if self.will_change(order):
before_status = order.financial_status
before_order_status = order.status
order.set_financial_status(self.change_data_provider.financial_status,
version=self.change_data_provider.version())
if order.financial_status is FinancialStatus.PAID \
and order.status in (OrderStatus.UNPAID, OrderStatus.VALID):
order.status = OrderStatus.READY
order.record(ChangeRecord(
before={'financial_status': before_status.value, 'order_status': before_order_status.value},
after={'financial_status': order.financial_status.value, 'order_status': order.status.value},
description=f"Financial status was updated to {self.change_data_provider.financial_status.value}",
when=datetime.now(tz=timezone.utc), who=self.on_behalf_of)
)
except ValueError as ve:
raise VersionConflictError(str(ve))