| rev | line source | 
| bsw/jbe@0 | 1 Issue = mondelefant.new_class() | 
| bsw/jbe@0 | 2 Issue.table = 'issue' | 
| bsw/jbe@0 | 3 | 
| bsw@549 | 4 local new_selector = Issue.new_selector | 
| bsw@549 | 5 | 
| bsw@549 | 6 function Issue:new_selector() | 
| bsw@549 | 7   local selector = new_selector(self) | 
| bsw@549 | 8   selector:add_field("coalesce(issue.fully_frozen + issue.voting_time, issue.half_frozen + issue.verification_time, issue.accepted + issue.discussion_time, issue.created + issue.admission_time) - now()", "state_time_left") | 
| bsw@549 | 9   return selector | 
| bsw@549 | 10 end | 
| bsw@549 | 11 | 
| bsw/jbe@0 | 12 Issue:add_reference{ | 
| bsw/jbe@0 | 13   mode          = 'm1', | 
| bsw/jbe@0 | 14   to            = "Area", | 
| bsw/jbe@0 | 15   this_key      = 'area_id', | 
| bsw/jbe@0 | 16   that_key      = 'id', | 
| bsw/jbe@0 | 17   ref           = 'area', | 
| bsw/jbe@0 | 18 } | 
| bsw/jbe@0 | 19 | 
| bsw/jbe@0 | 20 Issue:add_reference{ | 
| bsw/jbe@0 | 21   mode          = 'm1', | 
| bsw/jbe@0 | 22   to            = "Policy", | 
| bsw/jbe@0 | 23   this_key      = 'policy_id', | 
| bsw/jbe@0 | 24   that_key      = 'id', | 
| bsw/jbe@0 | 25   ref           = 'policy', | 
| bsw/jbe@0 | 26 } | 
| bsw/jbe@0 | 27 | 
| bsw/jbe@0 | 28 Issue:add_reference{ | 
| bsw/jbe@0 | 29   mode          = '1m', | 
| bsw/jbe@0 | 30   to            = "Initiative", | 
| bsw/jbe@0 | 31   this_key      = 'id', | 
| bsw/jbe@0 | 32   that_key      = 'issue_id', | 
| bsw/jbe@0 | 33   ref           = 'initiatives', | 
| bsw@551 | 34   back_ref      = 'issue', | 
| bsw@551 | 35   default_order = 'initiative.rank, initiative.supporter_count DESC, id' | 
| bsw/jbe@0 | 36 } | 
| bsw/jbe@0 | 37 | 
| bsw/jbe@0 | 38 Issue:add_reference{ | 
| bsw/jbe@0 | 39   mode          = '1m', | 
| bsw/jbe@0 | 40   to            = "Interest", | 
| bsw/jbe@0 | 41   this_key      = 'id', | 
| bsw/jbe@0 | 42   that_key      = 'issue_id', | 
| bsw/jbe@0 | 43   ref           = 'interests', | 
| bsw/jbe@0 | 44   back_ref      = 'issue', | 
| bsw/jbe@0 | 45   default_order = '"id"' | 
| bsw/jbe@0 | 46 } | 
| bsw/jbe@0 | 47 | 
| bsw/jbe@0 | 48 Issue:add_reference{ | 
| bsw/jbe@0 | 49   mode          = '1m', | 
| bsw/jbe@0 | 50   to            = "Supporter", | 
| bsw/jbe@0 | 51   this_key      = 'id', | 
| bsw/jbe@0 | 52   that_key      = 'issue_id', | 
| bsw/jbe@0 | 53   ref           = 'supporters', | 
| bsw/jbe@0 | 54   back_ref      = 'issue', | 
| bsw/jbe@0 | 55   default_order = '"id"' | 
| bsw/jbe@0 | 56 } | 
| bsw/jbe@0 | 57 | 
| bsw/jbe@0 | 58 Issue:add_reference{ | 
| bsw/jbe@0 | 59   mode          = '1m', | 
| bsw/jbe@0 | 60   to            = "DirectVoter", | 
| bsw/jbe@0 | 61   this_key      = 'id', | 
| bsw/jbe@0 | 62   that_key      = 'issue_id', | 
| bsw/jbe@0 | 63   ref           = 'direct_voters', | 
| bsw/jbe@0 | 64   back_ref      = 'issue', | 
| bsw/jbe@0 | 65   default_order = '"member_id"' | 
| bsw/jbe@0 | 66 } | 
| bsw/jbe@0 | 67 | 
| bsw/jbe@0 | 68 Issue:add_reference{ | 
| bsw/jbe@0 | 69   mode          = '1m', | 
| bsw/jbe@0 | 70   to            = "Vote", | 
| bsw/jbe@0 | 71   this_key      = 'id', | 
| bsw/jbe@0 | 72   that_key      = 'issue_id', | 
| bsw/jbe@0 | 73   ref           = 'votes', | 
| bsw/jbe@0 | 74   back_ref      = 'issue', | 
| bsw/jbe@0 | 75   default_order = '"member_id", "initiative_id"' | 
| bsw/jbe@0 | 76 } | 
| bsw/jbe@0 | 77 | 
| bsw/jbe@0 | 78 Issue:add_reference{ | 
| bsw@2 | 79   mode          = '1m', | 
| bsw@2 | 80   to            = "Delegation", | 
| bsw@2 | 81   this_key      = 'id', | 
| bsw@2 | 82   that_key      = 'issue_id', | 
| bsw@2 | 83   ref           = 'delegations', | 
| bsw@2 | 84   back_ref      = 'issue' | 
| bsw@2 | 85 } | 
| bsw@2 | 86 | 
| bsw@2 | 87 Issue:add_reference{ | 
| bsw/jbe@0 | 88   mode                  = 'mm', | 
| bsw/jbe@0 | 89   to                    = "Member", | 
| bsw/jbe@0 | 90   this_key              = 'id', | 
| bsw/jbe@0 | 91   that_key              = 'id', | 
| bsw/jbe@0 | 92   connected_by_table    = 'interest', | 
| bsw/jbe@0 | 93   connected_by_this_key = 'issue_id', | 
| bsw/jbe@0 | 94   connected_by_that_key = 'member_id', | 
| bsw/jbe@0 | 95   ref                   = 'members' | 
| bsw/jbe@0 | 96 } | 
| bsw/jbe@0 | 97 | 
| bsw@3 | 98 Issue:add_reference{ | 
| bsw@3 | 99   mode                  = 'mm', | 
| bsw@3 | 100   to                    = "Member", | 
| bsw@3 | 101   this_key              = 'id', | 
| bsw@3 | 102   that_key              = 'id', | 
| bsw@3 | 103   connected_by_table    = 'direct_interest_snapshot', | 
| bsw@3 | 104   connected_by_this_key = 'issue_id', | 
| bsw@3 | 105   connected_by_that_key = 'member_id', | 
| bsw@3 | 106   ref                   = 'interested_members_snapshot' | 
| bsw@3 | 107 } | 
| bsw@3 | 108 | 
| bsw/jbe@6 | 109 Issue:add_reference{ | 
| bsw/jbe@6 | 110   mode                  = 'mm', | 
| bsw/jbe@6 | 111   to                    = "Member", | 
| bsw/jbe@6 | 112   this_key              = 'id', | 
| bsw/jbe@6 | 113   that_key              = 'id', | 
| bsw/jbe@6 | 114   connected_by_table    = 'direct_voter', | 
| bsw/jbe@6 | 115   connected_by_this_key = 'issue_id', | 
| bsw/jbe@6 | 116   connected_by_that_key = 'member_id', | 
| bsw/jbe@6 | 117   ref                   = 'direct_voters' | 
| bsw/jbe@6 | 118 } | 
| bsw/jbe@6 | 119 | 
| bsw@525 | 120 Issue:add_reference{ | 
| bsw@525 | 121   mode               = "11", | 
| bsw@525 | 122   to                 = mondelefant.class_prototype, | 
| bsw@525 | 123   this_key           = "id", | 
| bsw@525 | 124   that_key           = "issue_id", | 
| bsw@547 | 125   ref                = "member_info", | 
| bsw@525 | 126   back_ref           = "issue", | 
| bsw@525 | 127   selector_generator = function(list, options) | 
| bsw@547 | 128     assert(options.member_id, "member_id mandatory for member_info") | 
| bsw@525 | 129     local ids = { sep = ", " } | 
| bsw@525 | 130     for i, object in ipairs(list) do | 
| bsw@525 | 131       local id = object.id | 
| bsw@525 | 132       if id ~= nil then | 
| bsw@525 | 133         ids[#ids+1] = {"?", id} | 
| bsw@525 | 134       end | 
| bsw@525 | 135     end | 
| bsw@525 | 136     local sub_selector = Issue:get_db_conn():new_selector() | 
| bsw@525 | 137     if #ids == 0 then | 
| bsw@525 | 138       return sub_selector:empty_list_mode() | 
| bsw@525 | 139     end | 
| bsw@525 | 140     sub_selector:from("issue") | 
| bsw@525 | 141     sub_selector:add_field("issue.id", "issue_id") | 
| bsw@529 | 142     sub_selector:add_field{ '(delegation_info(?, null, null, issue.id, ?)).*', options.member_id, options.trustee_id } | 
| bsw@525 | 143     sub_selector:add_where{ 'issue.id IN ($)', ids } | 
| bsw@525 | 144 | 
| bsw@525 | 145     local selector = Issue:get_db_conn():new_selector() | 
| bsw@547 | 146     selector:add_from("issue") | 
| bsw@547 | 147     selector:join(sub_selector, "delegation_info", "delegation_info.issue_id = issue.id") | 
| bsw@525 | 148     selector:left_join("member", "first_trustee", "first_trustee.id = delegation_info.first_trustee_id") | 
| bsw@525 | 149     selector:left_join("member", "other_trustee", "other_trustee.id = delegation_info.other_trustee_id") | 
| bsw@525 | 150     selector:add_field("delegation_info.*") | 
| bsw@525 | 151     selector:add_field("first_trustee.name", "first_trustee_name") | 
| bsw@525 | 152     selector:add_field("other_trustee.name", "other_trustee_name") | 
| bsw@547 | 153     selector:left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", options.member_id }) | 
| bsw@547 | 154     selector:add_field("direct_voter.member_id NOTNULL", "direct_voted") | 
| bsw@525 | 155     return selector | 
| bsw@525 | 156   end | 
| bsw@525 | 157 } | 
| bsw@525 | 158 | 
| bsw@547 | 159 function Issue.list:load_everything_for_member_id(member_id) | 
| bsw@547 | 160   local areas = self:load("area") | 
| bsw@547 | 161   areas:load("unit") | 
| bsw@547 | 162   self:load("policy") | 
| bsw@551 | 163   if member_id then | 
| bsw@551 | 164     self:load("member_info", { member_id = member_id }) | 
| bsw@551 | 165   end | 
| bsw@551 | 166   local initiatives = self:load("initiatives") | 
| bsw@551 | 167   initiatives:load_everything_for_member_id(member_id) | 
| bsw@525 | 168 end | 
| bsw@525 | 169 | 
| bsw@548 | 170 function Issue.object:load_everything_for_member_id(member_id) | 
| bsw@548 | 171   local areas = self:load("area") | 
| bsw@548 | 172   areas:load("unit") | 
| bsw@548 | 173   self:load("policy") | 
| bsw@551 | 174   if member_id then | 
| bsw@551 | 175     self:load("member_info", { member_id = member_id }) | 
| bsw@551 | 176   end | 
| bsw@551 | 177   local initiatives = self:load("initiatives") | 
| bsw@551 | 178   initiatives:load_everything_for_member_id(member_id) | 
| bsw@548 | 179 end | 
| bsw@548 | 180 | 
| bsw/jbe@0 | 181 function Issue:get_state_name_for_state(value) | 
| bsw@2 | 182   local state_name_table = { | 
| bsw@2 | 183     new          = _"New", | 
| bsw@3 | 184     accepted     = _"Discussion", | 
| bsw@2 | 185     frozen       = _"Frozen", | 
| bsw@2 | 186     voting       = _"Voting", | 
| bsw@2 | 187     finished     = _"Finished", | 
| bsw@2 | 188     cancelled    = _"Cancelled" | 
| bsw@2 | 189   } | 
| bsw@10 | 190   return state_name_table[value] or value or '' | 
| bsw/jbe@0 | 191 end | 
| bsw/jbe@0 | 192 | 
| bsw@2 | 193 function Issue:get_search_selector(search_string) | 
| bsw/jbe@0 | 194   return self:new_selector() | 
| bsw/jbe@0 | 195     :join('"initiative"', nil, '"initiative"."issue_id" = "issue"."id"') | 
| bsw/jbe@6 | 196     :join('"draft"', nil, '"draft"."initiative_id" = "initiative"."id"') | 
| bsw/jbe@6 | 197     :add_where{ '"initiative"."text_search_data" @@ "text_search_query"(?) OR "draft"."text_search_data" @@ "text_search_query"(?)', search_string, search_string } | 
| bsw/jbe@6 | 198     :add_group_by('"issue"."id"') | 
| bsw@481 | 199     :add_group_by('"issue"."state"') | 
| bsw/jbe@6 | 200     :add_group_by('"issue"."area_id"') | 
| bsw/jbe@6 | 201     :add_group_by('"issue"."policy_id"') | 
| bsw/jbe@6 | 202     :add_group_by('"issue"."created"') | 
| bsw/jbe@6 | 203     :add_group_by('"issue"."accepted"') | 
| bsw/jbe@6 | 204     :add_group_by('"issue"."half_frozen"') | 
| bsw/jbe@6 | 205     :add_group_by('"issue"."fully_frozen"') | 
| bsw/jbe@6 | 206     :add_group_by('"issue"."closed"') | 
| bsw/jbe@6 | 207     :add_group_by('"issue"."ranks_available"') | 
| bsw@483 | 208     :add_group_by('"issue"."status_quo_schulze_rank"') | 
| poelzi@140 | 209     :add_group_by('"issue"."cleaned"') | 
| bsw/jbe@6 | 210     :add_group_by('"issue"."snapshot"') | 
| bsw/jbe@6 | 211     :add_group_by('"issue"."latest_snapshot_event"') | 
| bsw/jbe@6 | 212     :add_group_by('"issue"."population"') | 
| bsw/jbe@6 | 213     :add_group_by('"issue"."voter_count"') | 
| bsw@75 | 214     :add_group_by('"issue"."admission_time"') | 
| bsw@75 | 215     :add_group_by('"issue"."discussion_time"') | 
| bsw@75 | 216     :add_group_by('"issue"."verification_time"') | 
| bsw@75 | 217     :add_group_by('"issue"."voting_time"') | 
| bsw/jbe@6 | 218     --:set_distinct() | 
| bsw/jbe@0 | 219 end | 
| bsw/jbe@0 | 220 | 
| bsw@75 | 221 function Issue:modify_selector_for_state(initiatives_selector, state) | 
| bsw@51 | 222   if state == "new" then | 
| bsw@75 | 223     initiatives_selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL") | 
| bsw@51 | 224   elseif state == "accepted" then | 
| bsw@75 | 225     initiatives_selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL") | 
| bsw@51 | 226   elseif state == "frozen" then | 
| bsw@75 | 227     initiatives_selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL AND issue.closed ISNULL") | 
| bsw@51 | 228   elseif state == "voting" then | 
| bsw@75 | 229     initiatives_selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL") | 
| bsw@51 | 230   elseif state == "finished" then | 
| bsw@75 | 231     initiatives_selector:add_where("issue.fully_frozen NOTNULL AND issue.closed NOTNULL") | 
| bsw@51 | 232   elseif state == "cancelled" then | 
| bsw@75 | 233     initiatives_selector:add_where("issue.fully_frozen ISNULL AND issue.closed NOTNULL") | 
| bsw@75 | 234   else | 
| bsw@75 | 235     error("Invalid state") | 
| bsw@51 | 236   end | 
| bsw@51 | 237 end | 
| bsw@51 | 238 | 
| bsw/jbe@0 | 239 function Issue.object_get:state() | 
| bsw/jbe@52 | 240   if self.closed then | 
| bsw/jbe@52 | 241     if self.fully_frozen then | 
| bsw/jbe@5 | 242       return "finished" | 
| bsw/jbe@0 | 243     else | 
| bsw/jbe@52 | 244       return "cancelled" | 
| bsw/jbe@0 | 245     end | 
| bsw/jbe@52 | 246   elseif self.fully_frozen then | 
| bsw/jbe@52 | 247     return "voting" | 
| bsw/jbe@52 | 248   elseif self.half_frozen then | 
| bsw/jbe@52 | 249     return "frozen" | 
| bsw/jbe@52 | 250   elseif self.accepted then | 
| bsw/jbe@52 | 251     return "accepted" | 
| bsw/jbe@0 | 252   else | 
| bsw/jbe@52 | 253     return "new" | 
| bsw/jbe@0 | 254   end | 
| bsw/jbe@52 | 255 | 
| bsw@2 | 256 end | 
| bsw@2 | 257 | 
| bsw@2 | 258 function Issue.object_get:state_name() | 
| bsw@2 | 259   return Issue:get_state_name_for_state(self.state) | 
| bsw@2 | 260 end | 
| bsw@2 | 261 | 
| bsw@2 | 262 function Issue.object_get:next_states() | 
| bsw@2 | 263   local state = self.state | 
| bsw@2 | 264   local next_states | 
| bsw@2 | 265   if state == "new" then | 
| bsw@2 | 266     next_states = { "accepted", "cancelled" } | 
| bsw@2 | 267   elseif state == "accepted" then | 
| bsw@2 | 268     next_states = { "frozen" } | 
| bsw@2 | 269   elseif state == "frozen" then | 
| bsw@2 | 270     next_states = { "voting" } | 
| bsw@2 | 271   elseif state == "voting" then | 
| bsw@2 | 272     next_states = { "finished" } | 
| bsw@2 | 273   end | 
| bsw@2 | 274   return next_states | 
| bsw@2 | 275 end | 
| bsw@2 | 276 | 
| bsw@2 | 277 function Issue.object_get:next_states_names() | 
| bsw@2 | 278   local next_states = self.next_states | 
| bsw@2 | 279   if not next_states then | 
| bsw@2 | 280     return | 
| bsw@2 | 281   end | 
| bsw@2 | 282   local state_names = {} | 
| bsw@2 | 283   for i, state in ipairs(self.next_states) do | 
| bsw@2 | 284     state_names[#state_names+1] = Issue:get_state_name_for_state(state) | 
| bsw@2 | 285   end | 
| bsw@2 | 286   return table.concat(state_names, ", ") | 
| bsw@525 | 287 end | 
| bsw@525 | 288 | 
| bsw@525 | 289 function Issue.object_get:etherpad_url() | 
| bsw@525 | 290   return config.etherpad.base_url .. "p/" .. config.etherpad.group_id .. "$Issue" .. self.id | 
| bsw@551 | 291 end |