Exemplo n.º 1
0
    def prepare_debts_list(self, debts):
        attachments = []
        for debt in debts:
            user = self.user_service.get_user_by_id(debt.user_id)
            phone_text = "\nPay with BLIK using phone number: *" + user.phone + "*" if user.phone else ''

            actions = []
            debt_text = "You owe " + str(
                debt.debt) + " PLN for " + get_user_name(user) + phone_text
            if debt.debt < 0:
                actions.append(
                    Action(name="debt-pay",
                           text="I just paid " + str(-debt.debt) + " PLN",
                           type="button",
                           value="pay-" + str(debt.user_id)))
                debt_text = "You owe " + str(
                    -debt.debt) + " PLN for " + get_user_name(
                        user) + phone_text
            elif debt.debt > 0:
                debt_text = get_user_name(user) + " owes you " + str(
                    debt.debt) + " PLN"

            attachments.append(
                Attachment(callback_id=string_helper.get_full_class_name(
                    FoodOrderPayload),
                           attachment_type="default",
                           text=debt_text,
                           color="#3AA3E3",
                           actions=actions).dump())
        return attachments
Exemplo n.º 2
0
    def order_checkout(self, command_body, arguments: list, action):
        user = self.get_user_by_slack_user_id(command_body['user_id'])
        reminder = self.food_order_service.checkout_order(
            user, datetime.today(), command_body['channel_name'])
        self.cancel_reminder(command_body, reminder)

        if not reminder:
            self.logger.warning(
                "User {} can't check out order for this channel".format(
                    user.username))
            self.slack_client.api_call(
                "chat.postEphemeral",
                channel=command_body['channel_name'],
                user=user.slack_user_id,
                text=
                "You can't check out order for this channel. Are you order owner?"
            )
            return

        order_items: [FoodOrderItem
                      ] = self.food_order_service.get_food_order_items_by_date(
                          user, datetime.today(), command_body['channel_name'])
        order_items_text = ''
        total_order_cost = Decimal(0.0)
        if order_items:
            for order_item in order_items:
                eating_user = self.user_service.get_user_by_id(
                    order_item.eating_user_id)
                order_items_text += get_user_name(
                    eating_user) + " - " + order_item.description + " (" + str(
                        order_item.cost) + " PLN)\n"
                total_order_cost += order_item.cost
            order_items_text += "\nTotal cost: " + str(
                total_order_cost) + " PLN"

        if total_order_cost == Decimal(0):
            self.slack_client.api_call(
                "chat.postMessage",
                channel=command_body['channel_name'],
                mrkdwn=True,
                attachments=[
                    Attachment(
                        attachment_type="default",
                        text=str(
                            "*{} checked out order. No orders for today.*".
                            format(get_user_name(user))),
                        color="#3AA3E3").dump()
                ])
        else:
            self.slack_client.api_call(
                "chat.postMessage",
                channel=command_body['channel_name'],
                mrkdwn=True,
                attachments=[
                    Attachment(attachment_type="default",
                               text=str("*{} checked out order:*\n" +
                                        order_items_text).format(
                                            get_user_name(user)),
                               color="#3AA3E3").dump()
                ])
    def handle(self, payload: ProjectAddPayload):

        if payload.submission:
            new_project_name: str = payload.submission.project_name
            self.project_service.create_project(new_project_name)

            self.send_message_to_client(payload.user.id,
                                        "New project *{0}* has been successfully created!".format(new_project_name))

        else:
            action: str = next(iter(payload.actions))
            action_name = action.split(":")[0]
            sub_action = action.split(":")[1]

            if action.startswith('projects_list'):
                # handle dialog with user selection
                project_id = payload.actions[action].selected_options[0].value
                users = []
                if sub_action == "unassign":
                    users = self.user_service.get_users_assigned_for_project(project_id)
                elif sub_action == "assign":
                    users = self.user_service.get_users_not_assigned_for_project(project_id)

                if not users:
                    return Message(text="There is no users to {0} :neutral_face:".format(sub_action),
                                   response_type="ephemeral", mrkdwn=True).dump()

                user_options_list = [TextSelectOption(string_helper.get_user_name(p), p.user_id) for p in users]

                return ProjectCommandHandler.create_select_user_message(sub_action, str(project_id),
                                                                        user_options_list).dump()

            elif action_name.startswith('assign'):
                # handle assign user to project
                project = self.project_service.get_project_by_id(sub_action)
                user = self.user_service.get_user_by_id(payload.actions[action].selected_options[0].value)

                self.project_service.assign_user_to_project(project=project, user=user)

                return Message(text="User *{0}* has been successfully assigned for project *{1}* :grinning:"
                               .format(string_helper.get_user_name(user), project.name),
                               response_type="ephemeral", mrkdwn=True).dump()

            elif action_name.startswith('unassign'):
                # handle unassign user to project
                project = self.project_service.get_project_by_id(sub_action)
                user = self.user_service.get_user_by_id(payload.actions[action].selected_options[0].value)

                self.project_service.unassign_user_from_project(project=project, user=user)

                return Message(text="User *{0}* has been successfully unassigned from project *{1}*"
                                        .format(string_helper.get_user_name(user), project.name),
                                        response_type="ephemeral", mrkdwn=True).dump()
Exemplo n.º 4
0
    def order_start(self, command_body, arguments: list, action):
        if len(arguments) == 0:
            return "Use format: */ni food _URL_*"

        ordering_link = arguments[0]
        user = self.get_user_by_slack_user_id(command_body['user_id'])

        self.food_order_service.remove_incomplete_food_order_items(
            datetime.today(), command_body['channel_name'])

        post_at: int = round(
            (datetime.now() + CHECKOUT_REMINDER_IN).timestamp())
        reminder_response = self.slack_client.api_call(
            "chat.scheduleMessage",
            channel=command_body['channel_name'],
            user=user.slack_user_id,
            post_at=post_at,
            text=
            "@{} Looks like you forgot to order from {}.\nUrge your friends to place an order and call */ni order*"
            .format(command_body['user_name'], ordering_link),
            link_names=True)
        if not reminder_response["ok"]:
            self.logger.error(reminder_response)
            raise RuntimeError('failed')

        scheduled_message_id = reminder_response['scheduled_message_id']
        order = self.food_order_service.create_food_order(
            user, datetime.today(), ordering_link, scheduled_message_id,
            command_body['channel_name'])
        self.logger.info("Created order %d for user %s with reminder %s",
                         order.food_order_id, command_body['user_name'],
                         scheduled_message_id)

        order_prompt_response = self.slack_client.api_call(
            "chat.postMessage",
            channel=command_body['channel_name'],
            mrkdwn=True,
            as_user=True,
            attachments=[
                Attachment(
                    callback_id=string_helper.get_full_class_name(
                        FoodOrderPayload),
                    attachment_type="default",
                    text=get_user_name(user) + " orders from " + ordering_link,
                    color="#3AA3E3",
                    actions=[
                        Action(name="order-prompt",
                               text="I'm ordering right now",
                               type="button",
                               value="order-" + str(order.food_order_id)),
                        Action(name="order-prompt",
                               text="Not today",
                               type="button",
                               value="pas-" + str(order.food_order_id)),
                    ]).dump()
            ])
        if not order_prompt_response["ok"]:
            self.logger.error(order_prompt_response)
            raise RuntimeError('failed')
        return None
Exemplo n.º 5
0
    def handle(self, payload: Payload):
        if 'debt-pay' in payload.actions and payload.actions[
                'debt-pay'].value.startswith('pay-'):
            settled_user = self.user_service.get_user_by_id(
                payload.actions['debt-pay'].value.replace("pay-", ""))
            user = self.user_service.get_user_by_slack_id(payload.user.id)

            self.food_order_service.pay_debts(user, settled_user)

            self.slack_client.api_call(
                "chat.postEphemeral",
                channel=payload.channel.name,
                user=user.slack_user_id,
                mrkdwn=True,
                as_user=True,
                attachments=[
                    Attachment(
                        attachment_type="default",
                        text=
                        "Lannisters always pay their debts. Glad that you too {} :tada:"
                        .format(get_user_name(settled_user)),
                        color="#3AA3E3").dump()
                ])

            self.slack_client.api_call(
                "chat.postEphemeral",
                channel=payload.channel.name,
                mrkdwn=True,
                as_user=True,
                user=settled_user.slack_user_id,
                attachments=[
                    Attachment(
                        attachment_type="default",
                        text="{} paid for you for food :heavy_dollar_sign:".
                        format(get_user_name(user)),
                        color="#3AA3E3").dump()
                ])
        else:
            raise RuntimeError("Unsupported action for food order prompt")
        return False
Exemplo n.º 6
0
 def show_debtors(self, command_body, arguments: list, action):
     debtors_str = "It's time for a dinner.\n"
     debtors = self.food_order_service.top_debtors()
     if debtors:
         debtors_str += "Top debtors are:\n"
     for debtor in debtors:
         debtors_str += "{} has total debt {} PLN\n".format(
             get_user_name(self.user_service.get_user_by_id(debtor[0])),
             debtor[1])
     for channel_name in self.food_order_service.get_all_food_channels(
     ) or []:
         self.slack_client.api_call("chat.postMessage",
                                    channel=channel_name,
                                    mrkdwn=True,
                                    attachments=[
                                        Attachment(
                                            attachment_type="default",
                                            text=str(debtors_str),
                                            color="#ec4444").dump()
                                    ])
    def create_dialog(self, command_body, argument, action) -> Dialog:

        selected_period = None
        if action and len(action.selected_options):
            selected_period = next(iter(action.selected_options), None).value

        start_end = get_start_end_date(selected_period)

        # todo cache it globally e.g. Flask-Cache
        projects = self.project_service.get_projects()
        project_options_list: List[LabelSelectOption] = [LabelSelectOption(label=p.name, value=p.project_id) for p in
                                                         projects]

        # admin see users list
        user = self.get_user_by_slack_user_id(action.name)

        elements: Element = [
            Element(label="Date from", type="text", name='day_from', placeholder="Specify date", value=start_end[0]),
            Element(label="Date to", type="text", name='day_to', placeholder="Specify date", value=start_end[1]),
            Element(label="Project", type="select", name='project', optional='true', placeholder="Select a project",
                    options=project_options_list)
        ]

        dialog: Dialog = Dialog(title="Generate report", submit_label="Generate",
                      callback_id=string_helper.get_full_class_name(ReportGenerateFormPayload), elements=elements)

        if action.name:
            prompted_user = self.get_user_by_slack_user_id(action.name)

        if user.role.role == 'admin':
            users = self.user_service.get_users()
            user_options_list = [LabelSelectOption(label=string_helper.get_user_name(p), value=p.user_id) for p in
                                 users]
            dialog.elements.append(
                Element(label="User", value=(prompted_user.user_id if prompted_user else None),
                        optional='true', type="select", name='user', placeholder="Select user",
                        options=user_options_list))

        return dialog
    def handle(self, payload: ProjectAddPayload):

        if payload.submission:
            new_project_name: str = payload.submission.project_name
            self.project_service.create_project(new_project_name)

            self.send_message_to_client(
                payload.user.id,
                "New project *{0}* has been successfully created!".format(
                    new_project_name))

        else:
            action: str = next(iter(payload.actions))
            action_name = action.split(":")[0]
            sub_action = action.split(":")[1]

            if action.startswith('projects_list'):
                # handle dialog with user selection
                project_id = payload.actions[action].selected_options[0].value
                users = []
                if sub_action == "unassign":
                    users = self.user_service.get_users_assigned_for_project(
                        project_id)
                elif sub_action == "assign":
                    users = self.user_service.get_users_not_assigned_for_project(
                        project_id)

                if not users:
                    return Message(
                        text="There is no users to {0} :neutral_face:".format(
                            sub_action),
                        response_type="ephemeral",
                        mrkdwn=True).dump()

                user_options_list = [
                    TextSelectOption(string_helper.get_user_name(p), p.user_id)
                    for p in users
                ]

                return ProjectCommandHandler.create_select_user_message(
                    sub_action, str(project_id), user_options_list).dump()

            elif action_name.startswith('assign'):
                # handle assign user to project
                project = self.project_service.get_project_by_id(sub_action)
                user = self.user_service.get_user_by_id(
                    payload.actions[action].selected_options[0].value)

                self.project_service.assign_user_to_project(project=project,
                                                            user=user)

                return Message(
                    text=
                    "User *{0}* has been successfully assigned for project *{1}* :grinning:"
                    .format(string_helper.get_user_name(user), project.name),
                    response_type="ephemeral",
                    mrkdwn=True).dump()

            elif action_name.startswith('unassign'):
                # handle unassign user to project
                project = self.project_service.get_project_by_id(sub_action)
                user = self.user_service.get_user_by_id(
                    payload.actions[action].selected_options[0].value)

                self.project_service.unassign_user_from_project(
                    project=project, user=user)

                return Message(
                    text=
                    "User *{0}* has been successfully unassigned from project *{1}*"
                    .format(string_helper.get_user_name(user), project.name),
                    response_type="ephemeral",
                    mrkdwn=True).dump()
    def create_dialog(self, command_body, argument, action) -> Dialog:

        selected_period = None
        if action and len(action.selected_options):
            selected_period = next(iter(action.selected_options), None).value

        start_end = get_start_end_date(selected_period)

        # todo cache it globally e.g. Flask-Cache
        projects = self.project_service.get_projects()
        project_options_list: List[LabelSelectOption] = [
            LabelSelectOption(label=p.name, value=p.project_id)
            for p in projects
        ]

        # admin see users list
        user = self.get_user_by_slack_user_id(action.name)

        elements: Element = [
            Element(label="Date from",
                    type="text",
                    name='day_from',
                    placeholder="Specify date",
                    value=start_end[0]),
            Element(label="Date to",
                    type="text",
                    name='day_to',
                    placeholder="Specify date",
                    value=start_end[1]),
            Element(label="Project",
                    type="select",
                    name='project',
                    optional='true',
                    placeholder="Select a project",
                    options=project_options_list)
        ]

        dialog: Dialog = Dialog(title="Generate report",
                                submit_label="Generate",
                                callback_id=string_helper.get_full_class_name(
                                    ReportGenerateFormPayload),
                                elements=elements)

        if action.name:
            prompted_user = self.get_user_by_slack_user_id(action.name)

        if user.role.role == 'admin':
            users = self.user_service.get_users()
            user_options_list = [
                LabelSelectOption(label=string_helper.get_user_name(p),
                                  value=p.user_id) for p in users
            ]
            dialog.elements.append(
                Element(
                    label="User",
                    value=(prompted_user.user_id if prompted_user else None),
                    optional='true',
                    type="select",
                    name='user',
                    placeholder="Select user",
                    options=user_options_list))

        return dialog