예제 #1
0
    def test_list_menu_range_endpoint_with_right_permission_wrong_period(self):
        location = LocationFactory()
        meal_item_repo = MealItemRepo()
        role = RoleFactory.create(name='admin')
        user_id = BaseTestCase.user_id()
        PermissionFactory.create(keyword='view_menu', role=role)
        UserRoleFactory.create(user_id=user_id, role=role)
        current_date = datetime.now().date()
        start_date = current_date.strftime('%Y-%m-%d')
        end_date = (datetime.now().date() +
                    timedelta(days=7)).strftime('%Y-%m-%d')

        side_meal_item = meal_item_repo.new_meal_item(name="side1",
                                                      image="image11",
                                                      meal_type="side",
                                                      location_id=location.id)
        protein_meal_item = meal_item_repo.new_meal_item(
            name="protein1",
            image="image12",
            meal_type="protein",
            location_id=location.id)
        MenuFactory.create_batch(5,
                                 side_items=side_meal_item.id,
                                 protein_items=protein_meal_item.id)

        response = self.client() \
            .get(self.make_url(f'/admin/menus/wrong_period/{start_date}/{end_date}'), headers=self.headers())
        response_json = self.decode_from_json_string(
            response.data.decode('utf-8'))

        self.assert400(response)
        self.assertEqual(response_json['msg'],
                         'Provide valid meal period and date range')
예제 #2
0
    def test_list_menu_endpoint_with_invalid_date_fails(self):
        """Test that users with the wrong date fails"""
        meal_item_repo = MealItemRepo()
        location = LocationFactory.create()

        main_meal_item = meal_item_repo.new_meal_item(name="main1",
                                                      image="image1",
                                                      meal_type="main",
                                                      location_id=location.id)
        side_meal_item = meal_item_repo.new_meal_item(name="side1",
                                                      image="image11",
                                                      meal_type="side",
                                                      location_id=location.id)
        protein_meal_item = meal_item_repo.new_meal_item(
            name="protein1",
            image="image12",
            meal_type="protein",
            location_id=location.id)

        menu = MenuFactory.create(main_meal_id=main_meal_item.id,
                                  side_items=str(side_meal_item.id),
                                  protein_items=str(protein_meal_item.id))

        date = '201502-24'

        response = self.client().get(
            self.make_url(f'/menus/{menu.meal_period}/{date}/{date}'),
            headers=self.headers())
        self.assert400(response)
예제 #3
0
    def test_list_menu_range_endpoint_with_right_permission(self):
        """ Test that users with right permission can view list of menu with date range """
        location = LocationFactory.create()
        meal_item_repo = MealItemRepo()
        role = RoleFactory.create(name='admin')
        user_id = BaseTestCase.user_id()
        PermissionFactory.create(keyword='view_menu', role=role)
        UserRoleFactory.create(user_id=user_id, role=role)
        current_date = datetime.now().date()
        start_date = current_date.strftime('%Y-%m-%d')
        end_date = (datetime.now().date() +
                    timedelta(days=7)).strftime('%Y-%m-%d')

        side_meal_item = meal_item_repo.new_meal_item(name="side1",
                                                      image="image11",
                                                      meal_type="side",
                                                      location_id=location.id)
        protein_meal_item = meal_item_repo.new_meal_item(
            name="protein1",
            image="image12",
            meal_type="protein",
            location_id=location.id)
        MenuFactory.create_batch(5,
                                 side_items=side_meal_item.id,
                                 protein_items=protein_meal_item.id,
                                 location=location)

        response = self.client() \
            .get(self.make_url(f'/admin/menus/{MealPeriods.lunch}/{start_date}/{end_date}'), headers=self.headers())

        self.assert200(response)
예제 #4
0
    def test_list_menu_range_endpoint_succeeds(self):
        meal_item_repo = MealItemRepo()

        main_meal_item = meal_item_repo.new_meal_item(name="main1",
                                                      image="image1",
                                                      meal_type="main",
                                                      location_id=1)
        side_meal_item = meal_item_repo.new_meal_item(name="side1",
                                                      image="image11",
                                                      meal_type="side",
                                                      location_id=1)
        protein_meal_item = meal_item_repo.new_meal_item(name="protein1",
                                                         image="image12",
                                                         meal_type="protein",
                                                         location_id=1)

        menu = MenuFactory.create(main_meal_id=main_meal_item.id,
                                  side_items=str(side_meal_item.id),
                                  protein_items=str(protein_meal_item.id))

        start_date = menu.vendor_engagement.start_date - timedelta(days=1)

        response = self.client().get(self.make_url(
            f'/menus/{menu.meal_period}/{start_date}/{menu.vendor_engagement.end_date}'
        ),
                                     headers=self.headers())

        response_json = self.decode_from_json_string(
            response.data.decode('utf-8'))

        self.assertEqual(response_json['msg'], 'OK')
        self.assertEqual(
            response_json['payload']['menuList'][0]['menus'][0]['id'], menu.id)
예제 #5
0
    def test_list_menu_endpoint_with_right_permission(self):
        """Test that users with the right permission can view list of menus"""

        meal_item_repo = MealItemRepo()
        role = RoleFactory.create(name='admin')
        user_id = BaseTestCase.user_id()
        PermissionFactory.create(keyword='view_menu', role_id=role.id)
        UserRoleFactory.create(user_id=user_id, role_id=role.id)
        the_date = datetime.now().date()
        current_date = the_date.strftime('%Y-%m-%d')

        side_meal_item = meal_item_repo.new_meal_item(name="side1",
                                                      image="image11",
                                                      meal_type="side",
                                                      location_id=1)
        protein_meal_item = meal_item_repo.new_meal_item(name="protein1",
                                                         image="image12",
                                                         meal_type="protein",
                                                         location_id=1)
        MenuFactory.create_batch(5,
                                 side_items=side_meal_item.id,
                                 protein_items=protein_meal_item.id,
                                 date=the_date)

        response = self.client().get(
            self.make_url(f'/admin/menus/{MealPeriods.lunch}/{current_date}'),
            headers=self.headers())

        self.assert200(response)
 def __init__(self, request):
     BaseController.__init__(self, request)
     self.vendor_rating_repo = VendorRatingRepo()
     self.vendor_repo = VendorRepo()
     self.vendor_engagement_repo = VendorEngagementRepo()
     self.menu_repo = MenuRepo()
     self.meal_repo = MealItemRepo()
     self.order_repo = OrderRepo()
예제 #7
0
 def __init__(self, request):
     BaseController.__init__(self, request)
     self.slackhelper = SlackHelper()
     self.menu_repo = MenuRepo()
     self.meal_repo = MealItemRepo()
     self.engagement_repo = VendorEngagementRepo()
     self.andela_service = AndelaService()
     self.vendor_rating_repo = VendorRatingRepo()
예제 #8
0
    def test_update_menu_endpoint_with_wrong_protein_item_values(self):
        location = LocationFactory.create()
        role = RoleFactory.create(name='admin')
        user_id = BaseTestCase.user_id()
        PermissionFactory.create(keyword='update_menu', role=role)
        UserRoleFactory.create(user_id=user_id, role=role)

        meal_item_repo = MealItemRepo()

        main_meal_item = meal_item_repo.new_meal_item(name="main1",
                                                      image="image1",
                                                      meal_type="main",
                                                      location_id=location.id)
        side_meal_item = meal_item_repo.new_meal_item(name="side1",
                                                      image="image11",
                                                      meal_type="side",
                                                      location_id=location.id)
        protein_meal_item = meal_item_repo.new_meal_item(
            name="protein1",
            image="image12",
            meal_type="protein",
            location_id=location.id)

        vendor = VendorFactory.build()
        vendor_engagement = VendorEngagementFactory.build(vendor_id=vendor.id)
        vendor_engagement.save()

        menu = MenuFactory.create(main_meal_id=main_meal_item.id,
                                  side_items=side_meal_item.id,
                                  protein_items=protein_meal_item.id)
        menu.vendor_engagement_id = vendor_engagement.id
        menu.save()

        data = {
            'date': menu.date.strftime('%Y-%m-%d'),
            'mealPeriod': menu.meal_period,
            'mainMealId': main_meal_item.id,
            'allowedSide': 2,
            'allowedProtein': 2,
            'sideItems': [side_meal_item.id],
            'proteinItems': [1000],
            'vendorEngagementId': vendor_engagement.id
        }

        response = self.client().put(self.make_url('/admin/menus/{}'.format(
            menu.id)),
                                     data=self.encode_to_json_string(data),
                                     headers=self.headers())
        response_json = self.decode_from_json_string(
            response.data.decode('utf-8'))

        self.assert400(response)
        self.assertEqual(
            response_json['msg'],
            'Bad Request - proteinItems contains invalid id(s) for meal_item table '
        )
예제 #9
0
    def test_update_menu_endpoint(self):
        """Test update of a menu"""
        location = LocationFactory()
        role = RoleFactory.create(name='admin')
        user_id = BaseTestCase.user_id()
        PermissionFactory.create(keyword='update_menu', role=role)
        UserRoleFactory.create(user_id=user_id, role=role)

        meal_item_repo = MealItemRepo()

        main_meal_item = meal_item_repo.new_meal_item(name="main1",
                                                      image="image1",
                                                      meal_type="main",
                                                      location_id=location.id)
        side_meal_item = meal_item_repo.new_meal_item(name="side1",
                                                      image="image11",
                                                      meal_type="side",
                                                      location_id=location.id)
        protein_meal_item = meal_item_repo.new_meal_item(
            name="protein1",
            image="image12",
            meal_type="protein",
            location_id=location.id)
        vendor = VendorFactory.build()
        vendor_engagement = VendorEngagementFactory.build(vendor_id=vendor.id)
        vendor_engagement.save()
        menu = MenuFactory.create(main_meal_id=main_meal_item.id,
                                  side_items=side_meal_item.id,
                                  protein_items=protein_meal_item.id,
                                  location=location)
        menu.save()
        data = {
            'date': menu.date.strftime('%Y-%m-%d'),
            'mealPeriod': menu.meal_period,
            'mainMealId': main_meal_item.id,
            'allowedSide': 2,
            'allowedProtein': 2,
            'sideItems': [side_meal_item.id],
            'proteinItems': [protein_meal_item.id],
            'vendorEngagementId': vendor_engagement.id
        }

        response = self.client().put(self.make_url('/admin/menus/{}'.format(
            menu.id)),
                                     data=self.encode_to_json_string(data),
                                     headers=self.headers())
        response_json = self.decode_from_json_string(
            response.data.decode('utf-8'))
        payload = response_json['payload']

        self.assert200(response)
        self.assertEqual(payload['menu']['allowedProtein'],
                         data['allowedProtein'])
        self.assertEqual(payload['menu']['allowedSide'], data['allowedSide'])
    def test_update_menu_endpoint_with_wrong_permission(self):
        role = RoleFactory.create(name='admin')
        user_id = BaseTestCase.user_id()
        PermissionFactory.create(keyword='wrong_permission', role_id=role.id)
        UserRoleFactory.create(user_id=user_id, role_id=role.id)

        meal_item_repo = MealItemRepo()

        main_meal_item = meal_item_repo.new_meal_item(name="main1",
                                                      description="descr1",
                                                      image="image1",
                                                      meal_type="main",
                                                      location_id=1)
        side_meal_item = meal_item_repo.new_meal_item(name="side1",
                                                      description="descr11",
                                                      image="image11",
                                                      meal_type="side",
                                                      location_id=1)
        protein_meal_item = meal_item_repo.new_meal_item(name="protein1",
                                                         description="descr11",
                                                         image="image12",
                                                         meal_type="protein",
                                                         location_id=1)

        vendor = VendorFactory.build()
        vendor_engagement = VendorEngagementFactory.build(vendor_id=vendor.id)

        menu = MenuFactory.create(main_meal_id=main_meal_item.id,
                                  side_items=side_meal_item.id,
                                  protein_items=protein_meal_item.id)
        menu.vendor_engagement_id = vendor_engagement.id

        data = {
            'date': menu.date.strftime('%Y-%m-%d'),
            'mealPeriod': menu.meal_period,
            'mainMealId': 10000,
            'allowedSide': 2,
            'allowedProtein': 2,
            'sideItems': [side_meal_item.id],
            'proteinItems': [protein_meal_item.id],
            'vendorEngagementId': vendor_engagement.id
        }

        response = self.client().put(self.make_url('/admin/menus/{}'.format(
            menu.id)),
                                     data=self.encode_to_json_string(data),
                                     headers=self.headers())
        response_json = self.decode_from_json_string(
            response.data.decode('utf-8'))

        self.assert400(response)
        self.assertEqual(response_json['msg'],
                         'Access Error - Permission Denied')
class VendorRatingController(BaseController):
    def __init__(self, request):
        BaseController.__init__(self, request)
        self.vendor_rating_repo = VendorRatingRepo()
        self.vendor_repo = VendorRepo()
        self.vendor_engagement_repo = VendorEngagementRepo()
        self.menu_repo = MenuRepo()
        self.meal_repo = MealItemRepo()
        self.order_repo = OrderRepo()

    def list_ratings(self, date):
        """retrieves a list of all ratings"""
        query_kwargs = self.get_params_dict()
        date = datetime.strptime(date, '%Y-%m-%d')

        ratings = self.vendor_rating_repo.filter_by(service_date=date,
                                                    **query_kwargs)
        if ratings.items:
            result = []
            vendor_name = self.vendor_repo.get(ratings.items[0].vendor_id).name

            for rating in ratings.items:
                if not rating.main_meal_id:
                    continue

                meal_name = self.meal_repo.get(rating.main_meal_id).name

                if meal_name not in [item.get('mainMeal') for item in result]:
                    meal_rating = {
                        'mainMeal':
                        meal_name,
                        'overallRating':
                        self.vendor_rating_repo.meal_average(
                            rating.main_meal_id, date),
                        'items': [
                            rtng.serialize() for rtng in ratings.items
                            if rtng.main_meal_id == rating.main_meal_id
                        ]
                    }
                    result.append(meal_rating)

            return self.handle_response('OK',
                                        payload={
                                            'date': date,
                                            'vendor': vendor_name,
                                            'result': result
                                        })
        return self.handle_response('No ratings for this date',
                                    status_code=404)

    def get_vendor_rating(self, rating_id):
        """retrieves the details of a specific rating, giving the rating id"""
        rating = self.vendor_rating_repo.get(rating_id)
        if rating:
            rtng = rating.serialize()

            return self.handle_response('OK', payload={'rating': rtng})
        else:
            return self.handle_response('Bad Request', status_code=400)

    def create_vendor_rating(self):
        '''Adds a vendor rating during a specific engagement'''
        (comment, rating, service_date, channel,
         engagement_id) = self.request_params('comment', 'rating',
                                              'serviceDate', 'channel',
                                              'engagementId')
        main_meal_id = None
        user_id = Auth.user('id')
        vendor_id = self.vendor_engagement_repo.get(engagement_id).vendor_id

        if self.vendor_repo.get(vendor_id):

            service_date = datetime.strptime(service_date, '%Y-%m-%d')

            rating = self.vendor_rating_repo.new_rating(
                vendor_id, user_id, rating, service_date,
                RatingType.engagement, engagement_id, engagement_id,
                main_meal_id, channel, comment)
            self.vendor_repo.update_vendor_average_rating(vendor_id)
            rtng = rating.serialize()

            return self.handle_response('Rating created',
                                        payload={'rating': rtng},
                                        status_code=201)

        return self.handle_response('Invalid vendor_id provided',
                                    status_code=400)

    def create_order_rating(self):
        """Adds a order or meal rating during a specific engagement """

        (order_id, main_meal_id, engagement_id, comment, rating, service_date,
         channel) = self.request_params('orderId', 'mainMealId',
                                        'engagementId', 'comment', 'rating',
                                        'serviceDate', 'channel')
        if not (1 <= rating <= 5):
            return self.handle_response(
                'Rating must be between 1 and 5, inclusive.', status_code=400)

        user_id = Auth.user('id')
        if not self.meal_repo.get(main_meal_id):
            return self.handle_response('Meal item with this id not found',
                                        status_code=400)
        engagement = self.vendor_engagement_repo.get(engagement_id)
        if not engagement:
            return self.handle_response('Engagement with this id is not found',
                                        status_code=400)
        vendor_id = engagement.vendor_id
        if order_id:
            rating_type = RatingType.order
            type_id = order_id
            order = self.order_repo.get(order_id)
            if not order:
                return self.handle_response('Order with this id is not found',
                                            status_code=400)
            if order.has_rated:
                return self.handle_response('This order has been rated',
                                            status_code=400)

        else:
            if (datetime.now() -
                    datetime.strptime(service_date, '%Y-%m-%d')).days < 1:
                return self.handle_response(
                    'You can only rate meals of past days.', status_code=400)
            rating_type = RatingType.meal
            type_id = main_meal_id
            user_meal_rating = self.vendor_rating_repo.get_unpaginated(
                user_id=user_id, type_id=type_id, rating_type='meal')
            if user_meal_rating:
                return self.handle_response('You have already rated this meal',
                                            status_code=400)

        rating = self.vendor_rating_repo.new_rating(
            vendor_id, user_id, rating,
            datetime.strptime(service_date, '%Y-%m-%d'), rating_type, type_id,
            engagement_id, main_meal_id, channel, comment)

        self.vendor_repo.update_vendor_average_rating(vendor_id)
        if rating.id and rating_type == RatingType.order:
            updates = {'has_rated': True}
            self.order_repo.update(order, **updates)

        rating_obj = rating.serialize()
        return self.handle_response('Rating successful',
                                    payload={'rating': rating_obj},
                                    status_code=201)

    def update_vendor_rating(self, rating_id):
        """edits an existing rating"""

        rtng = self.vendor_rating_repo.get(rating_id)
        comment = self.get_json()['comment']
        if rtng:
            if Auth.user(
                    'id'
            ) == rtng.user_id:  #You cannot update someone else's rating

                updates = {}
                if comment:
                    updates['comment'] = comment
                self.vendor_rating_repo.update(rtng, **updates)
                return self.handle_response(
                    'OK', payload={'rating': rtng.serialize()})
            return self.handle_response(
                'You are not allowed to update a rating that is not yours',
                status_code=403)
        return self.handle_response('Invalid or incorrect rating_id provided',
                                    status_code=404)
예제 #12
0
    def interactions(self):
        request_payload, trigger_id = self.post_params('payload', 'trigger_id')
        payload = json.loads(request_payload)

        webhook_url = payload["response_url"]
        slack_id = payload['user']['id']

        if payload['type'] == 'dialog_submission':
            slack_user_info = self.slackhelper.user_info(slack_id)
            slack_user_email = slack_user_info['user']['profile']['email']

            if payload['callback_id'] == 'final_selection':

                state = payload['state'].split('_')
                menu_id = state[0]
                meal_period = state[1]
                date_booked_for = state[2]
                location_id = state[4]
                submitted_values = payload['submission']
                meal_items = [int(v) for k, v in submitted_values.items()]
                meal_items.append(MenuRepo().get(menu_id).main_meal_id)
                meal_items = [
                    meal for meal in MealItemRepo().get_meal_items_by_ids(
                        meal_items)
                ]
                channel = 'slack'

                # Retrieve User Object
                user = self.andela_service.get_user_by_email_or_id(
                    slack_user_email)
                user_id = user['id']

                order = OrderRepo().create_order(
                    user_id=user_id,
                    date_booked_for=date_booked_for,
                    meal_items=meal_items,
                    location_id=location_id,
                    menu_id=menu_id,
                    channel=channel,
                    meal_period=meal_period)

                if order:
                    slack_data = {'text': 'Booking Confirmed!'}
                    requests.post(webhook_url,
                                  data=json.dumps(slack_data),
                                  headers={'Content-Type': 'application/json'})
                else:
                    slack_data = {'text': 'Booking Failed. Please Retry'}
                    requests.post(webhook_url,
                                  data=json.dumps(slack_data),
                                  headers={'Content-Type': 'application/json'})

            if payload['callback_id'] == 'submit_rating':

                state = payload['state'].split('_')
                menu_id = state[0]
                menu = self.menu_repo.get(menu_id)
                service_date = menu.date
                rating_type = RatingType.meal
                type_id = menu.main_meal_id
                engagement_id = menu.vendor_engagement_id
                vendor_id = self.engagement_repo.get(engagement_id).vendor_id
                rating_value = payload['submission']['rating value']
                channel = 'slack'
                comment = payload['submission']['comment']

                # Retrieve User Object
                user = self.andela_service.get_user_by_email_or_id(
                    slack_user_email)
                user_id = user['id']

                rating = self.vendor_rating_repo.new_rating(
                    vendor_id, user_id, rating_value, service_date,
                    rating_type, type_id, engagement_id, channel, comment,
                    type_id)

                if rating:
                    slack_data = {'text': 'Rating Successful!'}
                    requests.post(webhook_url,
                                  data=json.dumps(slack_data),
                                  headers={'Content-Type': 'application/json'})
                else:
                    slack_data = {'text': 'Rating Failed. Please Retry'}
                    requests.post(webhook_url,
                                  data=json.dumps(slack_data),
                                  headers={'Content-Type': 'application/json'})

            return make_response('', 200)

        if payload['type'] == 'interactive_message' and payload[
                'callback_id'] == 'center_selector':
            location_id = payload['actions'][0]['value']

            location = LocationRepo().get(location_id)
            menu_start_end_on = BotController.get_menu_start_end_on(location)
            start_on = menu_start_end_on[0]
            end_on = menu_start_end_on[1]

            date_buttons = [{
                'name':
                'selected_date',
                'type':
                'button',
                'text':
                '{}, {}'.format(day.strftime('%a'), day.strftime('%b %-d')),
                'value':
                '{}_{}'.format(day.strftime('%Y-%m-%d'), location.id)
            } for day in daterange(start_on, end_on)]

            request_buttons = [{
                "text": "",
                "callback_id": "day_selector",
                "color": "#3AA3E3",
                "attachment_type": "default",
                "actions": date_buttons
            }]

            return self.handle_response(slack_response={
                'text': f'Select Date',
                'attachments': request_buttons
            })

        if payload['type'] == 'interactive_message' and payload[
                'callback_id'] == 'day_selector':
            payload_action_value = payload['actions'][0]['value']
            selected_date = payload_action_value.split('_')[0]
            location_id = payload_action_value.split('_')[1]

            period_buttons = [
                # {'name': 'meal_period', 'type': 'button', 'text': 'Breakfast',
                #  'value': 'breakfast_{}'.format(payload_action_value)},
                {
                    'name': 'meal_period',
                    'type': 'button',
                    'text': 'Lunch',
                    'value': 'lunch_{}'.format(payload_action_value)
                }
            ]

            request_buttons = [{
                "text": "",
                "callback_id": "period_selector",
                "color": "#3AA3E3",
                "attachment_type": "default",
                "actions": period_buttons
            }]

            return self.handle_response(slack_response={
                'text': f'Select Meal Period',
                'attachments': request_buttons
            })

        if payload['type'] == 'interactive_message' and payload[
                'callback_id'] == 'period_selector':
            period = payload['actions'][0]['value'].split('_')[0]
            date = payload['actions'][0]['value'].split('_')[1]
            location_id = payload['actions'][0]['value'].split('_')[2]
            actions = {
                "attachments": [{
                    "text":
                    'What do you want to do?',
                    "callback_id":
                    "action_selector",
                    "color":
                    "#3AA3E3",
                    "attachment_type":
                    "default",
                    "actions": [{
                        "name": "main meal",
                        "text": "View Menu List",
                        "type": "button",
                        "value": f'{period}_{date}_menu_{location_id}'
                    }, {
                        "name": "main meal",
                        "text": "Place order",
                        "type": "button",
                        "value": f'{period}_{date}_order_{location_id}'
                    }]
                }]
            }
            return self.handle_response(slack_response=actions)

        if payload['type'] == 'interactive_message' and payload[
                'callback_id'] == 'action_selector':
            payload_action_value = payload['actions'][0]['value']
            if payload_action_value.split('_')[2] == 'menu':
                date = payload_action_value.split('_')[1]
                period = payload_action_value.split('_')[0]
                location_id = payload_action_value.split('_')[3]
                menus = self.menu_repo.get_unpaginated(date=date,
                                                       meal_period=period,
                                                       is_deleted=False)
                if not menus:
                    #   No Menu for provided date
                    back_buttons = [{
                        'name': 'back',
                        'text': 'Back',
                        'type': "button",
                        'value': location_id
                    }]
                    request_buttons = [{
                        "text": "",
                        "callback_id": "center_selector",
                        "color": "#3AA3E3",
                        "attachment_type": "default",
                        "actions": back_buttons
                    }]
                    return self.handle_response(
                        slack_response={
                            'text':
                            f'Sorry No Menu found for Date: {date}, Meal Period: {period}',
                            'attachments': request_buttons
                        })
                text = ''

                for menu in menus:
                    side_items_list = menu.side_items.split(',')
                    protein_items_list = menu.protein_items.split(',')

                    main = self.meal_repo.get(menu.main_meal_id).name
                    sides = [
                        side.name for side in
                        self.meal_repo.get_meal_items_by_ids(side_items_list)
                    ]
                    proteins = [
                        protein.name
                        for protein in self.meal_repo.get_meal_items_by_ids(
                            protein_items_list)
                    ]
                    menu_info = f'Main meal: *{main}*\n Side items: {", ".join(sides)}\nProtein items: {", ".join(proteins)}\n\n\n'
                    text += menu_info

                meals = {
                    "text":
                    f'{period.upper()}',
                    "attachments": [{
                        "text":
                        text,
                        "callback_id":
                        "after_menu_list",
                        "color":
                        "#3AA3E3",
                        "attachment_type":
                        "default",
                        "actions": [{
                            "name":
                            "main meal",
                            "text":
                            "Rate meal",
                            "type":
                            "button",
                            "value":
                            f'{period}_{date}_rate_{location_id}_{location_id}'
                        }, {
                            "name":
                            "main meal",
                            "text":
                            "Place an order",
                            "type":
                            "button",
                            "value":
                            f'{period}_{date}_order_{location_id}_{location_id}'
                        }]
                    }]
                }
                return self.handle_response(slack_response=meals)

        if (payload['type'] == 'interactive_message'
                and payload['callback_id'] == 'action_selector'
                and payload['actions'][0]['value'].split('_')[2] == 'order'
            ) or (payload['callback_id'] == 'after_menu_list'
                  and payload['actions'][0]['value'].split('_')[2] == 'order'):
            payload_action_value = payload['actions'][0]['value']
            meal_period = payload_action_value.split('_')[0]
            selected_date = payload_action_value.split('_')[1]
            location_id = payload_action_value.split('_')[3]
            menus = self.menu_repo.get_unpaginated(date=selected_date,
                                                   meal_period=meal_period,
                                                   is_deleted=False)
            if not menus:
                #   No Menu for provided date
                back_buttons = [{
                    'name': 'back',
                    'text': 'Back',
                    'type': "button",
                    'value': location_id
                }]

                request_buttons = [{
                    "text": "",
                    "callback_id": "center_selector",
                    "color": "#3AA3E3",
                    "attachment_type": "default",
                    "actions": back_buttons
                }]
                return self.handle_response(
                    slack_response={
                        'text':
                        f'Sorry No Menu found for Date: {selected_date}, Meal Period: {meal_period}',
                        'attachments': request_buttons
                    })

            meal_buttons = [{
                'name': 'main_meal',
                'type': 'button',
                'text': f'{menu.main_meal.name}',
                'value': f'{menu.id}_{payload_action_value}'
            } for menu in menus]

            request_buttons = [{
                "text": "",
                "callback_id": "meal_action_selector",
                "color": "#3AA3E3",
                "attachment_type": "default",
                "actions": meal_buttons
            }]

            return self.handle_response(slack_response={
                'text': 'Select Main Meal',
                'attachments': request_buttons
            })

        if payload['type'] == 'interactive_message' and payload[
                'callback_id'] == 'meal_action_selector':
            payload_action_value = payload['actions'][0]['value']
            if payload_action_value.find('order') > -1:
                menu_id = payload_action_value.split('_')[0]
                menu = self.menu_repo.get(menu_id)
                slack_id = payload['user']['id']
                slack_user_info = self.slackhelper.user_info(slack_id)
                slack_user_email = slack_user_info['user']['profile']['email']
                user = self.andela_service.get_user_by_email_or_id(
                    slack_user_email)

                # check if user already has an order
                if OrderRepo().user_has_order(user['id'],
                                              menu.date.strftime('%Y-%m-%d'),
                                              menu.meal_period):
                    slack_data = {
                        'text':
                        'You already have an order for this meal period.'
                    }
                    requests.post(webhook_url,
                                  data=json.dumps(slack_data),
                                  headers={'Content-Type': 'application/json'})
                    return self.handle_response(status_code=400)
                trigger_id = payload['trigger_id']

                side_items_list = menu.side_items.split(',')
                protein_items_list = menu.protein_items.split(',')

                side_items = self.meal_repo.get_meal_items_by_ids(
                    side_items_list)
                protein_items = self.meal_repo.get_meal_items_by_ids(
                    protein_items_list)

                request_dialog_element = []

                for i in range(1, menu.allowed_side + 1):
                    request_dialog_element.append({
                        'label':
                        f'Select Side {i}',
                        'type':
                        'select',
                        'name':
                        f'side_{i}',
                        'options': [{
                            'label': f'{side.name}',
                            'value': f'{side.id}'
                        } for side in side_items]
                    })

                for i in range(1, menu.allowed_protein + 1):
                    request_dialog_element.append({
                        'label':
                        f'Select Protein {i}',
                        'type':
                        'select',
                        'name':
                        f'protein_{i}',
                        'options': [{
                            'label': f'{protein.name}',
                            'value': f'{protein.id}'
                        } for protein in protein_items]
                    })

                state = f'{payload_action_value}'
                self.create_dialog(dialog_elem=request_dialog_element,
                                   trigger_id=trigger_id,
                                   title='Select Protein & Sides',
                                   callback_id='final_selection',
                                   state=state)

                return self.handle_response(
                    slack_response={'text': 'Select Meal Protein and Sides'})

        if payload['callback_id'] == 'after_menu_list' and payload['actions'][
                0]['value'].split('_')[2] == 'rate':

            payload_action_value = payload['actions'][0]['value']
            meal_period = payload_action_value.split('_')[0]
            selected_date = payload_action_value.split('_')[1]
            location_id = payload_action_value.split('_')[2]
            menus = self.menu_repo.get_unpaginated(date=selected_date,
                                                   meal_period=meal_period,
                                                   is_deleted=False)
            if not menus:
                #   No Menu for provided date
                back_buttons = [{
                    'name': 'back',
                    'text': 'Back',
                    'type': "button",
                    'value': location_id
                }]

                request_buttons = [{
                    "text": "",
                    "callback_id": "center_selector",
                    "color": "#3AA3E3",
                    "attachment_type": "default",
                    "actions": back_buttons
                }]
                return self.handle_response(
                    slack_response={
                        'text':
                        f'Sorry No Menu found forr Date: {selected_date}, Meal Period: {meal_period}',
                        'attachments': request_buttons
                    })

            meal_buttons = [{
                'name': 'main_meal',
                'type': 'button',
                'text': f'{menu.main_meal.name}',
                'value': f'{menu.id}_{payload_action_value}'
            } for menu in menus]

            request_buttons = [{
                "text": "",
                "callback_id": "rating_selector",
                "color": "#3AA3E3",
                "attachment_type": "default",
                "actions": meal_buttons
            }]

            return self.handle_response(slack_response={
                'text': 'Select Main Meal',
                'attachments': request_buttons
            })

        if payload['callback_id'] == 'rating_selector':

            menu_id = payload['actions'][0]['value'].split('_')[0]
            menu = self.menu_repo.get(menu_id)
            trigger_id = payload['trigger_id']
            main_meal = menu.main_meal_id

            request_dialog_element = [{
                'label':
                f'Rate meal: {self.meal_repo.get(main_meal).name}',
                'type':
                'select',
                'name':
                'rating value',
                'options': [{
                    'label': f'{value}',
                    'value': f'{value}'
                } for value in range(1, 6)]
            }, {
                'label': 'Add a short comment',
                'type': 'text',
                'name': 'comment'
            }]

            state = f'{payload["actions"][0]["value"]}'
            self.create_dialog(dialog_elem=request_dialog_element,
                               trigger_id=trigger_id,
                               title='Rate a meal',
                               callback_id='submit_rating',
                               state=state)

            return self.handle_response(slack_response={'text': 'Meal rating'})
예제 #13
0
class BotController(BaseController):
    def __init__(self, request):
        BaseController.__init__(self, request)
        self.slackhelper = SlackHelper()
        self.menu_repo = MenuRepo()
        self.meal_repo = MealItemRepo()
        self.engagement_repo = VendorEngagementRepo()
        self.andela_service = AndelaService()
        self.vendor_rating_repo = VendorRatingRepo()

    def bot(self):
        locations = LocationRepo().fetch_all()
        location_buttons = [{
            'name': 'location',
            'text': f'{location.name}',
            'type': "button",
            'value': location.id
        } for location in locations.items]

        request_buttons = [{
            "text": "",
            "callback_id": "center_selector",
            "color": "#3AA3E3",
            "attachment_type": "default",
            "actions": location_buttons
        }]

        return self.handle_response(slack_response={
            'text': f'Welcome To Andela Eats',
            'attachments': request_buttons
        })

    def interactions(self):
        request_payload, trigger_id = self.post_params('payload', 'trigger_id')
        payload = json.loads(request_payload)

        webhook_url = payload["response_url"]
        slack_id = payload['user']['id']

        if payload['type'] == 'dialog_submission':
            slack_user_info = self.slackhelper.user_info(slack_id)
            slack_user_email = slack_user_info['user']['profile']['email']

            if payload['callback_id'] == 'final_selection':

                state = payload['state'].split('_')
                menu_id = state[0]
                meal_period = state[1]
                date_booked_for = state[2]
                location_id = state[4]
                submitted_values = payload['submission']
                meal_items = [int(v) for k, v in submitted_values.items()]
                meal_items.append(MenuRepo().get(menu_id).main_meal_id)
                meal_items = [
                    meal for meal in MealItemRepo().get_meal_items_by_ids(
                        meal_items)
                ]
                channel = 'slack'

                # Retrieve User Object
                user = self.andela_service.get_user_by_email_or_id(
                    slack_user_email)
                user_id = user['id']

                order = OrderRepo().create_order(
                    user_id=user_id,
                    date_booked_for=date_booked_for,
                    meal_items=meal_items,
                    location_id=location_id,
                    menu_id=menu_id,
                    channel=channel,
                    meal_period=meal_period)

                if order:
                    slack_data = {'text': 'Booking Confirmed!'}
                    requests.post(webhook_url,
                                  data=json.dumps(slack_data),
                                  headers={'Content-Type': 'application/json'})
                else:
                    slack_data = {'text': 'Booking Failed. Please Retry'}
                    requests.post(webhook_url,
                                  data=json.dumps(slack_data),
                                  headers={'Content-Type': 'application/json'})

            if payload['callback_id'] == 'submit_rating':

                state = payload['state'].split('_')
                menu_id = state[0]
                menu = self.menu_repo.get(menu_id)
                service_date = menu.date
                rating_type = RatingType.meal
                type_id = menu.main_meal_id
                engagement_id = menu.vendor_engagement_id
                vendor_id = self.engagement_repo.get(engagement_id).vendor_id
                rating_value = payload['submission']['rating value']
                channel = 'slack'
                comment = payload['submission']['comment']

                # Retrieve User Object
                user = self.andela_service.get_user_by_email_or_id(
                    slack_user_email)
                user_id = user['id']

                rating = self.vendor_rating_repo.new_rating(
                    vendor_id, user_id, rating_value, service_date,
                    rating_type, type_id, engagement_id, channel, comment,
                    type_id)

                if rating:
                    slack_data = {'text': 'Rating Successful!'}
                    requests.post(webhook_url,
                                  data=json.dumps(slack_data),
                                  headers={'Content-Type': 'application/json'})
                else:
                    slack_data = {'text': 'Rating Failed. Please Retry'}
                    requests.post(webhook_url,
                                  data=json.dumps(slack_data),
                                  headers={'Content-Type': 'application/json'})

            return make_response('', 200)

        if payload['type'] == 'interactive_message' and payload[
                'callback_id'] == 'center_selector':
            location_id = payload['actions'][0]['value']

            location = LocationRepo().get(location_id)
            menu_start_end_on = BotController.get_menu_start_end_on(location)
            start_on = menu_start_end_on[0]
            end_on = menu_start_end_on[1]

            date_buttons = [{
                'name':
                'selected_date',
                'type':
                'button',
                'text':
                '{}, {}'.format(day.strftime('%a'), day.strftime('%b %-d')),
                'value':
                '{}_{}'.format(day.strftime('%Y-%m-%d'), location.id)
            } for day in daterange(start_on, end_on)]

            request_buttons = [{
                "text": "",
                "callback_id": "day_selector",
                "color": "#3AA3E3",
                "attachment_type": "default",
                "actions": date_buttons
            }]

            return self.handle_response(slack_response={
                'text': f'Select Date',
                'attachments': request_buttons
            })

        if payload['type'] == 'interactive_message' and payload[
                'callback_id'] == 'day_selector':
            payload_action_value = payload['actions'][0]['value']
            selected_date = payload_action_value.split('_')[0]
            location_id = payload_action_value.split('_')[1]

            period_buttons = [
                # {'name': 'meal_period', 'type': 'button', 'text': 'Breakfast',
                #  'value': 'breakfast_{}'.format(payload_action_value)},
                {
                    'name': 'meal_period',
                    'type': 'button',
                    'text': 'Lunch',
                    'value': 'lunch_{}'.format(payload_action_value)
                }
            ]

            request_buttons = [{
                "text": "",
                "callback_id": "period_selector",
                "color": "#3AA3E3",
                "attachment_type": "default",
                "actions": period_buttons
            }]

            return self.handle_response(slack_response={
                'text': f'Select Meal Period',
                'attachments': request_buttons
            })

        if payload['type'] == 'interactive_message' and payload[
                'callback_id'] == 'period_selector':
            period = payload['actions'][0]['value'].split('_')[0]
            date = payload['actions'][0]['value'].split('_')[1]
            location_id = payload['actions'][0]['value'].split('_')[2]
            actions = {
                "attachments": [{
                    "text":
                    'What do you want to do?',
                    "callback_id":
                    "action_selector",
                    "color":
                    "#3AA3E3",
                    "attachment_type":
                    "default",
                    "actions": [{
                        "name": "main meal",
                        "text": "View Menu List",
                        "type": "button",
                        "value": f'{period}_{date}_menu_{location_id}'
                    }, {
                        "name": "main meal",
                        "text": "Place order",
                        "type": "button",
                        "value": f'{period}_{date}_order_{location_id}'
                    }]
                }]
            }
            return self.handle_response(slack_response=actions)

        if payload['type'] == 'interactive_message' and payload[
                'callback_id'] == 'action_selector':
            payload_action_value = payload['actions'][0]['value']
            if payload_action_value.split('_')[2] == 'menu':
                date = payload_action_value.split('_')[1]
                period = payload_action_value.split('_')[0]
                location_id = payload_action_value.split('_')[3]
                menus = self.menu_repo.get_unpaginated(date=date,
                                                       meal_period=period,
                                                       is_deleted=False)
                if not menus:
                    #   No Menu for provided date
                    back_buttons = [{
                        'name': 'back',
                        'text': 'Back',
                        'type': "button",
                        'value': location_id
                    }]
                    request_buttons = [{
                        "text": "",
                        "callback_id": "center_selector",
                        "color": "#3AA3E3",
                        "attachment_type": "default",
                        "actions": back_buttons
                    }]
                    return self.handle_response(
                        slack_response={
                            'text':
                            f'Sorry No Menu found for Date: {date}, Meal Period: {period}',
                            'attachments': request_buttons
                        })
                text = ''

                for menu in menus:
                    side_items_list = menu.side_items.split(',')
                    protein_items_list = menu.protein_items.split(',')

                    main = self.meal_repo.get(menu.main_meal_id).name
                    sides = [
                        side.name for side in
                        self.meal_repo.get_meal_items_by_ids(side_items_list)
                    ]
                    proteins = [
                        protein.name
                        for protein in self.meal_repo.get_meal_items_by_ids(
                            protein_items_list)
                    ]
                    menu_info = f'Main meal: *{main}*\n Side items: {", ".join(sides)}\nProtein items: {", ".join(proteins)}\n\n\n'
                    text += menu_info

                meals = {
                    "text":
                    f'{period.upper()}',
                    "attachments": [{
                        "text":
                        text,
                        "callback_id":
                        "after_menu_list",
                        "color":
                        "#3AA3E3",
                        "attachment_type":
                        "default",
                        "actions": [{
                            "name":
                            "main meal",
                            "text":
                            "Rate meal",
                            "type":
                            "button",
                            "value":
                            f'{period}_{date}_rate_{location_id}_{location_id}'
                        }, {
                            "name":
                            "main meal",
                            "text":
                            "Place an order",
                            "type":
                            "button",
                            "value":
                            f'{period}_{date}_order_{location_id}_{location_id}'
                        }]
                    }]
                }
                return self.handle_response(slack_response=meals)

        if (payload['type'] == 'interactive_message'
                and payload['callback_id'] == 'action_selector'
                and payload['actions'][0]['value'].split('_')[2] == 'order'
            ) or (payload['callback_id'] == 'after_menu_list'
                  and payload['actions'][0]['value'].split('_')[2] == 'order'):
            payload_action_value = payload['actions'][0]['value']
            meal_period = payload_action_value.split('_')[0]
            selected_date = payload_action_value.split('_')[1]
            location_id = payload_action_value.split('_')[3]
            menus = self.menu_repo.get_unpaginated(date=selected_date,
                                                   meal_period=meal_period,
                                                   is_deleted=False)
            if not menus:
                #   No Menu for provided date
                back_buttons = [{
                    'name': 'back',
                    'text': 'Back',
                    'type': "button",
                    'value': location_id
                }]

                request_buttons = [{
                    "text": "",
                    "callback_id": "center_selector",
                    "color": "#3AA3E3",
                    "attachment_type": "default",
                    "actions": back_buttons
                }]
                return self.handle_response(
                    slack_response={
                        'text':
                        f'Sorry No Menu found for Date: {selected_date}, Meal Period: {meal_period}',
                        'attachments': request_buttons
                    })

            meal_buttons = [{
                'name': 'main_meal',
                'type': 'button',
                'text': f'{menu.main_meal.name}',
                'value': f'{menu.id}_{payload_action_value}'
            } for menu in menus]

            request_buttons = [{
                "text": "",
                "callback_id": "meal_action_selector",
                "color": "#3AA3E3",
                "attachment_type": "default",
                "actions": meal_buttons
            }]

            return self.handle_response(slack_response={
                'text': 'Select Main Meal',
                'attachments': request_buttons
            })

        if payload['type'] == 'interactive_message' and payload[
                'callback_id'] == 'meal_action_selector':
            payload_action_value = payload['actions'][0]['value']
            if payload_action_value.find('order') > -1:
                menu_id = payload_action_value.split('_')[0]
                menu = self.menu_repo.get(menu_id)
                slack_id = payload['user']['id']
                slack_user_info = self.slackhelper.user_info(slack_id)
                slack_user_email = slack_user_info['user']['profile']['email']
                user = self.andela_service.get_user_by_email_or_id(
                    slack_user_email)

                # check if user already has an order
                if OrderRepo().user_has_order(user['id'],
                                              menu.date.strftime('%Y-%m-%d'),
                                              menu.meal_period):
                    slack_data = {
                        'text':
                        'You already have an order for this meal period.'
                    }
                    requests.post(webhook_url,
                                  data=json.dumps(slack_data),
                                  headers={'Content-Type': 'application/json'})
                    return self.handle_response(status_code=400)
                trigger_id = payload['trigger_id']

                side_items_list = menu.side_items.split(',')
                protein_items_list = menu.protein_items.split(',')

                side_items = self.meal_repo.get_meal_items_by_ids(
                    side_items_list)
                protein_items = self.meal_repo.get_meal_items_by_ids(
                    protein_items_list)

                request_dialog_element = []

                for i in range(1, menu.allowed_side + 1):
                    request_dialog_element.append({
                        'label':
                        f'Select Side {i}',
                        'type':
                        'select',
                        'name':
                        f'side_{i}',
                        'options': [{
                            'label': f'{side.name}',
                            'value': f'{side.id}'
                        } for side in side_items]
                    })

                for i in range(1, menu.allowed_protein + 1):
                    request_dialog_element.append({
                        'label':
                        f'Select Protein {i}',
                        'type':
                        'select',
                        'name':
                        f'protein_{i}',
                        'options': [{
                            'label': f'{protein.name}',
                            'value': f'{protein.id}'
                        } for protein in protein_items]
                    })

                state = f'{payload_action_value}'
                self.create_dialog(dialog_elem=request_dialog_element,
                                   trigger_id=trigger_id,
                                   title='Select Protein & Sides',
                                   callback_id='final_selection',
                                   state=state)

                return self.handle_response(
                    slack_response={'text': 'Select Meal Protein and Sides'})

        if payload['callback_id'] == 'after_menu_list' and payload['actions'][
                0]['value'].split('_')[2] == 'rate':

            payload_action_value = payload['actions'][0]['value']
            meal_period = payload_action_value.split('_')[0]
            selected_date = payload_action_value.split('_')[1]
            location_id = payload_action_value.split('_')[2]
            menus = self.menu_repo.get_unpaginated(date=selected_date,
                                                   meal_period=meal_period,
                                                   is_deleted=False)
            if not menus:
                #   No Menu for provided date
                back_buttons = [{
                    'name': 'back',
                    'text': 'Back',
                    'type': "button",
                    'value': location_id
                }]

                request_buttons = [{
                    "text": "",
                    "callback_id": "center_selector",
                    "color": "#3AA3E3",
                    "attachment_type": "default",
                    "actions": back_buttons
                }]
                return self.handle_response(
                    slack_response={
                        'text':
                        f'Sorry No Menu found forr Date: {selected_date}, Meal Period: {meal_period}',
                        'attachments': request_buttons
                    })

            meal_buttons = [{
                'name': 'main_meal',
                'type': 'button',
                'text': f'{menu.main_meal.name}',
                'value': f'{menu.id}_{payload_action_value}'
            } for menu in menus]

            request_buttons = [{
                "text": "",
                "callback_id": "rating_selector",
                "color": "#3AA3E3",
                "attachment_type": "default",
                "actions": meal_buttons
            }]

            return self.handle_response(slack_response={
                'text': 'Select Main Meal',
                'attachments': request_buttons
            })

        if payload['callback_id'] == 'rating_selector':

            menu_id = payload['actions'][0]['value'].split('_')[0]
            menu = self.menu_repo.get(menu_id)
            trigger_id = payload['trigger_id']
            main_meal = menu.main_meal_id

            request_dialog_element = [{
                'label':
                f'Rate meal: {self.meal_repo.get(main_meal).name}',
                'type':
                'select',
                'name':
                'rating value',
                'options': [{
                    'label': f'{value}',
                    'value': f'{value}'
                } for value in range(1, 6)]
            }, {
                'label': 'Add a short comment',
                'type': 'text',
                'name': 'comment'
            }]

            state = f'{payload["actions"][0]["value"]}'
            self.create_dialog(dialog_elem=request_dialog_element,
                               trigger_id=trigger_id,
                               title='Rate a meal',
                               callback_id='submit_rating',
                               state=state)

            return self.handle_response(slack_response={'text': 'Meal rating'})

    def create_dialog(self,
                      dialog_elem,
                      trigger_id,
                      title,
                      callback_id,
                      state=None):
        dialog = {
            "title": title,
            "submit_label": "Submit",
            "callback_id": callback_id,
            "notify_on_cancel": True,
            "state": state,
            "elements": dialog_elem
        }
        return self.slackhelper.dialog(dialog=dialog, trigger_id=trigger_id)

    @staticmethod
    def get_menu_start_end_on(location):
        """This method takes a location id, and attempts to return a start date and an end date based on the conditions
        the application expects.

        Conditions:
            If current datetime is over 3PM , skip a day and return next days.
            If day is thursday and not yet 3PM, return only friday
            If current datetime is friday, saturday or sunday, return next week from monday till friday.
            If No conditions matches, return None for both dates.

        """
        start_on = end_on = None

        current_date = current_time_by_zone(location.zone)

        if current_date.strftime('%a') == 'Mon' and int(
                current_date.strftime('%H')) >= 15:
            start_on = current_date + timedelta(days=2)
            end_on = start_on + timedelta(days=2)

        elif current_date.strftime('%a') == 'Tue' and int(
                current_date.strftime('%H')) >= 15:
            start_on = current_date + timedelta(days=2)
            end_on = start_on + timedelta(days=1)

        elif current_date.strftime('%a') == 'Wed' and int(
                current_date.strftime('%H')) >= 15:
            start_on = end_on = current_date + timedelta(days=2)

        elif current_date.strftime('%a') == 'Thu' and int(
                current_date.strftime('%H')) >= 15:
            start_on = end_on = current_date + timedelta(days=4)

        else:

            start_on = current_date + timedelta(days=1)
            if current_date.strftime('%a') == 'Mon':
                end_on = start_on + timedelta(3)
            if current_date.strftime('%a') == 'Tue':
                end_on = start_on + timedelta(2)
            if current_date.strftime('%a') == 'Wed':
                end_on = start_on + timedelta(1)
            if current_date.strftime('%a') == 'Thu':
                end_on = start_on

            else:
                if current_date.strftime('%a') == 'Fri':
                    start_on = current_date + timedelta(days=3)
                    end_on = current_date + timedelta(days=7)

                if current_date.strftime('%a') == 'Sat':
                    start_on = current_date + timedelta(days=2)
                    end_on = current_date + timedelta(days=6)

                if current_date.strftime('%a') == 'Sun':
                    next_day = 1 if int(
                        current_date.strftime('%H')) < 15 else 2
                    start_on = current_date + timedelta(days=next_day)
                    end_on = current_date + timedelta(days=5)

        return tuple((start_on, end_on))
예제 #14
0
    def handle_dialog_submission(self, payload, slack_id, webhook_url):
        slack_user_info = self.slackhelper.user_info(slack_id)
        slack_user_email = slack_user_info['user']['profile']['email']

        if payload['callback_id'] == 'final_selection':

            state = payload['state'].split('_')
            menu_id = state[0]
            meal_period = state[1]
            date_booked_for = state[2]
            location_id = state[4]
            submitted_values = payload['submission']
            meal_items = [int(v) for k, v in submitted_values.items()]
            meal_items.append(MenuRepo().get(menu_id).main_meal_id)
            meal_items = [
                meal
                for meal in MealItemRepo().get_meal_items_by_ids(meal_items)
            ]
            channel = 'slack'

            # Retrieve User Object
            user = self.andela_service.get_user_by_email_or_id(
                slack_user_email)
            user_id = user['id']

            order = OrderRepo().create_order(user_id=user_id,
                                             date_booked_for=date_booked_for,
                                             meal_items=meal_items,
                                             location_id=location_id,
                                             menu_id=menu_id,
                                             channel=channel,
                                             meal_period=meal_period)

            if order:
                slack_data = {'text': 'Booking Confirmed!'}
                requests.post(webhook_url,
                              data=json.dumps(slack_data),
                              headers={'Content-Type': 'application/json'})
            else:
                slack_data = {'text': 'Booking Failed. Please Retry'}
                requests.post(webhook_url,
                              data=json.dumps(slack_data),
                              headers={'Content-Type': 'application/json'})

        if payload['callback_id'] == 'submit_rating':

            state = payload['state'].split('_')
            menu_id = state[0]
            menu = self.menu_repo.get(menu_id)
            service_date = menu.date
            rating_type = RatingType.meal
            type_id = menu.main_meal_id
            engagement_id = menu.vendor_engagement_id
            vendor_id = self.engagement_repo.get(engagement_id).vendor_id
            rating_value = payload['submission']['rating value']
            channel = 'slack'
            comment = payload['submission']['comment']

            # Retrieve User Object
            user = self.andela_service.get_user_by_email_or_id(
                slack_user_email)
            user_id = user['id']

            rating = self.vendor_rating_repo.new_rating(
                vendor_id, user_id, rating_value, service_date, rating_type,
                type_id, engagement_id, menu_id, channel, comment)

            if rating:
                slack_data = {'text': 'Rating Successful!'}
                requests.post(webhook_url,
                              data=json.dumps(slack_data),
                              headers={'Content-Type': 'application/json'})
            else:
                slack_data = {'text': 'Rating Failed. Please Retry'}
                requests.post(webhook_url,
                              data=json.dumps(slack_data),
                              headers={'Content-Type': 'application/json'})

        return make_response('', 200)