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
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()
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
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
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