Repository URL to install this package:
|
Version:
0.4.184 ▾
|
import abc
import logging
from datetime import datetime
from lib_b2b.change import ChangeRecord, ChangeDataProvider
from lib_b2b.errors import VersionConflictError
from lib_b2b.order import Order
from lib_b2b.order_change import OrderChangeRequest, SimpleOrderPredicate
from lib_b2b.order_status import OrderStatus
from lib_b2b.order_totals import OrderTotals
from lib_b2b.policy import Policy
logger = logging.getLogger(__name__)
class OrderTotalChangeDataProvider(ChangeDataProvider, metaclass=abc.ABCMeta):
@property
@abc.abstractmethod
def new_totals(self) -> OrderTotals:
raise NotImplementedError
class OrderTotalChangeRequest(OrderChangeRequest):
# TODO: - Move these policies to be data driven
_policy = Policy(
name='total_change_policy',
subject=Policy.SUBJECT_ALL,
predicates=[
SimpleOrderPredicate(
lambda o: o.status < OrderStatus.SHIPPED,
'Totals can only be updated prior to shipping.')
]
)
def __init__(self, on_behalf_of: str, change_data_provider: OrderTotalChangeDataProvider):
super().__init__(on_behalf_of, OrderTotalChangeRequest._policy)
self.change_data_provider = change_data_provider
def will_change(self, order: Order) -> bool:
return self.change_data_provider.new_totals != order.totals
def apply(self, order: Order):
try:
self.changeable_object = order
if super().permitted(order):
if self.will_change(order):
before_totals = order.totals.as_dict()
order.set_totals(self.change_data_provider.new_totals,
version=self.change_data_provider.version())
after_totals = self.change_data_provider.new_totals.as_dict()
order.record(
ChangeRecord(before=before_totals, after=after_totals, description="Totals were updated",
when=datetime.now().astimezone(UTC), who=self.on_behalf_of)
)
except ValueError as ve:
raise VersionConflictError(str(ve))