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