liquid_feedback_frontend

annotate model/issue.lua @ 1859:02c34183b6df

Fixed wrong filename in INSTALL file
author bsw
date Tue Nov 28 18:54:51 2023 +0100 (17 months ago)
parents faaf9ec3e09c
children
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@1234 8 selector:add_field("justify_interval(min_admission_time)::text", "min_admission_time_text")
bsw@1234 9 selector:add_field("justify_interval(max_admission_time)::text", "max_admission_time_text")
bsw@935 10 selector:add_field("justify_interval(discussion_time)::text", "discussion_time_text")
bsw@935 11 selector:add_field("justify_interval(verification_time)::text", "verification_time_text")
bsw@935 12 selector:add_field("justify_interval(voting_time)::text", "voting_time_text")
bsw@1234 13 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.max_admission_time) - now())", "state_time_left")
bsw@935 14 selector:add_field("justify_interval(now() - issue.closed)", "closed_ago")
bsw@549 15 return selector
bsw@549 16 end
bsw@549 17
bsw/jbe@0 18 Issue:add_reference{
bsw/jbe@0 19 mode = 'm1',
bsw/jbe@0 20 to = "Area",
bsw/jbe@0 21 this_key = 'area_id',
bsw/jbe@0 22 that_key = 'id',
bsw/jbe@0 23 ref = 'area',
bsw/jbe@0 24 }
bsw/jbe@0 25
bsw/jbe@0 26 Issue:add_reference{
bsw/jbe@0 27 mode = 'm1',
bsw/jbe@0 28 to = "Policy",
bsw/jbe@0 29 this_key = 'policy_id',
bsw/jbe@0 30 that_key = 'id',
bsw/jbe@0 31 ref = 'policy',
bsw/jbe@0 32 }
bsw/jbe@0 33
bsw/jbe@0 34 Issue:add_reference{
bsw/jbe@0 35 mode = '1m',
bsw/jbe@0 36 to = "Initiative",
bsw/jbe@0 37 this_key = 'id',
bsw/jbe@0 38 that_key = 'issue_id',
bsw/jbe@0 39 ref = 'initiatives',
bsw@551 40 back_ref = 'issue',
bsw@982 41 default_order = 'initiative.admitted DESC NULLS LAST, initiative.rank NULLS LAST, initiative.harmonic_weight DESC NULLS LAST, id'
bsw/jbe@0 42 }
bsw/jbe@0 43
bsw/jbe@0 44 Issue:add_reference{
bsw/jbe@0 45 mode = '1m',
bsw/jbe@0 46 to = "Interest",
bsw/jbe@0 47 this_key = 'id',
bsw/jbe@0 48 that_key = 'issue_id',
bsw/jbe@0 49 ref = 'interests',
bsw/jbe@0 50 back_ref = 'issue',
bsw/jbe@0 51 default_order = '"id"'
bsw/jbe@0 52 }
bsw/jbe@0 53
bsw/jbe@0 54 Issue:add_reference{
bsw/jbe@0 55 mode = '1m',
bsw/jbe@0 56 to = "Supporter",
bsw/jbe@0 57 this_key = 'id',
bsw/jbe@0 58 that_key = 'issue_id',
bsw/jbe@0 59 ref = 'supporters',
bsw/jbe@0 60 back_ref = 'issue',
bsw/jbe@0 61 default_order = '"id"'
bsw/jbe@0 62 }
bsw/jbe@0 63
bsw/jbe@0 64 Issue:add_reference{
bsw/jbe@0 65 mode = '1m',
bsw/jbe@0 66 to = "DirectVoter",
bsw/jbe@0 67 this_key = 'id',
bsw/jbe@0 68 that_key = 'issue_id',
bsw/jbe@0 69 ref = 'direct_voters',
bsw/jbe@0 70 back_ref = 'issue',
bsw/jbe@0 71 default_order = '"member_id"'
bsw/jbe@0 72 }
bsw/jbe@0 73
bsw/jbe@0 74 Issue:add_reference{
bsw/jbe@0 75 mode = '1m',
bsw/jbe@0 76 to = "Vote",
bsw/jbe@0 77 this_key = 'id',
bsw/jbe@0 78 that_key = 'issue_id',
bsw/jbe@0 79 ref = 'votes',
bsw/jbe@0 80 back_ref = 'issue',
bsw/jbe@0 81 default_order = '"member_id", "initiative_id"'
bsw/jbe@0 82 }
bsw/jbe@0 83
bsw/jbe@0 84 Issue:add_reference{
bsw@2 85 mode = '1m',
bsw@2 86 to = "Delegation",
bsw@2 87 this_key = 'id',
bsw@2 88 that_key = 'issue_id',
bsw@2 89 ref = 'delegations',
bsw@2 90 back_ref = 'issue'
bsw@2 91 }
bsw@2 92
bsw@2 93 Issue:add_reference{
bsw/jbe@0 94 mode = 'mm',
bsw/jbe@0 95 to = "Member",
bsw/jbe@0 96 this_key = 'id',
bsw/jbe@0 97 that_key = 'id',
bsw/jbe@0 98 connected_by_table = 'interest',
bsw/jbe@0 99 connected_by_this_key = 'issue_id',
bsw/jbe@0 100 connected_by_that_key = 'member_id',
bsw/jbe@0 101 ref = 'members'
bsw/jbe@0 102 }
bsw/jbe@0 103
bsw@3 104 Issue:add_reference{
bsw@3 105 mode = 'mm',
bsw@3 106 to = "Member",
bsw@3 107 this_key = 'id',
bsw@3 108 that_key = 'id',
bsw@3 109 connected_by_table = 'direct_interest_snapshot',
bsw@3 110 connected_by_this_key = 'issue_id',
bsw@3 111 connected_by_that_key = 'member_id',
bsw@3 112 ref = 'interested_members_snapshot'
bsw@3 113 }
bsw@3 114
bsw/jbe@6 115 Issue:add_reference{
bsw/jbe@6 116 mode = 'mm',
bsw/jbe@6 117 to = "Member",
bsw/jbe@6 118 this_key = 'id',
bsw/jbe@6 119 that_key = 'id',
bsw/jbe@6 120 connected_by_table = 'direct_voter',
bsw/jbe@6 121 connected_by_this_key = 'issue_id',
bsw/jbe@6 122 connected_by_that_key = 'member_id',
bsw/jbe@6 123 ref = 'direct_voters'
bsw/jbe@6 124 }
bsw/jbe@6 125
bsw@525 126 Issue:add_reference{
bsw@525 127 mode = "11",
bsw@525 128 to = mondelefant.class_prototype,
bsw@525 129 this_key = "id",
bsw@525 130 that_key = "issue_id",
bsw@547 131 ref = "member_info",
bsw@525 132 back_ref = "issue",
bsw@525 133 selector_generator = function(list, options)
bsw@547 134 assert(options.member_id, "member_id mandatory for member_info")
bsw@525 135 local ids = { sep = ", " }
bsw@525 136 for i, object in ipairs(list) do
bsw@525 137 local id = object.id
bsw@525 138 if id ~= nil then
bsw@525 139 ids[#ids+1] = {"?", id}
bsw@525 140 end
bsw@525 141 end
bsw@525 142 local sub_selector = Issue:get_db_conn():new_selector()
bsw@525 143 if #ids == 0 then
bsw@525 144 return sub_selector:empty_list_mode()
bsw@525 145 end
bsw@1045 146 sub_selector:from ( "issue" )
bsw@1045 147 sub_selector:add_field ( "issue.id", "issue_id" )
bsw@1045 148 sub_selector:add_field { '(delegation_info(?, null, null, issue.id, ?)).*', options.member_id, options.trustee_id }
bsw@1045 149 sub_selector:add_where { 'issue.id IN ($)', ids }
bsw@525 150
bsw@525 151 local selector = Issue:get_db_conn():new_selector()
bsw@1045 152 selector:add_from ( "issue" )
bsw@1045 153 selector:join(sub_selector, "delegation_info", "delegation_info.issue_id = issue.id" )
bsw@1045 154 selector:left_join ( "member", "first_trustee", "first_trustee.id = delegation_info.first_trustee_id" )
bsw@1045 155 selector:left_join ( "member", "other_trustee", "other_trustee.id = delegation_info.other_trustee_id" )
bsw@1045 156 selector:add_field ( "delegation_info.*" )
bsw@1045 157 selector:add_field ( "first_trustee.name", "first_trustee_name" )
bsw@1045 158 selector:add_field ( "other_trustee.name", "other_trustee_name" )
bsw@1045 159 selector:left_join ( "direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", options.member_id })
bsw@1045 160 selector:add_field ( "direct_voter.member_id NOTNULL", "direct_voted")
bsw@1045 161 selector:left_join ( "non_voter", nil, { "non_voter.issue_id = issue.id AND non_voter.member_id = ?", options.member_id })
bsw@1045 162 selector:add_field ( "non_voter.member_id NOTNULL", "non_voter" )
bsw@1045 163 selector:left_join ( "direct_interest_snapshot", nil, { [[
bsw@1045 164 direct_interest_snapshot.issue_id = issue.id AND
bsw/jbe@1309 165 direct_interest_snapshot.snapshot_id = issue.latest_snapshot_id AND
bsw@1045 166 direct_interest_snapshot.member_id = ?
bsw@1045 167 ]], options.member_id })
bsw@1045 168 selector:add_field ( "direct_interest_snapshot.weight", "weight" )
bsw@525 169 return selector
bsw@525 170 end
bsw@525 171 }
bsw@525 172
bsw@547 173 function Issue.list:load_everything_for_member_id(member_id)
bsw@547 174 local areas = self:load("area")
bsw@547 175 areas:load("unit")
bsw@547 176 self:load("policy")
bsw@551 177 if member_id then
bsw@551 178 self:load("member_info", { member_id = member_id })
bsw@551 179 end
bsw@551 180 local initiatives = self:load("initiatives")
bsw@551 181 initiatives:load_everything_for_member_id(member_id)
bsw@525 182 end
bsw@525 183
bsw@548 184 function Issue.object:load_everything_for_member_id(member_id)
bsw@548 185 local areas = self:load("area")
bsw@548 186 areas:load("unit")
bsw@548 187 self:load("policy")
bsw@551 188 if member_id then
bsw@551 189 self:load("member_info", { member_id = member_id })
bsw@551 190 end
bsw@551 191 local initiatives = self:load("initiatives")
bsw@551 192 initiatives:load_everything_for_member_id(member_id)
bsw@548 193 end
bsw@548 194
bsw@972 195
bsw@972 196
bsw/jbe@0 197 function Issue:get_state_name_for_state(value)
bsw@2 198 local state_name_table = {
bsw@1045 199 admission = _"Admission",
bsw@972 200 discussion = _"Discussion",
bsw@1045 201 verification = _"Verification",
bsw@972 202 voting = _"Voting",
bsw@1045 203 canceled_revoked_before_accepted = _"Revoked (during admission)",
bsw@1045 204 canceled_issue_not_accepted = _"Failed 1st quorum",
bsw@1045 205 canceled_after_revocation_during_discussion = _"Revoked (during discussion)",
bsw@1045 206 canceled_after_revocation_during_verification = _"Revoked (during verification)",
bsw@1029 207 canceled_by_admin = _"Canceled by administrative intervention",
bsw@972 208 calculation = _"Calculation",
bsw@1045 209 canceled_no_initiative_admitted = _"All initiatives failed 2nd quorum",
bsw@1045 210 finished_without_winner = _"Disapproved",
bsw@1045 211 finished_with_winner = _"Finished with winner",
bsw@2 212 }
bsw@10 213 return state_name_table[value] or value or ''
bsw/jbe@0 214 end
bsw/jbe@0 215
bsw@972 216
bsw@972 217
bsw@2 218 function Issue:get_search_selector(search_string)
bsw/jbe@0 219 return self:new_selector()
bsw/jbe@0 220 :join('"initiative"', nil, '"initiative"."issue_id" = "issue"."id"')
bsw/jbe@6 221 :join('"draft"', nil, '"draft"."initiative_id" = "initiative"."id"')
bsw@1492 222 :add_where{ 'to_tsvector("initiative") @@ "plainto_tsquery"(?) OR to_tsvector("draft") @@ "plainto_tsquery"(?)', search_string, search_string }
bsw/jbe@6 223 :add_group_by('"issue"."id"')
bsw/jbe@0 224 end
bsw/jbe@0 225
bsw@75 226 function Issue:modify_selector_for_state(initiatives_selector, state)
bsw@51 227 if state == "new" then
bsw@75 228 initiatives_selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL")
bsw@51 229 elseif state == "accepted" then
bsw@75 230 initiatives_selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL")
bsw@51 231 elseif state == "frozen" then
bsw@75 232 initiatives_selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL AND issue.closed ISNULL")
bsw@51 233 elseif state == "voting" then
bsw@75 234 initiatives_selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL")
bsw@51 235 elseif state == "finished" then
bsw@75 236 initiatives_selector:add_where("issue.fully_frozen NOTNULL AND issue.closed NOTNULL")
bsw@973 237 elseif state == "canceled" then
bsw@75 238 initiatives_selector:add_where("issue.fully_frozen ISNULL AND issue.closed NOTNULL")
bsw@75 239 else
bsw@75 240 error("Invalid state")
bsw@51 241 end
bsw@51 242 end
bsw@51 243
bsw@2 244
bsw@2 245 function Issue.object_get:state_name()
bsw@2 246 return Issue:get_state_name_for_state(self.state)
bsw@2 247 end
bsw@2 248
bsw@2 249 function Issue.object_get:next_states_names()
bsw@2 250 local next_states = self.next_states
bsw@2 251 if not next_states then
bsw@2 252 return
bsw@2 253 end
bsw@2 254 local state_names = {}
bsw@2 255 for i, state in ipairs(self.next_states) do
bsw@2 256 state_names[#state_names+1] = Issue:get_state_name_for_state(state)
bsw@2 257 end
bsw@2 258 return table.concat(state_names, ", ")
bsw@525 259 end
bsw@525 260
bsw@525 261 function Issue.object_get:etherpad_url()
bsw@525 262 return config.etherpad.base_url .. "p/" .. config.etherpad.group_id .. "$Issue" .. self.id
bsw@551 263 end
bsw@1045 264
bsw@1045 265 function Issue.object_get:name()
bsw@1045 266 return self.policy.name .. " #" .. self.id
bsw@1045 267 end
bsw@1045 268
bsw@1045 269 function Issue.object_get:state_time_text()
bsw@1045 270 if self.closed then
bsw@1045 271 return _("#{closed_ago} ago", { closed_ago = self.closed_ago })
bsw@1045 272 elseif string.sub(self.state_time_left, 1, 2) ~= "-" then
bsw@1045 273 return _("ends soon", { state_time_left = self.state_time_left })
bsw@1045 274 else
bsw@1045 275 return _("ends in #{state_time_left}", { state_time_left = self.state_time_left })
bsw@1045 276 end
bsw@1045 277 end
bsw/jbe@1309 278
bsw/jbe@1309 279 function Issue:by_ids(ids)
bsw/jbe@1309 280 local selector = self:new_selector()
bsw/jbe@1309 281 selector:add_where{'"id" IN ($)', { ids } }
bsw/jbe@1309 282 return selector:exec()
bsw/jbe@1309 283 end
bsw/jbe@1309 284

Impressum / About Us