예제 #1
0
    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')
예제 #2
0
    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')
예제 #3
0
 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)))
예제 #4
0
    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')
예제 #5
0
    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)
예제 #6
0
 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)
예제 #7
0
 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)
예제 #8
0
    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')
예제 #9
0
    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)