consent.lua 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. -- TODO: NEEDS TO BE REWRITTEN AS A LIBRARY NOT A MODULE
  2. modpol.orgs.consent = {}
  3. -- sets consent to its own callback
  4. modpol.orgs.consent.__index = modpol.orgs.consent
  5. function temp_consent_process()
  6. return {
  7. type = "consent",
  8. id = nil,
  9. org_id = nil,
  10. request_id = nil,
  11. total_votes = 0,
  12. majority_to_pass = 0.51,
  13. votes_needed = nil,
  14. votes_yes = {},
  15. votes_no = {}
  16. }
  17. end
  18. -- ===============================================
  19. -- function to create a new consent process to resolve a pending process
  20. function modpol.orgs.consent:new_process(id, request_id, org_id)
  21. local process = temp_consent_process()
  22. process.id = id
  23. process.request_id = request_id
  24. process.org_id = org_id
  25. setmetatable(process, modpol.orgs.consent)
  26. modpol.ocutil.log('Created new process #' .. id .. ' for request id #' .. request_id)
  27. local p_org = modpol.orgs.get_org(org_id)
  28. for i, member in ipairs(p_org.members) do
  29. p_org:add_pending_action(id, member)
  30. end
  31. process.votes_needed = math.ceil(process.majority_to_pass * p_org:get_member_count())
  32. return process
  33. end
  34. -- ============================
  35. -- interact function for the consent module
  36. -- input: user (string)
  37. function modpol.orgs.consent:interact(user)
  38. -- TODO this needs more context on the vote at hand
  39. modpol.interactions.binary_poll_user(
  40. user, "Do you consent?",
  41. function(vote)
  42. if vote == 'Yes' then
  43. self:approve(user, true)
  44. elseif vote == 'No' then
  45. self:approve(user, false)
  46. end
  47. end)
  48. end
  49. -- ======================================================
  50. -- function for users to vote on a pending request
  51. function modpol.orgs.consent:approve(user, decision)
  52. if not modpol.orgs.get_org(self.org_id):has_member(user) then
  53. modpol.ocutil.log('Error in consent:approve -> user not a member of the org')
  54. return
  55. end
  56. if decision then
  57. table.insert(self.votes_yes, user)
  58. modpol.ocutil.log('User ' .. user .. ' voted yes on request #' .. self.request_id)
  59. else
  60. table.insert(self.votes_no, user)
  61. modpol.ocutil.log('User ' .. user .. ' voted no on request #' .. self.request_id)
  62. end
  63. self.total_votes = self.total_votes + 1
  64. local p_org = modpol.orgs.get_org(self.org_id)
  65. p_org:remove_pending_action(self.id, user)
  66. self:update_status()
  67. end
  68. -- ===================================================
  69. -- determines whether process has finished and resolves request if it has (unfinished)
  70. function modpol.orgs.consent:update_status()
  71. local process_org = modpol.orgs.get_org(self.org_id)
  72. if #self.votes_yes >= self.votes_needed then
  73. modpol.ocutil.log('Request #' .. self.request_id .. ' passes')
  74. process_org:resolve_request(self.request_id, true)
  75. elseif #self.votes_no >= self.votes_needed then
  76. modpol.ocutil.log('Request #' .. self.request_id .. ' fails to pass')
  77. process_org:resolve_request(self.request_id, false)
  78. else
  79. modpol.ocutil.log('Waiting for more votes...')
  80. end
  81. end