def regular_eft_payment_proof_send(): order_storage = OrderStorageImplementation() logger = Logger() file_storage = FileStorageImplementation() sqs_sender = SqsSenderImplementation() try: user_id = __get_user().id request_data = blueprint.current_request.json_body order_number_value = str(request_data.get('order_number', '')).strip() file_id = str(request_data.get('file_id', '')).strip() if not order_number_value: raise HttpIncorrectInputDataException('order_number is required!') elif not file_id: raise HttpIncorrectInputDataException('file_id is required!') order_number = Order.Number(order_number_value) order = order_storage.load(order_number) if not order: raise HttpNotFoundException('Order "{}" does not exist!'.format(order_number)) elif order.customer_id.value != user_id: raise HttpAccessDenyException('Access Denied!') elif not isinstance(order.payment_method, RegularEftOrderPaymentMethod): raise ApplicationLogicException('Order "{}" does not have Regular EFT payment!') file = file_storage.get(file_id) if not file: raise HttpNotFoundException('File does not exist!') def __log_flow(text: str) -> None: logger.log_simple('Regular EFT : Sending POP : {} : {}'.format(order.number.value, text)) __log_flow('Order Updating...') order.status = Order.Status(Order.Status.PAYMENT_SENT) order_storage.save(order) __log_flow('Order Updated!') try: __log_flow('Order SQS Sending...') sqs_sender.send(OrderChangeSqsSenderEvent(order)) __log_flow('Order SQS Sent!') except BaseException as e: logger.log_exception(e) __log_flow('Order SQS NOT Sent because of Error: {}!'.format(str(e))) try: __log_flow('Regular EFT POP SQS Sending...') sqs_sender.send(RegularEftProofUploadedSqsSenderEvent(order, file)) __log_flow('Regular EFT POP SQS Sent!') except BaseException as e: logger.log_exception(e) __log_flow('Regular EFT POP SQS NOT Sent because of Error: {}!'.format(str(e))) return { 'Code': 'Success', 'Message': 'Success', } except BaseException as e: return http_response_exception_or_throw(e)
def __on_hold_not_closed_status(self, order: Order, on_hold_status: str, __log_flow) -> None: __log_flow('Order Updating...') order.status = Order.Status(on_hold_status) __log_flow('Order Updated!') __log_flow('Order Saving...') self.__order_storage.save(order) __log_flow('Order Saved!')
def handle(self, sqs_message: SqsMessage) -> None: def __log_flow(text: str) -> None: self.__logger.log_simple('{} : SQS Message #{} : {}'.format( self.__class__.__qualname__, sqs_message.id, text )) __log_flow('Start - {}'.format(sqs_message.message_data)) data = { 'order_number': sqs_message.message_data.get('order_number', '') or '', 'order_status_mpc': sqs_message.message_data.get('order_status_mpc', '') or '', 'popup_message': { 'customer_email': sqs_message.message_data.get('popup_message').get('customer_email'), 'message_title': sqs_message.message_data.get('popup_message').get('message_title'), 'message_text': sqs_message.message_data.get('popup_message').get('message_text'), } if sqs_message.message_data.get('popup_message', None) or None else None, } __log_flow('Order: Updating...') order_number = Order.Number(data.get('order_number')) order = self.__order_storage.load(order_number) if not order: raise ValueError('Order "{}" does not exist in the MPC!') mpc_order_status = str(data.get('order_status_mpc')) order.status = Order.Status(mpc_order_status) __log_flow('Order: Updated!') __log_flow('Order: Saving...') self.__order_storage.save(order) __log_flow('Order: Saved!') # Attention! # We need to send-back order changes because of compatibility reason. __log_flow('Order: SQS Sending-Back...') self.__sqs_sender.send(OrderChangeSqsSenderEvent(order)) __log_flow('Order: SQS Sent-Back!') # add message, if is needed (silently) try: message_data = data.get('popup_message') or None if message_data: __log_flow('Notification popup: Adding...') message = Message( str(uuid.uuid4()), message_data.get('customer_id'), message_data.get('message_title'), message_data.get('message_text'), ) self.__messages_storage.save(message) __log_flow('Notification popup: Added!') except BaseException as e: self.__logger.log_exception(e) __log_flow('Notification popup: Not Added because of Error : {}'.format(str(e))) __log_flow('End')
def __cancellation_create_submit_before_payment(order: Order, items): orders_storage = OrderStorageImplementation() products_storage = ProductStorageImplementation() sqs_sender = SqsSenderImplementation() logger = Logger() def __log_flow(text: str): logger.log_simple( 'Cancellation for Order #{} Before Payment: {}'.format( order.number.value, text)) __log_flow('Start - {}'.format([{ 'simple_sku': item['simple_sku'].value, 'qty': item['qty'].value, } for item in items])) # updates products_to_update = {} for item in items: products_to_update[ item['simple_sku'].value] = products_storage.load( item['simple_sku']) products_to_update[item['simple_sku'].value].restore_qty( item['qty']) order.cancel_before_payment(item['simple_sku'], item['qty']) order_change_event = OrderChangeSqsSenderEvent(order) # save order __log_flow('Order Saving...') orders_storage.save(order) __log_flow('Order Saved!') # saving products __log_flow('Products Saving... {}'.format( tuple(products_to_update.keys()))) for product in tuple(products_to_update.values()): __log_flow('Product {} Saving...'.format(product.simple_sku.value)) products_storage.update(product) __log_flow('Product {} Saved!'.format(product.simple_sku.value)) __log_flow('Products Saved!') # send order __log_flow('Order SQS Sending...') sqs_sender.send(order_change_event) __log_flow('Order SQS Sent!') __log_flow('End')
def __close_order_on_hold(self, order: Order, __log_flow) -> None: __log_flow('Updating...') # close order __log_flow('Order Updating...') order.status = Order.Status(Order.Status.CLOSED) __log_flow('Order Updated!') # restore products qty __log_flow('Product Qty Updating - Start') products_to_save = [] for order_item in order.items: if order_item.qty_processable.value == 0: __log_flow('Product Qty Updating: {} skipped because of 0 qty'.format(order_item.simple_sku.value)) continue __log_flow('Product Qty Updating {} / {} ...'.format( order_item.simple_sku.value, order_item.qty_processable.value )) product = self.__products_storage.load(order_item.simple_sku) product.restore_qty(order_item.qty_processable) products_to_save.append(product) __log_flow('Product Qty Updated {} / {}!'.format( order_item.simple_sku.value, order_item.qty_processable.value )) __log_flow('Product Qty Updating - End') __log_flow('Updated!') __log_flow('Saving...') __log_flow('Order Saving...') self.__order_storage.save(order) __log_flow('Order Saved!') __log_flow('Products Saving...') for product in products_to_save: __log_flow('Product {} Saving...'.format(product.simple_sku.value)) self.__products_storage.update(product) __log_flow('Product {} Saved!'.format(product.simple_sku.value)) __log_flow('Products Saved!') __log_flow('Saved!')
def handle(self, sqs_message: SqsMessage) -> None: def __log_flow(text: str) -> None: self.__logger.log_simple('{} : SQS Message #{} : {}'.format( self.__class__.__qualname__, sqs_message.id, text )) __log_flow('Start : {}'.format(sqs_message.message_data)) if sqs_message.message_type != 'fixel_order_on_hold_by_portal': raise ValueError('{} does not know how to handle {} sqs message! Message data: {}'.format( self.__class__.__qualname__, sqs_message.message_type, sqs_message.message_data )) order_number_value = sqs_message.message_data.get('order_number') on_hold_status = sqs_message.message_data.get('status') order_number = Order.Number(order_number_value) order = self.__order_storage.load(order_number) if on_hold_status == Order.Status.CLOSED: self.__close_order_on_hold(order, __log_flow) else: self.__on_hold_not_closed_status(order, on_hold_status, __log_flow) self.__send_order_change_to_portal(order, __log_flow) self.__notify_about_order_status_change_silently(order, __log_flow) __log_flow('End')
def handle(self, sqs_message: SqsMessage) -> None: def __log_flow(text: str) -> None: self.__logger.log_simple('{} : {} : {}'.format( self.__class__.__qualname__, sqs_message.id, text )) __log_flow('Start - {}'.format(sqs_message.message_data)) request_number = CancelRequest.Number(sqs_message.message_data['request_number']) order_number = Order.Number(sqs_message.message_data['order_number']) simple_sku = SimpleSku(sqs_message.message_data['simple_sku']) qty = Qty(sqs_message.message_data['qty']) status = sqs_message.message_data['status'] actions_map = { 'approved': self.__approve, 'declined': self.__decline, } action = actions_map.get(status) if not action: raise Exception('{} can\'t handle SQS message {}:{}! Status is unknown!'.format( self.handle.__qualname__, sqs_message.message_type, sqs_message.message_data )) action(request_number, order_number, simple_sku, qty, __log_flow) __log_flow('End')
def handle(self, sqs_message: SqsMessage) -> None: def __log_flow(text: str) -> None: self.__logger.log_simple('{} : {} : {}'.format( self.__class__.__qualname__, sqs_message.id, text )) __log_flow('Start - {}'.format(sqs_message.message_data)) order_number = Order.Number(sqs_message.message_data['order_number']) simple_sku = SimpleSku(sqs_message.message_data['simple_sku']) qty = Qty(sqs_message.message_data['qty']) order = self.__orders_storage.load(order_number) product = self.__products_storage.load(simple_sku) if order.was_paid: order.request_cancellation_after_payment(simple_sku, qty) order.approve_cancellation_after_payment(simple_sku, qty) else: order.cancel_before_payment(simple_sku, qty) product.restore_qty(qty) order_change_event = OrderChangeSqsSenderEvent(order) __log_flow('Order Saving...') self.__orders_storage.save(order) __log_flow('Order Saved!') __log_flow('Product Saving...') self.__products_storage.update(product) __log_flow('Product Saved!') __log_flow('Order SQS Sending...') self.__sqs_sender.send(order_change_event) __log_flow('Order SQS Sent!') try: __log_flow('Notification popup: Adding...') customer = self.__customer_storage.get_by_id(order.customer_id) message = Message( str(uuid.uuid4()), customer.email.value, 'Order #{} has been Updated!'.format(order.number.value), 'Product "{}" for Order #{} has been Cancelled in Qty {}!'.format( product.name.value, order.number.value, qty.value ), ) self.__messages_storage.save(message) __log_flow('Notification popup: Added!') except BaseException as e: self.__logger.log_exception(e) __log_flow('Notification popup: Not Added because of Error : {}'.format(str(e))) __log_flow('End')
def info(order_number): try: __check_header_or_error() order_storage = OrderStorageImplementation() order = order_storage.load(Order.Number(order_number)) if not order: raise HttpNotFoundException('Order does not exist!') return {'order': _order_info(order)} except BaseException as e: return http_response_exception_or_throw(e)
def handle(self, sqs_message: SqsMessage) -> None: def __log_flow(text: str) -> None: self.__logger.log_simple('{} : SQS Message #{} : {}'.format( self.__class__.__qualname__, sqs_message.id, text )) __log_flow('Start - {}'.format(sqs_message.message_data)) order_number = Order.Number(sqs_message.message_data['order_number']) simple_sku = SimpleSku(sqs_message.message_data['simple_sku']) qty = Qty(sqs_message.message_data['qty']) __log_flow('Order Updating...') order = self.__order_storage.load(order_number) order.refund(simple_sku, qty) __log_flow('Order Updated!') __log_flow('Order Saving...') self.__order_storage.save(order) __log_flow('Order Saved!') __log_flow('Order SQS Sending...') self.__sqs_sender.send(OrderChangeSqsSenderEvent(order)) __log_flow('Order SQS Sent!') # add message (silently) try: __log_flow('Notification popup: Adding...') customer = self.__customer_storage.get_by_id(order.customer_id) product = self.__product_storage.load(simple_sku) message = Message( str(uuid.uuid4()), customer.email.value, 'Refund for Order #{}'.format(order.number.value), '"{}" has been Refunded in Qty {} for Order #{}'.format( product.name.value, qty.value, order.number.value ), ) self.__messages_storage.save(message) __log_flow('Notification popup: Added!') except BaseException as e: self.__logger.log_exception(e) __log_flow('Notification popup: Not Added because of Error : {}'.format(str(e))) __log_flow('End')
def cancellation_create_get_initial_data(order_number): user = __get_user() orders_storage = OrderStorageImplementation() products_storage = ProductStorageImplementation() try: order_number = Order.Number(order_number) except BaseException: raise BadRequestError('Incorrect Input Data!') order = orders_storage.load(order_number) if not order: raise NotFoundError('Order #{} does not exist!'.format( order_number.value)) elif order.customer_id.value != user.id: raise ForbiddenError('Order #{} is not your!'.format( order_number.value)) elif not order.is_cancellable: raise UnprocessableEntityError( 'Order #{} is not Cancellable!'.format(order.number.value)) products_map: Dict[str, ProductInterface] = {} for item in order.items: product = products_map.get( item.simple_sku.value) or products_storage.load( item.simple_sku) products_map[item.simple_sku.value] = product return { 'items': [{ 'simple_sku': item.simple_sku.value, 'product_name': products_map[item.simple_sku.value].name.value, 'img_url': (products_map[item.simple_sku.value].image_urls[0] if products_map[item.simple_sku.value].image_urls else None), 'costs': [{ 'qty': qty, 'cost': item.get_refund_cost(Qty(qty)).value } for qty in range(1, item.qty_processable.value + 1)], 'qty_can_cancel': item.qty_processable.value, } for item in order.items], 'refund_methods': __get_refund_methods_initial_data(order), }
def orders_view(order_number): orders_storage = OrderStorageImplementation() try: order_number = str(order_number).strip() if not order_number: raise HttpIncorrectInputDataException('order_number is required!') order_number = Order.Number(order_number) order = orders_storage.load(order_number) if not order: raise HttpNotFoundException('Order does not exist!') user_id = __get_user_id() customer_id = Id(user_id) if order.customer_id != customer_id: raise HttpAccessDenyException() return __orders_response([order])[0] except BaseException as e: return http_response_exception_or_throw(e)
def cancellation_get_by_order(order_number): user = __get_user() orders_storage = OrderStorageImplementation() cancel_requests_storage = CancelRequestStorageImplementation() try: order_number = Order.Number(order_number) except BaseException: raise BadRequestError('Incorrect Input Data!') order = orders_storage.load(order_number) if not order: raise NotFoundError('Order #{} does not exist!'.format( order_number.value)) elif order.customer_id.value != user.id: raise ForbiddenError('Order #{} is not your!'.format( order_number.value)) requests = cancel_requests_storage.get_all_by_order_number( order.number) return __get_cancellation_requests_response(requests)
def __restore(self, data: dict) -> Order: order_number = Order.Number(data.get('sk')) customer_id = Id(data.get('customer_id')) delivery_cost = Cost(float(data.get('delivery_cost'))) vat_percent = Percentage(float(data.get('vat_percent'))) credits_spent = Cost(float(data.get('credits_spent') or '0')) payment_method = self.__restore_payment_method( data.get('payment_method'), json.loads(data.get('payment_method_extra_data_json') or '{}') if data.get('payment_method') else None) delivery_address = DeliveryAddress( data.get('delivery_address_recipient_name'), data.get('delivery_address_phone_number'), data.get('delivery_address_street_address'), data.get('delivery_address_suburb'), data.get('delivery_address_city'), data.get('delivery_address_province'), data.get('delivery_address_complex_building'), data.get('delivery_address_postal_code'), data.get('delivery_address_business_name'), data.get('delivery_address_special_instructions')) status_changes = [] for status_change_data in data.get('status_history'): status = Order.Status(status_change_data.get('status')) changed_at = datetime.datetime.strptime( status_change_data.get('datetime'), '%Y-%m-%dT%H:%M:%S.%f') status_change = self.__reflector.construct( Order.StatusChangesHistory.Change, { '__status': status, '__datetime': changed_at }) status_changes.append(status_change) status_change_history = Order.StatusChangesHistory( tuple(status_changes)) order_items = [] for item_data in data.get('order_items'): event_code = EventCode(item_data.get('event_code')) simple_sku = SimpleSku(item_data.get('simple_sku')) product_original_price = Cost( item_data.get('product_original_price')) product_current_price = Cost( item_data.get('product_current_price')) fbucks_earnings = Cost(item_data.get('fbucks_earnings')) dtd = Dtd( Dtd.Occasion( Name(item_data.get('dtd_occasion_name')), Description(item_data.get('dtd_occasion_description'))) if item_data.get('dtd_occasion_name') else None, datetime.date( int(item_data.get('dtd_date_from').split('-')[0]), int(item_data.get('dtd_date_from').split('-')[1]), int(item_data.get('dtd_date_from').split('-')[2])), datetime.date(int(item_data.get('dtd_date_to').split('-')[0]), int(item_data.get('dtd_date_to').split('-')[1]), int(item_data.get('dtd_date_to').split('-')[2])), int(item_data.get('dtd_working_days_from')), int(item_data.get('dtd_working_days_to'))) qty_ordered = Qty(int(item_data.get('qty_ordered'))) qty_return_requested = Qty( int(item_data.get('qty_return_requested') or 0)) qty_return_returned = Qty( int(item_data.get('qty_return_returned') or 0)) qty_cancelled_before_payment = Qty( int(item_data.get('qty_cancelled_before_payment') or 0)) qty_cancelled_after_payment_requested = Qty( int( item_data.get('qty_cancelled_after_payment_requested') or 0)) qty_cancelled_after_payment_cancelled = Qty( int( item_data.get('qty_cancelled_after_payment_cancelled') or 0)) qty_refunded = Qty(int(item_data.get('qty_refunded') or 0)) qty_modified_at = datetime.datetime.strptime( item_data.get('qty_modified_at'), '%Y-%m-%dT%H:%M:%S.%f') order_item = self.__reflector.construct( Order.Item, { '__event_code': event_code, '__simple_sku': simple_sku, '__product_original_price': product_original_price, '__product_current_price': product_current_price, '__dtd': dtd, '__qty_ordered': qty_ordered, '__qty_return_requested': qty_return_requested, '__qty_return_returned': qty_return_returned, '__qty_cancelled_before_payment': qty_cancelled_before_payment, '__qty_cancelled_after_payment_requested': qty_cancelled_after_payment_requested, '__qty_cancelled_after_payment_cancelled': qty_cancelled_after_payment_cancelled, '__qty_refunded': qty_refunded, '__qty_modified_at': qty_modified_at, '__fbucks_earnings': fbucks_earnings }) order_items.append(order_item) order = self.__reflector.construct( Order, { '__order_number': order_number, '__customer_id': customer_id, '__items': order_items, '__delivery_address': delivery_address, '__delivery_cost': delivery_cost, '__vat_percent': vat_percent, '__payment_method': payment_method, '__status_history': status_change_history, '__credits_spent': credits_spent, }) return order
def __restore(self, data: dict) -> Order: order_number = Order.Number(data.get('order_number')) customer_id = Id(data.get('customer_id')) delivery_cost = Cost(float(data.get('delivery_cost'))) vat_percent = Percentage( float( # I added "vat_percent" after first orders were stored, # but it's hard to make changes in elastic, so... # @todo : create migration tool. data.get('vat_percent') or self.__current_vat_value)) credits_spent = Cost(float(data.get('credits_spent') or '0')) # can be not existed in old data payment_method = self.__restore_payment_method( data.get('payment_method'), json.loads(data.get('payment_method_extra_data_json') or '{}') if data.get('payment_method') else None) delivery_address = DeliveryAddress( data.get('delivery_address_recipient_name'), data.get('delivery_address_phone_number'), data.get('delivery_address_street_address'), data.get('delivery_address_suburb'), data.get('delivery_address_city'), data.get('delivery_address_province'), data.get('delivery_address_complex_building'), data.get('delivery_address_postal_code'), data.get('delivery_address_business_name'), data.get('delivery_address_special_instructions')) status_changes = [] for status_change_data in data.get('status_history'): status = Order.Status(status_change_data.get('status')) # elastic supports only 3 digits for milliseconds changed_at = datetime.datetime.strptime( status_change_data.get('datetime') + '000', '%Y-%m-%dT%H:%M:%S.%f') status_change = self.__reflector.construct( Order.StatusChangesHistory.Change, { '__status': status, '__datetime': changed_at }) status_changes.append(status_change) status_change_history = Order.StatusChangesHistory( tuple(status_changes)) order_items = [] for item_data in data.get('order_items'): event_code = EventCode(item_data.get('event_code')) simple_sku = SimpleSku(item_data.get('simple_sku')) product_original_price = Cost( item_data.get('product_original_price')) product_current_price = Cost( item_data.get('product_current_price')) fbucks_earnings = Cost(item_data.get('fbucks_amount') or 0) # old orders don't have this field dtd = Dtd( Dtd.Occasion( Name(item_data.get('dtd_occasion_name')), Description(item_data.get('dtd_occasion_description'))) if item_data.get('dtd_occasion_name') else None, datetime.date( int(item_data.get('dtd_date_from').split('-')[0]), int(item_data.get('dtd_date_from').split('-')[1]), int(item_data.get('dtd_date_from').split('-')[2])), datetime.date(int(item_data.get('dtd_date_to').split('-')[0]), int(item_data.get('dtd_date_to').split('-')[1]), int(item_data.get('dtd_date_to').split('-')[2])), int(item_data.get('dtd_working_days_from')), int(item_data.get('dtd_working_days_to'))) qty_ordered = Qty(int(item_data.get('qty_ordered'))) qty_return_requested = Qty( int(item_data.get('qty_return_requested') or 0)) qty_return_returned = Qty( int(item_data.get('qty_return_returned') or 0)) qty_cancelled_before_payment = Qty( int(item_data.get('qty_cancelled_before_payment') or 0)) qty_cancelled_after_payment_requested = Qty( int( item_data.get('qty_cancelled_after_payment_requested') or 0)) qty_cancelled_after_payment_cancelled = Qty( int( item_data.get('qty_cancelled_after_payment_cancelled') or 0)) qty_refunded = Qty(int(item_data.get('qty_refunded') or 0)) # elastic supports only 3 digits for milliseconds qty_modified_at = datetime.datetime.strptime( ( # "qty_modified_at" may not exist for old data (dev, test), # but it's hard to make changes in elastic, so... # @todo : create migration tool. item_data.get('qty_modified_at') or status_change_history.get_last().datetime.strftime( '%Y-%m-%dT%H:%M:%S.%f')[:-3]) + '000', '%Y-%m-%dT%H:%M:%S.%f') order_item = self.__reflector.construct( Order.Item, { '__event_code': event_code, '__simple_sku': simple_sku, '__product_original_price': product_original_price, '__product_current_price': product_current_price, '__dtd': dtd, '__qty_ordered': qty_ordered, '__qty_return_requested': qty_return_requested, '__qty_return_returned': qty_return_returned, '__qty_cancelled_before_payment': qty_cancelled_before_payment, '__qty_cancelled_after_payment_requested': qty_cancelled_after_payment_requested, '__qty_cancelled_after_payment_cancelled': qty_cancelled_after_payment_cancelled, '__qty_refunded': qty_refunded, '__qty_modified_at': qty_modified_at, '__fbucks_earnings': fbucks_earnings }) order_items.append(order_item) order = self.__reflector.construct( Order, { '__order_number': order_number, '__customer_id': customer_id, '__items': order_items, '__delivery_address': delivery_address, '__delivery_cost': delivery_cost, '__vat_percent': vat_percent, '__payment_method': payment_method, '__status_history': status_change_history, '__credits_spent': credits_spent, }) return order
def customer_credits_checkout(): checkout_storage = CheckoutStorageImplementation() order_storage = OrderStorageImplementation() order_app_service = OrderAppService() cart_service = CartAppService() checkout_service = CheckoutAppService() sqs_sender = SqsSenderImplementation() logger = Logger() try: user = __get_user() # @todo : refactoring checkout = checkout_storage.load(Id(user.id)) if not checkout: raise ApplicationLogicException('Checkout does not exist!') elif checkout.total_due.value != 0: raise ApplicationLogicException('Unable to checkout not 0 amount with Customer Credits!') order = order_app_service.get_waiting_for_payment_by_checkout_or_checkout_new(user.id) def __log_flow(text: str) -> None: logger.log_simple('Customer Credits Payment Log for Order #{} : {}'.format( order.number.value, text )) __log_flow('Start') try: __log_flow('Credits Spending...') # Attention! # Currently we use f-bucks only! Other credits are not available for now! # @todo : other credit types # @todo : copy-paste code # @todo : when reservation of credits amount will be done, perhaps, use sqs to spend credits """""" from chalicelib.libs.purchase.core import Checkout see = Checkout.__init__ """""" # @TODO : refactoring : raw data usage import uuid import datetime from chalicelib.settings import settings from chalicelib.libs.core.elastic import Elastic fbucks_customer_amount_elastic = Elastic( settings.AWS_ELASTICSEARCH_FBUCKS_CUSTOMER_AMOUNT, settings.AWS_ELASTICSEARCH_FBUCKS_CUSTOMER_AMOUNT, ) fbucks_customer_amount_changes_elastic = Elastic( settings.AWS_ELASTICSEARCH_FBUCKS_CUSTOMER_AMOUNT_CHANGES, settings.AWS_ELASTICSEARCH_FBUCKS_CUSTOMER_AMOUNT_CHANGES, ) fbucks_customer_amount_elastic.update_data(order.customer_id.value, { 'script': 'ctx._source.amount -= ' + str(order.credit_spent_amount.value) }) fbucks_customer_amount_changes_elastic.create(str(uuid.uuid4()) + str(order.customer_id.value), { "customer_id": order.customer_id.value, "amount": -order.credit_spent_amount.value, "changed_at": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "order_number": order.number.value, }) __log_flow('Credits Spent!') __log_flow('Order Updating...') order.payment_method = CustomerCreditsOrderPaymentMethod() order.status = Order.Status(Order.Status.PAYMENT_SENT) order.status = Order.Status(Order.Status.PAYMENT_RECEIVED) order_storage.save(order) __log_flow('Order Updated!') except BaseException as e: __log_flow('Not done because of Error : {}'.format(str(e))) raise e # send order update to sqs try: __log_flow('Order Change SQS Sending...') sqs_sender.send(OrderChangeSqsSenderEvent(order)) __log_flow('Order Change SQS Sent!') except BaseException as e: __log_flow('Order Change SQS NOT Sent because of Error: {}!'.format(str(e))) logger.log_exception(e) # flush cart try: __log_flow('Cart Flushing...') cart_service.clear_cart(user.session_id) __log_flow('Cart Flushed!') except BaseException as e: __log_flow('Cart NOT Flushed because of Error: {}'.format(str(e))) logger.log_exception(e) # flush checkout try: __log_flow('Checkout Flushing...') checkout_service.remove(user.id) __log_flow('Checkout Flushed!') except BaseException as e: __log_flow('Checkout NOT Flushed because of Error: {}'.format(str(e))) logger.log_exception(e) result = { 'order_number': order.number.value } __log_flow('End') return result except BaseException as e: logger.log_exception(e) return http_response_exception_or_throw(e)
def handle(self, sqs_message: SqsMessage) -> None: def __log_flow(text: str) -> None: self.__logger.log_simple('{} : SQS Message #{} : {}'.format( self.__class__.__qualname__, sqs_message.id, text)) __log_flow('Start') if sqs_message.message_type != 'regular_eft_proof_check_result': raise ValueError( '{} does not know how to handle {} sqs message! Message data: {}' .format(self.__class__.__qualname__, sqs_message.message_type, sqs_message.message_data)) order_number_value = sqs_message.message_data.get('order_number') is_proof_accepted = sqs_message.message_data.get('is_proof_accepted') __log_flow('Order #{} - Payment - {}'.format( order_number_value, 'Accepted' if is_proof_accepted else 'Declined')) __log_flow('Updating...') order_number = Order.Number(order_number_value) order = self.__order_storage.load(order_number) if not order: raise ValueError( 'Unable to handle {} sqs-message #{}: order does not exist. Message data: {}' .format(sqs_message.message_type, sqs_message.id, sqs_message.message_data)) if not isinstance(order.payment_method, RegularEftOrderPaymentMethod): raise ValueError( 'Order #{} is not a Regular EFT payment order!'.format( order.number.value)) if is_proof_accepted: # accept order payment __log_flow('Order Updating...') order.status = Order.Status(Order.Status.PAYMENT_RECEIVED) self.__order_storage.save(order) __log_flow('Order Updated!') else: # Attention! # Order must be closed first to avoid multiple "restore-qty" actions! # @todo : refactoring ? # close order __log_flow('Order Closing...') order.status = Order.Status(Order.Status.CLOSED) self.__order_storage.save(order) __log_flow('Order Closed!') # restore products qty __log_flow('Product Qty Restoring - Start') for order_item in order.items: if order_item.qty_processable.value == 0: __log_flow( 'Product Qty Restoring: {} skipped because of 0 qty'. format(order_item.simple_sku.value)) continue try: __log_flow('Product Qty Restoring {} / {} ...'.format( order_item.simple_sku.value, order_item.qty_processable.value)) product = self.__products_storage.load( order_item.simple_sku) product.restore_qty(order_item.qty_processable) self.__products_storage.update(product) __log_flow('Product Qty Restored {} / {}!'.format( order_item.simple_sku.value, order_item.qty_processable.value)) except BaseException as e: self.__logger.log_exception(e) __log_flow( 'Product Qty NOT Restored {} / {} because of Error: '. format(order_item.simple_sku.value, order_item.qty_processable.value, str(e))) __log_flow('Product Qty Restoring - End') __log_flow('Updated!') # send to portal __log_flow('Order SQS: Sending...') self.__sqs_sender.send(OrderChangeSqsSenderEvent(order)) __log_flow('Order SQS: Sent!') # silently add notification (silently) try: __log_flow('Notification popup: Adding...') customer = self.__customer_storage.get_by_id(order.customer_id) if not customer: raise ValueError( '{} cant notify customer #{} about Regular-EFT payment updates for Order #{}' .format(self.handle.__qualname__, order.customer_id.value, order.number.value)) self.__message_storage.save( Message( str(uuid.uuid4()), customer.email.value, 'Regular EFT Payment has been checked!', 'Regular EFT Payment for Order #{} has been checked and {}!' .format(order.number.value, 'Accepted' if is_proof_accepted else 'Declined'))) __log_flow('Notification popup: Added!') except BaseException as e: self.__logger.log_exception(e) __log_flow( 'Notification popup: Not Added because of Error : {}'.format( str(e))) __log_flow('End')
def handle(self, sqs_message: SqsMessage) -> None: import uuid import datetime from chalicelib.libs.purchase.core import Order order_number_values = sqs_message.message_data['order_numbers'] for order_number_value in order_number_values: try: now_string = datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S") # skip duplicates # if self.__fbucks_handled_orders_elastic.get_data(order_number_value): if self.__fbucks_handled_orders_dynamo_db.find_item( order_number_value): self.__logger.log_simple( '{}: Fbucks for order #{} already earned!'.format( self.handle.__qualname__, order_number_value)) continue # ignore orders without fbucks amounts order = self.__orders_storage.load( Order.Number(order_number_value)) fbucks_amount = order.total_fbucks_earnings.value if fbucks_amount == 0: # remember order as handled # self.__fbucks_handled_orders_elastic.create(order_number_value, {'handled_at': now_string}) self.__fbucks_handled_orders_dynamo_db.put_item( order_number_value, {'handled_at': now_string}) continue # earn fbucks self.__fbucks_customer_amount_elastic.update_data( order.customer_id.value, { 'script': 'ctx._source.amount += ' + str(fbucks_amount), 'upsert': { 'amount': fbucks_amount, } }) self.__fbucks_customer_amount_changes_elastic.create( str(uuid.uuid4()) + str(order.customer_id.value), { "customer_id": order.customer_id.value, "amount": +fbucks_amount, "changed_at": now_string, "order_number": order_number_value, }) # remember order as handled # self.__fbucks_handled_orders_elastic.create(order_number_value, {'handled_at': now_string}) self.__fbucks_handled_orders_dynamo_db.put_item( order_number_value, {'handled_at': now_string}) # notify (silently) try: customer = self.__customer_storage.get_by_id( order.customer_id) self.__messages_storage.save( Message( str(uuid.uuid4()), customer.email.value, 'F-Bucks has been Earned!', 'You have earned {} F-Bucks by your Order #{}'. format(fbucks_amount, order.number.value))) except BaseException as e: self.__logger.log_exception(e) except BaseException as e: self.__logger.log_exception(e)
def cancellation_create_submit(): user = __get_user() orders_storage = OrderStorageImplementation() try: order_number = Order.Number( blueprint.current_request.json_body.get('order_number')) items = [{ 'simple_sku': SimpleSku(item.get('simple_sku')), 'qty': Qty(item.get('qty')) } for item in blueprint.current_request.json_body.get('items') or []] additional_comment = str( blueprint.current_request.json_body.get('additional_comment') or '') or None refund_method_input_data = blueprint.current_request.json_body.get( 'refund_method') or {} refund_method_input_data['type'] = str( refund_method_input_data.get('type') or '') refund_method_input_data['params'] = refund_method_input_data.get( 'params') or {} except ValueError: raise BadRequestError('Incorrect Input Data!') order = orders_storage.load(order_number) if not order: raise NotFoundError('Order #{} does not exist!'.format( order_number.value)) elif order.customer_id.value != user.id: raise ForbiddenError('Order #{} is not your!'.format( order_number.value)) elif not order.is_cancellable: raise UnprocessableEntityError( 'Order #{} is not Cancellable!'.format(order.number.value)) # @todo : refactoring ??? try: if order.was_paid: refund_method_instance = None for _refund_method_instance in [ StoreCreditRefundMethod(), EftRefundMethod('test', 'test', 'test'), MobicredRefundMethod(), CreditCardRefundMethod() ]: if _refund_method_instance.descriptor == refund_method_input_data[ 'type']: refund_method_instance = _refund_method_instance.__class__( **refund_method_input_data['params']) break if not refund_method_instance: error_message = 'Incorrect Input Data! Refund method {} is not allowed for selected orders!' raise BadRequestError( error_message.format(refund_method_input_data['type'])) cancellation_request = __cancellation_create_submit_after_payment( order, items, refund_method_instance, additional_comment) return {'request_number': cancellation_request.number.value} else: __cancellation_create_submit_before_payment(order, items) return { 'Code': 'Success', 'Message': 'Success', } except ApplicationLogicException as e: raise UnprocessableEntityError(str(e))
def __cancellation_create_submit_after_payment( order: Order, items, refund_method: RefundMethodAbstract, additional_comment: Optional[str]) -> CancelRequest: orders_storage = OrderStorageImplementation() cancellation_storage = CancelRequestStorageImplementation() sqs_sender = SqsSenderImplementation() logger = Logger() def __log_flow(text: str): logger.log_simple( 'Cancellation for Order #{} After Payment: {}'.format( order.number.value, text)) __log_flow('Start - {}'.format({ 'items': [{ 'simple_sku': item['simple_sku'].value, 'qty': item['qty'].value, } for item in items], 'additional_comment': additional_comment })) # updates cancellation_request = CancelRequest( CancelRequest.Number(datetime.datetime.now().strftime('%y%j03%f')), order.number, tuple([ CancelRequest.Item(item['simple_sku'], item['qty']) for item in items ]), refund_method, CancelRequest.AdditionalComment(additional_comment) if additional_comment else None) for item in items: order.request_cancellation_after_payment(item['simple_sku'], item['qty']) order_change_event = OrderChangeSqsSenderEvent(order) cancel_request_event = CancelRequestPaidOrderSqsSenderEvent( cancellation_request) # save request __log_flow('Cancel Request Saving...') cancellation_storage.save(cancellation_request) __log_flow('Cancel Request Saved!') # save order __log_flow('Order Saving...') orders_storage.save(order) __log_flow('Order Saved!') # send request __log_flow('Cancel Request SQS Sending...') sqs_sender.send(cancel_request_event) __log_flow('Cancel Request SQS Sent!') # send order __log_flow('Order SQS Sending...') sqs_sender.send(order_change_event) __log_flow('Order SQS Sent!') __log_flow('End') return cancellation_request