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 returns_send_item(): returns_storage = ReturnRequestStorageImplementation() sqs_sender = SqsSenderImplementation() logger = Logger() request_data = blueprint.current_request.json_body request_number = str(request_data.get('request_number') or '').strip() or None if not request_number: raise BadRequestError('"request_number" is required') return_request = returns_storage.load( ReturnRequest.Number(request_number)) if not return_request: raise NotFoundError( 'Return Request #{} does not exist!'.format(request_number)) if return_request.customer_id.value != __get_user().id: raise ForbiddenError('It is not your Return Request!') try: return_request.make_package_sent() except ApplicationLogicException as e: raise UnprocessableEntityError(str(e)) def __log_flow(text: str) -> None: logger.log_simple('Return Request #{} - Sending : {}'.format( return_request.number.value, text)) __log_flow('Start') # change status __log_flow('Saving - Start') try: __log_flow('Return Request Saving...') returns_storage.save(return_request) __log_flow('Return Request Saving - Done!') except BaseException as e: __log_flow( 'Return Request Saving - Not done because of Error: {}!'. format(str(e))) raise e __log_flow('Saving - End') # send sqs __log_flow('SQS Sending - Start') try: __log_flow('Return Request SQS Sending...') sqs_sender.send(ReturnRequestChangeSqsSenderEvent(return_request)) __log_flow('Return Request SQS Sending - Done!') except BaseException as e: logger.log_exception(e) __log_flow( 'Return Request SQS Sending - Not done because of Error: {}!'. format(str(e))) __log_flow('SQS Sending - End') __log_flow('End')
class OrderRefundSqsHandler(SqsHandlerInterface): def __init__(self) -> None: self.__messages_storage = MessageStorageImplementation() self.__order_storage = OrderStorageImplementation() self.__customer_storage = CustomerStorageImplementation() self.__product_storage = ProductStorageImplementation() self.__sqs_sender = SqsSenderImplementation() self.__logger = Logger() 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 getaddress(address_hash): logger = Logger() user = __get_current_user() try: ret = user.profile.get_address(address_hash) return {'status': True, 'data': ret} except Exception as e: logger.log_exception(e) return {'status': False, 'msg': str(e)}
def getInformation(): logger = Logger() try: email = str(__get_request().json_body.get('email') or '').strip() if not email: raise ValueError('email is empty') ret = InformationService().get(email).get_item() return {'status': True, 'data': ret} except Exception as e: logger.log_exception(e) return {'status': False, 'msg': str(e)}
def credit_cards_list(): cards_storage = CreditCardsStorageImplementation() logger = Logger() try: user = __get_user() cards = cards_storage.get_all_by_customer(user.id) return [__get_card_response(card) for card in cards] except BaseException as e: logger.log_exception(e) return http_response_exception_or_throw(e)
def deleteaddress(address_hash): logger = Logger() user = __get_current_user() try: user.profile.delete_address(address_hash) event = InformationsSqsSenderEvent(user.profile.informations) SqsSenderImplementation().send(event) ret = user.profile.informations['addresses'] return {'status': True, 'data': ret} except Exception as e: logger.log_exception(e) return {'status': False, 'msg': str(e)}
def add_information(): logger = Logger() user = __get_current_user() request = __get_request() params = request.json_body try: user.profile.add_information(params) event = InformationsSqsSenderEvent(user.profile.informations) SqsSenderImplementation().send(event) return {'status': True} except Exception as e: logger.log_exception(e) return {'status': False, 'msg': str(e)}
def addresses(): logger = Logger() user = __get_current_user() request = __get_request() if request.method == 'GET': return user.profile.informations['addresses'] elif request.method == 'POST': params = request.json_body try: ret = user.profile.add_addresses(params) event = InformationsSqsSenderEvent(user.profile.informations) SqsSenderImplementation().send(event) return {'status': True, 'data': ret["Attributes"]["addresses"]} except Exception as e: logger.log_exception(e) return {'status': False, 'msg': str(e)}
def informations(): logger = Logger() user = __get_current_user() request = __get_request() if request.method == 'GET': user_info = user.profile.informations if user_info['email'] == None or user_info[ 'email'] == '' or user_info['email'] == 'BLANK': user_info['email'] = user.email if user_info['first_name'] == None or user_info[ 'first_name'] == '' and user.first_name is not None: user_info['first_name'] = user.first_name if user_info['last_name'] == None or user_info[ 'last_name'] == '' and user.last_name is not None: user_info['last_name'] = user.last_name user.profile.informations = user_info return user_info elif request.method == 'POST': params = request.json_body try: form = AccountInformationForm() form.load(params) validation_errors = form.validate() if validation_errors: return { 'status': False, 'msg': tuple(validation_errors.values())[0][0] } user.profile.informations = params event = InformationsSqsSenderEvent(user.profile.informations) SqsSenderImplementation().send(event) return { 'status': True, 'msg': 'Information has been updated successfully' } except Exception as e: logger.log_exception(e) return {'status': False, 'msg': str(e)}
def possible_favorite_sizes(): user = __get_current_user() logger = Logger() if user.is_anyonimous: return __response_error('Authentication is required!') try: response = {} for category in user.profile.categories: gender_key = category.gender_name type_key = category.product_type_name response[gender_key] = response.get(gender_key) or {} response[gender_key][type_key] = response[gender_key].get( type_key) or [] response[gender_key][type_key].extend( [size.name for size in category.sizes]) response[gender_key][type_key] = list( set(response[gender_key][type_key])) return __response_success(response) except BaseException as e: logger.log_exception(e) return __response_error('Internal Server Error')
class OrderChangeSqsHandler(SqsHandlerInterface): def __init__(self): self.__messages_storage = MessageStorageImplementation() self.__order_storage = OrderStorageImplementation() self.__sqs_sender = SqsSenderImplementation() self.__logger = Logger() 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 regular_eft_checkout(): checkout_storage = CheckoutStorageImplementation() order_storage = OrderStorageImplementation() order_app_service = OrderAppService() logger = Logger() mailer = MailerImplementation() # 1. Get or create order. Critical! # ------------------------------------------------------ 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 0 amount with Regular Eft!') order = order_app_service.get_waiting_for_payment_by_checkout_or_checkout_new(user.id) def __log_order_flow(text: str) -> None: logger.log_simple('Regular EFT : Checkout : {} : {}'.format(order.number.value, text)) __log_order_flow('Start') # 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 if order.credit_spent_amount.value > 0: __log_order_flow('Spending 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_order_flow('Spending Credits: Done!') __log_order_flow('Order Updating...') order.payment_method = RegularEftOrderPaymentMethod() order_storage.save(order) __log_order_flow('Order Updated!') except BaseException as e: logger.log_exception(e) return http_response_exception_or_throw(e) # 2. Send eft email. Not critical. # Theoretically can be redone or downloaded manually. # ------------------------------------------------------ try: __log_order_flow('EFT Email Sending...') message = RegularEftBankDetailsMailMessage(order) mailer.send(message) __log_order_flow('EFT Email Sent!') except BaseException as e: logger.log_exception(e) __log_order_flow('EFT Email Not Sent because of Error: {}'.format(str(e))) # 3. Flush cart, checkout. Not critical. # ------------------------------------------------------ # flush cart try: __log_order_flow('Cart Flushing...') from chalicelib.libs.purchase.cart.service import CartAppService cart_service = CartAppService() cart_service.clear_cart(user.session_id) __log_order_flow('Cart Flushed!') except BaseException as e: logger.log_exception(e) __log_order_flow('Cart Not Flushed because of Error: {}'.format(str(e))) # flush checkout try: __log_order_flow('Checkout Flushing...') from chalicelib.libs.purchase.checkout.service import CheckoutAppService checkout_service = CheckoutAppService() checkout_service.remove(user.id) __log_order_flow('Checkout Flushed!') except BaseException as e: logger.log_exception(e) __log_order_flow('Checkout Not Flushed because of Error: {}'.format(str(e))) return { 'order_number': order.number.value }
class CancelRequestPaidOrderAnswerSqsHandler(SqsHandlerInterface): def __init__(self): self.__orders_storage = OrderStorageImplementation() self.__products_storage = ProductStorageImplementation() self.__cancel_request_storage = CancelRequestStorageImplementation() self.__customer_storage = CustomerStorageImplementation() self.__messages_storage = MessageStorageImplementation() self.__sqs_sender = SqsSenderImplementation() self.__logger = Logger() 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 __approve( self, request_number: CancelRequest.Number, order_number: Order.Number, simple_sku: SimpleSku, qty: Qty, __log_flow ) -> None: __log_flow('Approving...') cancel_request = self.__cancel_request_storage.get_by_number(request_number) order = self.__orders_storage.load(order_number) product = self.__products_storage.load(simple_sku) cancel_request.approve_item(simple_sku) order.approve_cancellation_after_payment(simple_sku, qty) product.restore_qty(qty) order_change_event = OrderChangeSqsSenderEvent(order) __log_flow('Cancel Request Saving...') self.__cancel_request_storage.save(cancel_request) __log_flow('Cancel Request Saved!') __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...') self.__add_notification_message(cancel_request, order, product, 'Approved') __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('Approved!') def __decline( self, request_number: CancelRequest.Number, order_number: Order.Number, simple_sku: SimpleSku, qty: Qty, __log_flow ) -> None: __log_flow('Declining...') cancel_request = self.__cancel_request_storage.get_by_number(request_number) order = self.__orders_storage.load(order_number) product = self.__products_storage.load(simple_sku) cancel_request.decline_item(simple_sku) order.decline_cancellation_after_payment(simple_sku, qty) order_change_event = OrderChangeSqsSenderEvent(order) __log_flow('Cancel Request Saving...') self.__cancel_request_storage.save(cancel_request) __log_flow('Cancel Request Saved!') __log_flow('Order Saving...') self.__orders_storage.save(order) __log_flow('Order Saved!') __log_flow('Order SQS Sending...') self.__sqs_sender.send(order_change_event) __log_flow('Order SQS Sent!') try: __log_flow('Notification popup: Adding...') self.__add_notification_message(cancel_request, order, product, '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('Declined!') def __add_notification_message( self, cancel_request: CancelRequest, order: Order, product: ProductInterface, status_label: str ) -> None: customer = self.__customer_storage.get_by_id(order.customer_id) message = Message( str(uuid.uuid4()), customer.email.value, 'Cancellation Request #{} has been Updated!'.format(cancel_request.number.value), 'Cancellation Request for Product "{}" for Order #{} has been {}!'.format( product.name.value, order.number.value, status_label ), ) self.__messages_storage.save(message)
def credit_cards_add(): cards_storage = CreditCardsStorageImplementation() logger = Logger() try: user = __get_user() input_data = blueprint.current_request.json_body or {} if not input_data: raise BadRequestError('Incorrect Input Data!') redirect_back_path = input_data.get('redirect_back_path') if not redirect_back_path or not isinstance( redirect_back_path, str): raise BadRequestError('Incorrect Input Data!') redirect_back_path = '/' + redirect_back_path if redirect_back_path[ 0] != '/' else redirect_back_path form = CreditCardForm() form.load(input_data.get('form') or {}) form_errors = form.validate() if form_errors: return { 'status': False, 'form_errors': form_errors, } def __log_flow(text: str) -> None: logger.log_simple( 'Creating Credit Card for customer #{}: {}'.format( __get_user().id, text)) __log_flow('Start') try: __log_flow('Initial Payment...') response = requests.post( url=settings.PEACH_PAYMENT_BASE_URL + 'payments', data=(lambda data: data.update( {'card.holder': form.holder_name} if form.holder_name else {}) or data)({ 'entityId': settings.PEACH_PAYMENT_ENTITY_ID, 'card.number': form.number, 'card.expiryMonth': form.expiry_month, 'card.expiryYear': str(2000 + int(form.expiry_year_2d)), 'card.cvv': form.cvv, 'amount': '%.2f' % 1, 'currency': 'ZAR', 'paymentType': 'PA', 'recurringType': 'INITIAL', 'createRegistration': True, 'shopperResultUrl': requests.utils.requote_uri( settings.FRONTEND_BASE_URL + redirect_back_path) }), headers={ 'Authorization': 'Bearer {}'.format(settings.PEACH_PAYMENT_ACCESS_TOKEN) }) if response.status_code != 200: raise Exception( 'Peach Payment Request has been Failed: {} - {} - {}'. format(response.status_code, response.reason, response.text)) response_data = response.json() if response_data['result']['code'] not in ( '000.200.000', # transaction pending '000.000.000', # Transaction successfully processed in LIVE system '000.100.110', # Transaction successfully processed in TEST system ): raise Exception( 'Peach Payment is not available now: {}'.format( response_data['result'])) __log_flow('Initial Payment Done!') __log_flow('New Card Creation...') card = CreditCard( response_data['registrationId'], user.id, form.brand, ('*' * len(form.number[0:-4])) + form.number[-4:], datetime.date(year=2000 + int(form.expiry_year_2d), month=int(form.expiry_month), day=31) if int(form.expiry_month) == 12 else (datetime.date(year=2000 + int(form.expiry_year_2d), month=int(form.expiry_month) + 1, day=1) - datetime.timedelta(days=1)), form.holder_name) __log_flow('New Card Created {}. Saving...'.format(card.token)) cards_storage.save(card) __log_flow('New Card Saved!') __log_flow('Initial Payment Done!') result = { 'url': response_data['redirect']['url'], 'method': 'POST', 'parameters': response_data['redirect']['parameters'], } __log_flow('End') return result except BaseException as e: __log_flow('Fail because of Error {}'.format(str(e))) raise e except BaseException as e: logger.log_exception(e) return http_response_exception_or_throw(e)
class ReturnRequestChangeSqsHandler(SqsHandlerInterface): def __init__(self): self.__returns_storage = ReturnRequestStorageImplementation() self.__order_storage = OrderStorageImplementation() self.__customer_storage = CustomerStorageImplementation() self.__product_storage = ProductStorageImplementation() self.__messages_storage = MessageStorageImplementation() self.__sqs_sender = SqsSenderImplementation() self.__logger = Logger() 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 = sqs_message.message_data.get('return_request_number') order_number = sqs_message.message_data.get('order_number') simple_sku = sqs_message.message_data.get('simple_sku') status = sqs_message.message_data.get('status') __log_flow('Updating...') return_request = self.__returns_storage.load(ReturnRequest.Number(request_number)) if not return_request: raise ValueError('{} can\'t handle SQS message {}:{}! Return Request does not exist!'.format( self.handle.__qualname__, sqs_message.message_type, sqs_message.message_data )) actions_map = { 'approved': self.__approve, 'cancelled': self.__decline, 'closed': self.__close, } 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(return_request, OrderNumber(order_number), SimpleSku(simple_sku), __log_flow) __log_flow('Updated!') __log_flow('End') def __approve( self, return_request: ReturnRequest, order_number: OrderNumber, simple_sku: SimpleSku, __log_flow ) -> None: __log_flow('Approving...') return_request.make_item_approved(order_number, simple_sku) __log_flow('Return Request Saving...') self.__returns_storage.save(return_request) __log_flow('Return Request Saved!') try: __log_flow('Notification popup: Adding...') self.__add_notification_message(return_request, order_number, simple_sku, 'Approved') __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('Approved!') def __decline( self, return_request: ReturnRequest, order_number: OrderNumber, simple_sku: SimpleSku, __log_flow ) -> None: __log_flow('Declining...') qty = return_request.get_item_qty(order_number, simple_sku) order = self.__order_storage.load(order_number) # updating return_request.make_item_declined(order_number, simple_sku) order.decline_return(simple_sku, qty) # saving __log_flow('Declining: Return Request Saving...') self.__returns_storage.save(return_request) __log_flow('Declining: Return Request Saved!') __log_flow('Declining: Order Saving...') self.__order_storage.save(order) __log_flow('Declining: Order Saved!') # add notification silently try: __log_flow('Notification popup: Adding...') self.__add_notification_message(return_request, order_number, simple_sku, '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('Declined!') def __close( self, return_request: ReturnRequest, order_number: OrderNumber, simple_sku: SimpleSku, __log_flow ) -> None: __log_flow('Closing...') qty = return_request.get_item_qty(order_number, simple_sku) product = self.__product_storage.load(simple_sku) order = self.__order_storage.load(order_number) product.restore_qty(qty) order.close_return(simple_sku, qty) return_request.make_item_closed(order_number, simple_sku) # update product __log_flow('Closing: Product Qty: Restoring...') self.__product_storage.update(product) __log_flow('Closing: Product Qty: Restored!') # update order __log_flow('Closing: Order Qty: Returning...') self.__order_storage.save(order) __log_flow('Closing: Order Qty: Returned!') # update request __log_flow('Closing: Return Request: Updating...') self.__returns_storage.save(return_request) __log_flow('Closing: Return Request: Updated!') __log_flow('Closing: Order SQS: Sending...') self.__sqs_sender.send(OrderChangeSqsSenderEvent(order)) __log_flow('Closing: Order SQS: Sent!') # add notification silently try: __log_flow('Notification popup: Adding...') self.__add_notification_message(return_request, order_number, simple_sku, 'Closed') __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('Closed!') def __add_notification_message( self, return_request: ReturnRequest, order_number: OrderNumber, simple_sku: SimpleSku, status_label: str ) -> None: order = self.__order_storage.load(order_number) 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, 'Return Request #{} has been Updated!'.format(return_request.number.value), 'Return Request for Product "{}" for Order #{} has been {}!'.format( product.name.value, order_number.value, status_label ), ) self.__messages_storage.save(message)
def returns_reject(): returns_storage = ReturnRequestStorageImplementation() orders_storage = OrderStorageImplementation() sqs_sender = SqsSenderImplementation() logger = Logger() request_data = blueprint.current_request.json_body request_number = str(request_data.get('request_number') or '').strip() or None if not request_number: raise BadRequestError('"request_number" is required') order_number_value = str(request_data.get('order_number') or '').strip() or None if not order_number_value: raise BadRequestError('"order_number" is required') simple_sku_value = str(request_data.get('simple_sku') or '').strip() or None if not simple_sku_value: raise BadRequestError('"simple_sku" is required') return_request = returns_storage.load( ReturnRequest.Number(request_number)) if not return_request: raise NotFoundError( 'Return Request #{} does not exist!'.format(request_number)) if return_request.customer_id.value != __get_user().id: raise ForbiddenError('It is not your Return Request!') order_number = OrderNumber(order_number_value) simple_sku = SimpleSku(simple_sku_value) order = orders_storage.load(order_number) if (not order or not len([ item for item in return_request.items if item.order_number == order_number ]) or not len( [item for item in order.items if item.simple_sku == simple_sku])): raise NotFoundError( 'Product "{}" is not requested in Return Request #{} for Order #{}!' .format( simple_sku.value, return_request.number.value, order_number.value, )) # update values try: qty = return_request.get_item_qty(order_number, simple_sku) return_request.make_item_rejected(order_number, simple_sku) order.reject_return(simple_sku, qty) except ApplicationLogicException as e: raise UnprocessableEntityError(str(e)) # save updates def __log_flow(text: str) -> None: logger.log_simple('Return Request #{} - Rejecting : {}'.format( return_request.number.value, text)) __log_flow('Start') # saving __log_flow('Saving - Start') try: __log_flow('Order #{} Saving...'.format(order_number.value)) orders_storage.save(order) __log_flow('Order #{} Saving - Done!'.format(order_number.value)) __log_flow('Return Request Saving...') returns_storage.save(return_request) __log_flow('Return Request Saving - Done!') except ApplicationLogicException as e: __log_flow('Not Saved because of Error : {}'.format(str(e))) raise UnprocessableEntityError(str(e)) __log_flow('Saving - End') # send sqs __log_flow('SQS Sending - Start') try: __log_flow('Return Request SQS Sending...') sqs_sender.send(ReturnRequestChangeSqsSenderEvent(return_request)) __log_flow('Return Request SQS Sending - Done!') except BaseException as e: __log_flow( 'Return Request SQS Sending - Not done because of Error : {}'. format(str(e))) logger.log_exception(e) __log_flow('SQS Sending - End') __log_flow('End')
class FbucksChargeSqsHandler(SqsHandlerInterface): # @TODO : REFACTORING !!! currently we are working with raw data def __init__(self): self.__orders_storage = OrderStorageImplementation() self.__logger = Logger() # """ # curl -X DELETE localhost:9200/fbucks_handled_orders # curl -X PUT localhost:9200/fbucks_handled_orders -H "Content-Type: application/json" -d'{ # "mappings": { # "fbucks_handled_orders": { # "properties": { # "handled_at": {"type": "date", "format": "yyyy-MM-dd HH:mm:ss"} # } # } # } # }' # """ # self.__fbucks_handled_orders_elastic = Elastic( # settings.AWS_ELASTICSEARCH_FBUCKS_HANDLED_ORDERS, # settings.AWS_ELASTICSEARCH_FBUCKS_HANDLED_ORDERS, # ) self.__fbucks_handled_orders_dynamo_db = DynamoModel( settings.AWS_DYNAMODB_CMS_TABLE_NAME) self.__fbucks_handled_orders_dynamo_db.PARTITION_KEY = 'PURCHASE_FBUCKS_REWARD_HANDLED_ORDERS' # Attention! # We can get current customer's amount as a sum of all changes by customer_id # But theoretically elastic can not be in time with index update (1 second) between requests. # So there is another index to store amount value. """ curl -X DELETE localhost:9200/fbucks_customer_amount curl -X PUT localhost:9200/fbucks_customer_amount -H "Content-Type: application/json" -d'{ "mappings": { "fbucks_customer_amount": { "properties": { "amount": {"type": "integer"} } } } }' curl -X DELETE localhost:9200/fbucks_customer_amount_changes curl -X PUT localhost:9200/fbucks_customer_amount_changes -H "Content-Type: application/json" -d'{ "mappings": { "fbucks_customer_amount_changes": { "properties": { "customer_id": {"type": "keyword"}, "amount": {"type": "integer"}, "changed_at": {"type": "date", "format": "yyyy-MM-dd HH:mm:ss"}, "order_number": {"type": "keyword"} } } } }' """ self.__fbucks_customer_amount_elastic = Elastic( settings.AWS_ELASTICSEARCH_FBUCKS_CUSTOMER_AMOUNT, settings.AWS_ELASTICSEARCH_FBUCKS_CUSTOMER_AMOUNT, ) self.__fbucks_customer_amount_changes_elastic = Elastic( settings.AWS_ELASTICSEARCH_FBUCKS_CUSTOMER_AMOUNT_CHANGES, settings.AWS_ELASTICSEARCH_FBUCKS_CUSTOMER_AMOUNT_CHANGES, ) self.__customer_storage = CustomerStorageImplementation() self.__messages_storage = MessageStorageImplementation() 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)
class CustomerTiersCustomersSqsHandler(SqsHandlerInterface): def __init__(self): self.__tiers_storage = CustomerTierStorageImplementation() self.__messages = MessageStorageImplementation() self.__logger = Logger() """""" # @todo : refactoring from chalicelib.libs.purchase.core import CustomerInterface from chalicelib.libs.purchase.customer.storage import CustomerStorageImplementation see = CustomerInterface.tier see = CustomerStorageImplementation.save """""" self.__elastic = Elastic( settings.AWS_ELASTICSEARCH_CUSTOMER_TIERS_CUSTOMER_TIERS, settings.AWS_ELASTICSEARCH_CUSTOMER_TIERS_CUSTOMER_TIERS) def handle(self, sqs_message: SqsMessage) -> None: # 'tiers' here are the same tiers set as in 'customer_tiers_set' sqs-message. # Theoretically this message can be handled earlier than 'customer_tiers_set' message, # so we need to be sure, that all new tiers exist. incoming_tiers_ids = [ row['id'] for row in sqs_message.message_data['tiers'] ] stored_tiers_ids = [ tier.id.value for tier in self.__tiers_storage.get_all() ] if sum([ tier_id for tier_id in incoming_tiers_ids if tier_id not in stored_tiers_ids ]) > 0: # @todo : this is a crutch CustomerTiersTiersSqsHandler().handle( SqsMessage(sqs_message.id, 'customer_tiers_set', {'tiers': sqs_message.message_data['tiers']})) # assign customers to tiers tiers = self.__tiers_storage.get_all() tiers_map = {} for tier in tiers: tiers_map[tier.id.value] = tier for customer_tier_data in sqs_message.message_data.get('customers'): customer_email = str(customer_tier_data['email']) tier_id = int(customer_tier_data['tier_id']) if self.__elastic.get_data(customer_email): self.__elastic.update_data(customer_email, {'doc': { 'tier_id': tier_id }}) else: self.__elastic.create(customer_email, {'tier_id': tier_id}) # notify user (silently) try: tier = tiers_map[str(tier_id)] self.__messages.save( Message( str(uuid.uuid4()), customer_email, 'Your Customer Tier has been changed!', 'Now you are in the "{}" Customer Tier!'.format( tier.name.value))) except BaseException as e: self.__logger.log_exception(e)
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 on_signup(): logger = Logger() user = __get_current_user() # Attention! Please, do all actions silently (in try-except block) try: # Trigger to calculate product scores per the just registerred customer here. pass except Exception as e: pass # subscription try: __on_signup__subscription(user) except BaseException as e: logger.log_exception(e) # request customer info try: __on_signup_request_customer_info(user) except BaseException as e: logger.log_exception(e) # set information email and identification number try: email_value = str(__get_request().json_body.get('email') or '').strip() identification_number_value = str( __get_request().json_body.get('identification_number') or '').strip() # this is not usual usage, but it's simple to check identification number and email here in this way form = AccountInformationForm() form.load({ AccountInformationForm.ATTRIBUTE_EMAIL: email_value, AccountInformationForm.ATTRIBUTE_IDENTIFICATION_NUMBER: identification_number_value }) form_errors = form.validate() email_errors = form_errors.get( AccountInformationForm.ATTRIBUTE_EMAIL, []) identification_number_errors = form_errors.get( AccountInformationForm.ATTRIBUTE_IDENTIFICATION_NUMBER, []) if email_errors or identification_number_errors: return { 'status': False, 'message': (email_errors + identification_number_errors)[0] } # update only identification number and email information = user.profile.informations information['email'] = email_value information['identification_number'] = identification_number_value user.profile.informations = information event = InformationsSqsSenderEvent(user.profile.informations) SqsSenderImplementation().send(event) return {'status': True} except BaseException as e: logger.log_exception(e) return {'status': False, 'message': 'Internal Server Error'}
class OrderPaymentOhHoldHandler(SqsHandlerInterface): def __init__(self): self.__order_storage = OrderStorageImplementation() self.__sqs_sender = SqsSenderImplementation() self.__logger = Logger() self.__message_storage = MessageStorageImplementation() self.__customer_storage = CustomerStorageImplementation() self.__products_storage = ProductStorageImplementation() 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 __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 __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 __send_order_change_to_portal(self, order: Order, __log_flow) -> None: __log_flow('Order SQS: Sending...') self.__sqs_sender.send(OrderChangeSqsSenderEvent(order)) __log_flow('Order SQS: Sent!') def __notify_about_order_status_change_silently(self, order: Order, __log_flow) -> None: try: __log_flow('Notification popup: Adding...') customer = self.__customer_storage.get_by_id(order.customer_id) self.__message_storage.save(Message( str(uuid.uuid4()), customer.email.value, 'Order #{} status is changed!', 'Order #{} has been turned to "{}" status!'.format(order.number.value, order.status.label) )) __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)))
class CancelledOrderOnPortalSideSqsHandle(SqsHandlerInterface): def __init__(self): self.__orders_storage = OrderStorageImplementation() self.__products_storage = ProductStorageImplementation() self.__cancel_request_storage = CancelRequestStorageImplementation() self.__customer_storage = CustomerStorageImplementation() self.__messages_storage = MessageStorageImplementation() self.__sqs_sender = SqsSenderImplementation() self.__logger = Logger() 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 credit_cards_checkout(): cards_storage = CreditCardsStorageImplementation() checkout_storage = CheckoutStorageImplementation() order_app_service = OrderAppService() cart_service = CartAppService() checkout_service = CheckoutAppService() logger = Logger() try: user = __get_user() card_response_id = (blueprint.current_request.json_body or {}).get('card_id') or None if not card_response_id: raise BadRequestError('Incorrect Input Data!') card = None for _card in cards_storage.get_all_by_customer(user.id): if __get_card_response(_card)['id'] == card_response_id: card = _card break if not card: raise NotFoundError('Card does not exist!') elif not card.is_verified: raise ApplicationLogicException( 'Unable to checkout with Not Verified Card!') checkout = checkout_storage.load(Id(user.id)) if not checkout: raise HttpNotFoundException('Checkout does not exist!') elif checkout.total_due.value == 0: raise ApplicationLogicException( 'Unable to checkout 0 amount with Credit Cards!') order = order_app_service.get_waiting_for_payment_by_checkout_or_checkout_new( user.id) def __log_flow(text: str) -> None: logger.log_simple('Credit Cards : Checkout : {} : {}'.format( order.number.value, text)) __log_flow('Start') # init try: __log_flow('Payment Request...') response = requests.post( url=settings.PEACH_PAYMENT_BASE_URL + 'registrations/{}/payments'.format(card.token), data={ 'entityId': settings.PEACH_PAYMENT_ENTITY_ID, 'amount': '%.2f' % order.total_current_cost_ordered.value, 'paymentType': 'DB', 'currency': 'ZAR', 'shopperResultUrl': requests.utils.requote_uri(settings.FRONTEND_BASE_URL + '/order/confirmation/{}'. format(order.number.value)), 'customParameters[order_number]': order.number.value, }, headers={ 'Authorization': 'Bearer {}'.format(settings.PEACH_PAYMENT_ACCESS_TOKEN) }) if response.status_code != 200: raise Exception( 'Peach Payment Request has been Failed: {} - {} - {}'. format(response.status_code, response.reason, response.text)) response_data = response.json() if response_data['result']['code'] not in ( '000.200.000', # transaction pending ): raise Exception( 'Credit Card Initial request response is not good: {} - {}' .format(response_data['result']['code'], response_data['result']['description'])) __log_flow('Payment Request is Done!') except BaseException as e: logger.log_exception(e) __log_flow( 'Payment Request is Not done because of Error: {}'.format( str(e))) raise UnprocessableEntityError( 'Credit Card Payment is unavailable now!') # flush cart (silently) try: __log_flow('Cart Flushing...') cart_service.clear_cart(user.session_id) __log_flow('Cart Flushed!') except BaseException as e: logger.log_exception(e) __log_flow('Cart is NOT Flushed because of Error: {}'.format( str(e))) # flush checkout (silently) try: __log_flow('Checkout Flushing...') checkout_service.remove(user.id) __log_flow('Checkout Flushed!') except BaseException as e: logger.log_exception(e) __log_flow( 'Checkout is NOT Flushed because of Error: {}'.format( str(e))) result = { 'order_number': order.number.value, 'url': response_data['redirect']['url'], 'method': 'POST', 'parameters': [{ 'name': param['name'], 'value': param['value'], } for param in response_data['redirect']['parameters']] } __log_flow('End') return result except BaseException as e: logger.log_exception(e) return http_response_exception_or_throw(e)
def credit_cards_remove(): cards_storage = CreditCardsStorageImplementation() logger = Logger() try: user = __get_user() card_response_id = (blueprint.current_request.json_body or {}).get('card_id') or None if not card_response_id: raise BadRequestError('Incorrect Input Data!') card = None for _card in cards_storage.get_all_by_customer(user.id): if card_response_id == __get_card_response(_card)['id']: card = _card break if not card: raise NotFoundError('Card not Found!') def __log_flow(text: str) -> None: logger.log_simple('Removing Credit Card #{} : {}'.format( card.token, text)) __log_flow('Start') try: __log_flow('Removing from storage...') cards_storage.remove(card) __log_flow('Removed from storage!') __log_flow('Removing from Peach...') response = requests.delete( url=settings.PEACH_PAYMENT_BASE_URL + 'registrations/{}?entityId={}'.format( card.token, settings.PEACH_PAYMENT_ENTITY_ID), headers={ 'Authorization': 'Bearer {}'.format(settings.PEACH_PAYMENT_ACCESS_TOKEN) }) if response.status_code != 200: raise Exception( 'Peach Payment Request has been Failed: {} - {} - {}'. format(response.status_code, response.reason, response.text)) response_data = response.json() if response_data['result']['code'] not in ( '000.000.000', # Transaction successfully processed in LIVE system '000.100.110', # Transaction successfully processed in TEST system ): raise Exception( 'Peach Payment is not available now: {}'.format( response_data['result'])) __log_flow('Removed from Peach!') except BaseException as e: __log_flow('Not done because of Error: {}'.format(str(e))) raise e __log_flow('End') except BaseException as e: logger.log_exception(e) return http_response_exception_or_throw(e) return { 'Code': 'Success', 'Message': 'Success', }
def mobicred_checkout(): order_app_service = OrderAppService() cart_service = CartAppService() checkout_storage = CheckoutStorageImplementation() checkout_service = CheckoutAppService() logger = Logger() try: user = blueprint.current_request.current_user if user.is_anyonimous: raise HttpAuthenticationRequiredException() # @todo : refactoring checkout = checkout_storage.load(Id(user.id)) if not checkout: raise HttpNotFoundException('Checkout does not exist!') elif checkout.total_due.value == 0: raise ApplicationLogicException( 'Unable to checkout 0 amount with Mobicred!') # check input data form = MobicredCredentialsForm() form.load(blueprint.current_request.json_body or {}) form_errors = form.validate() if form_errors: return {'status': False, 'form_errors': form_errors} order = order_app_service.get_waiting_for_payment_by_checkout_or_checkout_new( user.id) def __log_flow(text: str) -> None: logger.log_simple( 'Mobicred Payment Log for Order #{} : {}'.format( order.number.value, text)) __log_flow('Start') # init mobicred try: __log_flow('Payment Initializing...') response = requests.post( url=settings.PEACH_PAYMENT_BASE_URL + 'payments', data={ 'entityId': settings.PEACH_PAYMENT_ENTITY_ID, 'paymentBrand': 'MOBICRED', 'paymentType': 'DB', 'virtualAccount[accountId]': form.username, 'virtualAccount[password]': form.password, 'amount': '%.2f' % order.total_current_cost_ordered.value, 'currency': 'ZAR', 'customParameters[order_number]': order.number.value, 'shopperResultUrl': requests.utils.requote_uri(settings.FRONTEND_BASE_URL + '/order/confirmation/{}'. format(order.number.value)), }, headers={ 'Authorization': 'Bearer {}'.format(settings.PEACH_PAYMENT_ACCESS_TOKEN) }) if response.status_code != 200: raise Exception( 'Mobicred Initial request has been failed: {} - {} - {}!' .format(response.status_code, response.reason, response.text)) response_data = response.json() if response_data['result']['code'] not in ( '000.000.000', # Transaction successfully processed in LIVE system '000.100.110', # Transaction successfully processed in TEST system ): raise Exception( 'Mobicred Initial request response is not good: {} - {}' .format(response_data['result']['code'], response_data['result']['description'])) except BaseException as e: logger.log_exception(e) __log_flow( 'Payment Not Initialized because of Error: {}'.format( str(e))) raise HttpNotFoundException( 'Mobicred Payment is unavailable now!') __log_flow('Payment Initialized!') # flush cart (silently) try: __log_flow('Cart Flushing...') cart_service.clear_cart(user.session_id) __log_flow('Cart Flushed!') except BaseException as e: logger.log_exception(e) __log_flow('Cart Not Flushed because of Error {}!'.format( str(e))) # flush checkout (silently) try: __log_flow('Checkout Flushing...') checkout_service.remove(user.id) __log_flow('Checkout Flushed!') except BaseException as e: __log_flow('Cart Not Flushed because of Error {}!'.format( str(e))) logger.log_exception(e) __log_flow('End') result = { 'order_number': order.number.value, 'url': response_data['redirect']['url'], 'method': 'POST', 'parameters': response_data['redirect']['parameters'], } return result except BaseException as e: return http_response_exception_or_throw(e)
class RegularEftPaymentSqsHandler(SqsHandlerInterface): def __init__(self): # Need to be imported here, because orders storage depends from payment method class in this file. from chalicelib.libs.purchase.order.storage import OrderStorageImplementation from chalicelib.libs.purchase.product.storage import ProductStorageImplementation self.__order_storage = OrderStorageImplementation() self.__sqs_sender = SqsSenderImplementation() self.__logger = Logger() self.__message_storage = MessageStorageImplementation() self.__customer_storage = CustomerStorageImplementation() self.__products_storage = ProductStorageImplementation() 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')