Repository URL to install this package:
|
Version:
0.4.139 ▾
|
lib-py-b2b
/
acknowledge.py
|
|---|
from os import environ
import datetime
import logging
from boto3 import resource
from botocore.exceptions import ClientError
from validators import url
from .errors import AcknowledgementFailedError, AcknowledgementFailedWarning
from .profile import Profile
from .shopify import CancelOrderAction
order_table = environ['order_table'] if 'order_table' in environ else 'test.b2b.Orders'
log_level = logging.getLevelName(environ['LOG_LEVEL']) if 'LOG_LEVEL' in environ else logging.INFO
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(log_level)
MAX_RETRY_COUNT = 5
class Acknowledgement:
def __init__(self, order):
self.order = order
self.profile = Profile.profile_for(customer=self.order['customer_edi_id'])
def __record_status(self, was_successful, msg=None):
try:
dynamodb_resource = resource('dynamodb', region_name='us-east-1')
table = dynamodb_resource.Table(order_table)
oid = self.order['id']
logger.debug(f"Updating order acknowledgement status (success: {was_successful}) for order {oid}")
if was_successful:
response = table.update_item(
Key={'id': oid},
UpdateExpression="set acknowledged = :a, acknowledged_date = :d, acknowledgement_sent = :s",
ExpressionAttributeValues={
':s': True,
':d': datetime.datetime.now().isoformat(),
':a': True
},
ReturnValues="UPDATED_NEW"
)
else:
retry_count = self.order['acknowledged_send_retry_count'] if 'acknowledged_send_retry_count' in self.order else 0
retry_count = retry_count + 1
response = table.update_item(
Key={'id': oid},
UpdateExpression="set acknowledged = :s, acknowledgement_last_error = :m, "
"acknowledgement_last_error_date = :d, acknowledged_send_retry_count = :r",
ExpressionAttributeValues={
':s': False,
':m': msg,
':r': retry_count,
':d': datetime.datetime.now().isoformat()
},
ReturnValues="UPDATED_NEW"
)
return response
except ClientError as ce:
logger.error(ce)
if ce.response['Error']['Code'] != 'ConditionalCheckFailedException':
raise ce
except Exception as e:
logger.error(e)
def is_required(self):
try:
if self.profile.integration_config.send_ack_to_url_from_order:
notification_url = self.order['notification_urls']['order_acknowledgement']
if url(notification_url) is not True:
return False
retry_count = self.order['acknowledged_send_retry_count'] if 'acknowledged_send_retry_count' in self.order else 0
if ('acknowledged' not in self.order or self.order['acknowledged'] is False) \
and retry_count < MAX_RETRY_COUNT:
return True
return False
except KeyError:
return False
def notify(self):
if self.is_required():
if self.profile.integration_config.send_ack_to_url_from_order:
try:
StandardAcknowledgementAction(self.order).send()
self.__record_status(was_successful=True)
logging.info(f"Sent order acknowledgement for order: [{self.order['id']}] ")
return self.order
except Exception as e:
ackf = AcknowledgementFailedWarning(e)
self.__record_status(was_successful=False, msg=str(ackf))
logging.warning(f"Failed to send acknowledgement for order: [{self.order['id']}]. "
f"Will retry on next scheduled interval. ", ackf)
logging.warning(ackf)
if self.profile.integration_config.cancel_order_on_reject and self.order['order_status'] == 'REJECTED':
try:
CancelOrderAction(self.order).send()
logging.info(f"Canceled Orders: [{self.order['id']}]")
except Exception as e:
logging.error(f"Failed to cancel Orders: [{self.order['id']}]")
logging.error(e)
else:
if 'acknowledged' not in self.order or self.order['acknowledged'] is False:
retry_count = self.order['acknowledged_send_retry_count'] if 'acknowledged_send_retry_count' in self.order else 0
if retry_count >= MAX_RETRY_COUNT:
afe = AcknowledgementFailedError(f"Maximum retries exhausted trying to send acknowledgement "
f"for order: [{self.order['id']}].")
logging.error(afe)
else:
afe = AcknowledgementFailedError(f"Acknowledgment not required for order that is not acknowledged. "
f"order: [{self.order['id']}]")
logging.error(afe)
# Moved here to avoid silly python circular import problems
from .standard import StandardAcknowledgementAction