/custom/icds/rules/custom_actions.py

https://github.com/dimagi/commcare-hq · Python · 125 lines · 103 code · 22 blank · 0 comment · 9 complexity · e35bc56cd90bb596b1f770056a26b3ba MD5 · raw file

  1. import pytz
  2. import uuid
  3. from casexml.apps.case.mock import CaseBlock
  4. from corehq.apps.data_interfaces.models import CaseRuleActionResult, AUTO_UPDATE_XMLNS
  5. from corehq.apps.hqcase.utils import submit_case_blocks, update_case
  6. from corehq.apps.users.util import SYSTEM_USER_ID
  7. from corehq.util.timezones.conversions import ServerTime
  8. from datetime import datetime
  9. from xml.etree import cElementTree as ElementTree
  10. def _create_tech_issue_delegate_for_escalation(tech_issue, owner_id):
  11. case_id = uuid.uuid4().hex
  12. caseblock = CaseBlock(
  13. case_id,
  14. case_type='tech_issue_delegate',
  15. create=True,
  16. update={'change_in_level': '1'},
  17. user_id=SYSTEM_USER_ID,
  18. owner_id=owner_id,
  19. case_name=tech_issue.name,
  20. index={'parent': (tech_issue.type, tech_issue.case_id, 'child')},
  21. )
  22. return submit_case_blocks(
  23. ElementTree.tostring(caseblock.as_xml()).decode('utf-8'),
  24. tech_issue.domain,
  25. user_id=SYSTEM_USER_ID,
  26. xmlns=AUTO_UPDATE_XMLNS,
  27. device_id=__name__ + "._create_tech_issue_delegate_for_escalation",
  28. )
  29. def _update_existing_tech_issue_delegate(tech_issue_delegate, owner_id):
  30. if tech_issue_delegate.get_case_property('change_in_level') == '1':
  31. change_in_level = '2'
  32. else:
  33. change_in_level = '1'
  34. return update_case(
  35. tech_issue_delegate.domain,
  36. tech_issue_delegate.case_id,
  37. case_properties={'change_in_level': change_in_level},
  38. close=False,
  39. xmlns=AUTO_UPDATE_XMLNS,
  40. device_id=__name__ + "._update_existing_tech_issue_delegate",
  41. owner_id=owner_id,
  42. )
  43. def _update_tech_issue_for_escalation(case, escalated_ticket_level):
  44. today = ServerTime(datetime.utcnow()).user_time(pytz.timezone('Asia/Kolkata')).done().date()
  45. return update_case(
  46. case.domain,
  47. case.case_id,
  48. case_properties={
  49. 'ticket_level': escalated_ticket_level,
  50. 'change_in_level': '1',
  51. 'touch_case_date': today.strftime('%Y-%m-%d'),
  52. },
  53. close=False,
  54. xmlns=AUTO_UPDATE_XMLNS,
  55. device_id=__name__ + "._update_tech_issue_for_escalation",
  56. )
  57. def _get_escalated_tech_issue_delegate(tech_issue, location_id):
  58. for subcase in tech_issue.get_subcases(index_identifier='parent'):
  59. if (
  60. subcase.type == 'tech_issue_delegate' and
  61. subcase.owner_id == location_id and
  62. not subcase.closed
  63. ):
  64. return subcase
  65. return None
  66. def escalate_tech_issue(case, rule):
  67. if case.type != 'tech_issue':
  68. return CaseRuleActionResult()
  69. escalated_ticket_level_map = {
  70. 'supervisor': 'block',
  71. 'block': 'district',
  72. 'district': 'state',
  73. }
  74. current_location_id_map = {
  75. 'supervisor': case.get_case_property('supervisor_location_id'),
  76. 'block': case.get_case_property('block_location_id'),
  77. 'district': case.get_case_property('district_location_id'),
  78. }
  79. escalated_location_id_map = {
  80. 'supervisor': case.get_case_property('block_location_id'),
  81. 'block': case.get_case_property('district_location_id'),
  82. 'district': case.get_case_property('state_location_id'),
  83. }
  84. current_ticket_level = case.get_case_property('ticket_level')
  85. escalated_ticket_level = escalated_ticket_level_map.get(current_ticket_level)
  86. current_location_id = current_location_id_map.get(current_ticket_level)
  87. escalated_location_id = escalated_location_id_map.get(current_ticket_level)
  88. if not escalated_ticket_level or not escalated_location_id:
  89. return CaseRuleActionResult()
  90. update_result = _update_tech_issue_for_escalation(case, escalated_ticket_level)
  91. rule.log_submission(update_result[0].form_id)
  92. num_creates = 0
  93. num_related_updates = 0
  94. tech_issue_delegate = _get_escalated_tech_issue_delegate(case, current_location_id)
  95. if tech_issue_delegate:
  96. delegate_update_result = _update_existing_tech_issue_delegate(tech_issue_delegate, escalated_location_id)
  97. rule.log_submission(delegate_update_result[0].form_id)
  98. num_related_updates = 1
  99. else:
  100. create_result = _create_tech_issue_delegate_for_escalation(case, escalated_location_id)
  101. rule.log_submission(create_result[0].form_id)
  102. num_creates = 1
  103. return CaseRuleActionResult(num_updates=1, num_creates=num_creates, num_related_updates=num_related_updates)