Нет описания

case_tasks_db.py 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. # IRIS Source Code
  2. # Copyright (C) 2021 - Airbus CyberSecurity (SAS)
  3. # ir@cyberactionlab.net
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU Lesser General Public
  7. # License as published by the Free Software Foundation; either
  8. # version 3 of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. # Lesser General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Lesser General Public License
  16. # along with this program; if not, write to the Free Software Foundation,
  17. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. from datetime import datetime
  19. from flask_login import current_user
  20. from sqlalchemy import desc
  21. from sqlalchemy import and_
  22. from app import db
  23. from app.datamgmt.conversions import convert_sort_direction
  24. from app.datamgmt.manage.manage_attribute_db import get_default_custom_attributes
  25. from app.datamgmt.manage.manage_users_db import get_users_list_restricted_from_case
  26. from app.datamgmt.states import update_tasks_state
  27. from app.models.models import CaseTasks
  28. from app.models.models import TaskAssignee
  29. from app.models.cases import Cases
  30. from app.models.models import Comments
  31. from app.models.models import TaskComments
  32. from app.models.models import TaskStatus
  33. from app.models.authorization import User
  34. from app.models.pagination_parameters import PaginationParameters
  35. def get_tasks_status():
  36. return TaskStatus.query.all()
  37. def get_filtered_tasks(case_identifier, pagination_parameters: PaginationParameters):
  38. query = CaseTasks.query.filter(
  39. CaseTasks.task_case_id == case_identifier
  40. ).join(
  41. CaseTasks.status
  42. ).order_by(
  43. desc(TaskStatus.status_name)
  44. )
  45. sort_by = pagination_parameters.get_order_by()
  46. if sort_by is not None:
  47. order_func = convert_sort_direction(pagination_parameters.get_direction())
  48. if hasattr(CaseTasks, sort_by):
  49. query = query.order_by(order_func(getattr(CaseTasks, sort_by)))
  50. return query.paginate(page=pagination_parameters.get_page(), per_page=pagination_parameters.get_per_page(), error_out=False)
  51. def get_tasks_with_assignees(caseid):
  52. tasks = CaseTasks.query.with_entities(
  53. CaseTasks.id.label('task_id'),
  54. CaseTasks.task_uuid,
  55. CaseTasks.task_title,
  56. CaseTasks.task_description,
  57. CaseTasks.task_open_date,
  58. CaseTasks.task_tags,
  59. CaseTasks.task_status_id,
  60. TaskStatus.status_name,
  61. TaskStatus.status_bscolor
  62. ).filter(
  63. CaseTasks.task_case_id == caseid
  64. ).join(
  65. CaseTasks.status
  66. ).order_by(
  67. desc(TaskStatus.status_name)
  68. ).all()
  69. if not tasks:
  70. return None
  71. tasks = [c._asdict() for c in tasks]
  72. task_with_assignees = []
  73. for task in tasks:
  74. task_id = task['task_id']
  75. get_assignee_list = TaskAssignee.query.with_entities(
  76. TaskAssignee.task_id,
  77. User.user,
  78. User.id,
  79. User.name
  80. ).join(
  81. TaskAssignee.user
  82. ).filter(
  83. TaskAssignee.task_id == task_id
  84. ).all()
  85. assignee_list = {}
  86. for member in get_assignee_list:
  87. if member.task_id not in assignee_list:
  88. assignee_list[member.task_id] = [{
  89. 'user': member.user,
  90. 'name': member.name,
  91. 'id': member.id
  92. }]
  93. else:
  94. assignee_list[member.task_id].append({
  95. 'user': member.user,
  96. 'name': member.name,
  97. 'id': member.id
  98. })
  99. task['task_assignees'] = assignee_list.get(task['task_id'], [])
  100. task_with_assignees.append(task)
  101. return task_with_assignees
  102. def get_task(task_id: int) -> CaseTasks:
  103. return CaseTasks.query.filter(CaseTasks.id == task_id).first()
  104. def get_task_assignees(task_identifier: int):
  105. get_assignee_list = TaskAssignee.query.with_entities(
  106. TaskAssignee.task_id,
  107. User.user,
  108. User.id,
  109. User.name
  110. ).join(
  111. TaskAssignee.user
  112. ).filter(
  113. TaskAssignee.task_id == task_identifier
  114. ).all()
  115. assignee_list = {}
  116. for member in get_assignee_list:
  117. if member.task_id not in assignee_list:
  118. assignee_list[member.task_id] = [{
  119. 'user': member.user,
  120. 'name': member.name,
  121. 'id': member.id
  122. }]
  123. else:
  124. assignee_list[member.task_id].append({
  125. 'user': member.user,
  126. 'name': member.name,
  127. 'id': member.id
  128. })
  129. return assignee_list.get(task_identifier, [])
  130. def update_task_status(task_status, task_id, caseid):
  131. task = get_task(task_id)
  132. if task:
  133. try:
  134. task.task_status_id = task_status
  135. update_tasks_state(caseid=caseid)
  136. db.session.commit()
  137. return True
  138. except:
  139. return False
  140. else:
  141. return False
  142. def update_task_assignees(task_identifier, task_assignee_list, caseid):
  143. cur_assignee_list = TaskAssignee.query.with_entities(
  144. TaskAssignee.user_id
  145. ).filter(TaskAssignee.task_id == task_identifier).all()
  146. # Some formatting
  147. set_cur_assignees = set([assignee[0] for assignee in cur_assignee_list])
  148. set_assignees = set(int(assignee) for assignee in task_assignee_list)
  149. assignees_to_add = set_assignees - set_cur_assignees
  150. assignees_to_remove = set_cur_assignees - set_assignees
  151. allowed_users = [u.get('user_id') for u in get_users_list_restricted_from_case(caseid)]
  152. for uid in assignees_to_add:
  153. if uid not in allowed_users:
  154. continue
  155. user = User.query.filter(User.id == uid).first()
  156. if user:
  157. ta = TaskAssignee()
  158. ta.task_id = task_identifier
  159. ta.user_id = user.id
  160. db.session.add(ta)
  161. for uid in assignees_to_remove:
  162. TaskAssignee.query.filter(
  163. and_(TaskAssignee.task_id == task_identifier,
  164. TaskAssignee.user_id == uid)
  165. ).delete()
  166. db.session.commit()
  167. def add_task(task, assignee_id_list, user_id, caseid):
  168. now = datetime.now()
  169. task.task_case_id = caseid
  170. task.task_userid_open = user_id
  171. task.task_userid_update = user_id
  172. task.task_open_date = now
  173. task.task_last_update = now
  174. task.custom_attributes = task.custom_attributes if task.custom_attributes else get_default_custom_attributes('task')
  175. db.session.add(task)
  176. update_tasks_state(caseid=caseid)
  177. db.session.commit()
  178. update_task_status(task.task_status_id, task.id, caseid)
  179. update_task_assignees(task.id, assignee_id_list, caseid)
  180. return task
  181. def get_case_task_comments(task_id):
  182. return Comments.query.filter(
  183. TaskComments.comment_task_id == task_id
  184. ).join(
  185. TaskComments,
  186. Comments.comment_id == TaskComments.comment_id
  187. ).order_by(
  188. Comments.comment_date.asc()
  189. ).all()
  190. def add_comment_to_task(task_id, comment_id):
  191. ec = TaskComments()
  192. ec.comment_task_id = task_id
  193. ec.comment_id = comment_id
  194. db.session.add(ec)
  195. db.session.commit()
  196. def get_case_tasks_comments_count(tasks_list):
  197. return TaskComments.query.filter(
  198. TaskComments.comment_task_id.in_(tasks_list)
  199. ).with_entities(
  200. TaskComments.comment_task_id,
  201. TaskComments.comment_id
  202. ).group_by(
  203. TaskComments.comment_task_id,
  204. TaskComments.comment_id
  205. ).all()
  206. def get_case_task_comment(task_id, comment_id):
  207. return TaskComments.query.filter(
  208. TaskComments.comment_task_id == task_id,
  209. TaskComments.comment_id == comment_id
  210. ).with_entities(
  211. Comments.comment_id,
  212. Comments.comment_text,
  213. Comments.comment_date,
  214. Comments.comment_update_date,
  215. Comments.comment_uuid,
  216. User.name,
  217. User.user
  218. ).join(
  219. TaskComments.comment
  220. ).join(
  221. Comments.user
  222. ).first()
  223. def delete_task(task_id):
  224. with db.session.begin_nested():
  225. TaskAssignee.query.filter(
  226. TaskAssignee.task_id == task_id
  227. ).delete()
  228. com_ids = TaskComments.query.with_entities(
  229. TaskComments.comment_id
  230. ).filter(
  231. TaskComments.comment_task_id == task_id
  232. ).all()
  233. com_ids = [c.comment_id for c in com_ids]
  234. TaskComments.query.filter(TaskComments.comment_id.in_(com_ids)).delete()
  235. Comments.query.filter(Comments.comment_id.in_(com_ids)).delete()
  236. CaseTasks.query.filter(
  237. CaseTasks.id == task_id
  238. ).delete()
  239. def delete_task_comment(task_id, comment_id):
  240. comment = Comments.query.filter(
  241. Comments.comment_id == comment_id,
  242. Comments.comment_user_id == current_user.id
  243. ).first()
  244. if not comment:
  245. return False, "You are not allowed to delete this comment"
  246. TaskComments.query.filter(
  247. TaskComments.comment_task_id == task_id,
  248. TaskComments.comment_id == comment_id
  249. ).delete()
  250. db.session.delete(comment)
  251. db.session.commit()
  252. return True, "Comment deleted"
  253. def get_tasks_cases_mapping(open_cases_only=False):
  254. condition = Cases.close_date == None if open_cases_only else True
  255. return CaseTasks.query.filter(
  256. condition
  257. ).with_entities(
  258. CaseTasks.task_case_id,
  259. CaseTasks.task_status_id
  260. ).join(
  261. CaseTasks.case
  262. ).all()