Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
lib-py-b2b / order_change / accept.py
Size: Mime:
import logging
from datetime import datetime

from boto3.dynamodb.conditions import Attr, Or
from botocore.exceptions import ClientError

from lib_b2b.change import ChangeRecord
from lib_b2b.errors import OrderStatusChangeError, VersionConflictError
from lib_b2b.order import Order
from lib_b2b.order_change import OrderChangeRequest, SimpleOrderPredicate, OrderStatusChangeDataProvider
from lib_b2b.order_status import OrderStatus
from lib_b2b.policy import Policy

logger = logging.getLogger(__name__)


class OrderAcceptChangeRequest(OrderChangeRequest):
    # TODO: - Move these policies to be data driven
    _policy = Policy(
        name='accept_change_policy',
        subject=Policy.SUBJECT_ALL,
        predicates=[
            SimpleOrderPredicate(
                lambda o: o.status is OrderStatus.READY,
                'Accept is only allowed if the order is Ready.')
        ]
    )

    def __init__(self, on_behalf_of: str, change_data_provider: OrderStatusChangeDataProvider):
        super().__init__(on_behalf_of, OrderAcceptChangeRequest._policy)
        self.change_data_provider = change_data_provider

    def will_change(self, order: Order) -> bool:
        return self.change_data_provider.new_status is OrderStatus.ACCEPTED \
               and order.status is not OrderStatus.ACCEPTED

    def apply(self, order: Order):
        try:
            self.changeable_object = order
            if super().permitted(order):
                if self.will_change(order):
                    before_status = order.status
                    expressions = [
                        Attr('acknowledgement_sent').not_exists(),
                        Attr('acknowledgement_sent').eq(False)
                    ]
                    conditions = Or(*expressions)
                    order.set_status(new_status=OrderStatus.ACCEPTED,
                                     conditions=conditions,
                                     version=self.change_data_provider.version())
                    order.modify(
                        data={
                            'acknowledged': True,
                            'acknowledgement_sent': False,
                            'acknowledged_date': datetime.now().isoformat()
                        }
                    )
                    order.record(
                        ChangeRecord(before=before_status.value, after=OrderStatus.ACCEPTED.value,
                                     description="Order was Accepted", when=datetime.now(), who=self.on_behalf_of)
                    )
        except ValueError as ve:
            raise VersionConflictError(str(ve))
        except ClientError as ce:
            # order.error(ErrorRecord(code="ORDER-11",
            #                         msg=f"Order accept failed due to client error. [{str(ce)}]"))
            logger.error(f"Order accept failed due to client error. [{str(ce)}]")
            raise OrderStatusChangeError("Unable to accept order") from ce