liquid_feedback_frontend

view model/issue.lua @ 215:1dab81353eb1

More enhancements for second generation frontend
author bsw
date Sat Mar 05 15:34:17 2011 +0100 (2011-03-05)
parents 3e4ad069847a
children 4f6e6b213fb8
line source
1 Issue = mondelefant.new_class()
2 Issue.table = 'issue'
4 Issue:add_reference{
5 mode = 'm1',
6 to = "Area",
7 this_key = 'area_id',
8 that_key = 'id',
9 ref = 'area',
10 }
12 Issue:add_reference{
13 mode = 'm1',
14 to = "Policy",
15 this_key = 'policy_id',
16 that_key = 'id',
17 ref = 'policy',
18 }
20 Issue:add_reference{
21 mode = '1m',
22 to = "Initiative",
23 this_key = 'id',
24 that_key = 'issue_id',
25 ref = 'initiatives',
26 back_ref = 'issue',
27 default_order = 'initiative.rank, initiative.admitted ISNULL, initiative.admitted DESC, initiative.positive_votes::float / initiative.negative_votes::float DESC, initiative.supporter_count DESC'
28 }
30 Issue:add_reference{
31 mode = '1m',
32 to = "Interest",
33 this_key = 'id',
34 that_key = 'issue_id',
35 ref = 'interests',
36 back_ref = 'issue',
37 default_order = '"id"'
38 }
40 Issue:add_reference{
41 mode = '1m',
42 to = "Supporter",
43 this_key = 'id',
44 that_key = 'issue_id',
45 ref = 'supporters',
46 back_ref = 'issue',
47 default_order = '"id"'
48 }
50 Issue:add_reference{
51 mode = '1m',
52 to = "DirectVoter",
53 this_key = 'id',
54 that_key = 'issue_id',
55 ref = 'direct_voters',
56 back_ref = 'issue',
57 default_order = '"member_id"'
58 }
60 Issue:add_reference{
61 mode = '1m',
62 to = "Vote",
63 this_key = 'id',
64 that_key = 'issue_id',
65 ref = 'votes',
66 back_ref = 'issue',
67 default_order = '"member_id", "initiative_id"'
68 }
70 Issue:add_reference{
71 mode = '1m',
72 to = "Delegation",
73 this_key = 'id',
74 that_key = 'issue_id',
75 ref = 'delegations',
76 back_ref = 'issue'
77 }
79 Issue:add_reference{
80 mode = 'mm',
81 to = "Member",
82 this_key = 'id',
83 that_key = 'id',
84 connected_by_table = 'interest',
85 connected_by_this_key = 'issue_id',
86 connected_by_that_key = 'member_id',
87 ref = 'members'
88 }
89 --[[
90 Issue:add_reference{
91 mode = 'mm',
92 to = "Member",
93 this_key = 'id',
94 that_key = 'id',
95 connected_by_table = 'direct_interest_snapshot',
96 connected_by_this_key = 'issue_id',
97 connected_by_that_key = 'member_id',
98 ref = 'interested_members_snapshot'
99 }
100 --]]
101 Issue:add_reference{
102 mode = 'mm',
103 to = "Member",
104 this_key = 'id',
105 that_key = 'id',
106 connected_by_table = 'direct_voter',
107 connected_by_this_key = 'issue_id',
108 connected_by_that_key = 'member_id',
109 ref = 'direct_voters'
110 }
112 Issue:add_reference{
113 mode = 'mm',
114 to = "Member",
115 this_key = 'id',
116 that_key = 'id',
117 connected_by_table = 'direct_interest_snapshot',
118 connected_by_this_key = 'issue_id',
119 connected_by_that_key = 'member_id',
120 ref = 'interested_members_snapshot',
121 selector_generator = function(list, options)
122 -- build list of issue ids
123 local ids = { sep = ", " }
124 for i, object in ipairs(list) do
125 local id = object.id
126 if id ~= nil then
127 ids[#ids+1] = {"?", id}
128 end
129 end
131 if #ids == 0 then
132 return Member:new_selector():empty_list_mode()
133 end
135 local selector = Member:new_selector()
136 selector:join("direct_interest_snapshot", nil, { "direct_interest_snapshot.member_id = member.id AND direct_interest_snapshot.issue_id IN ($)", ids })
137 selector:join("issue", nil, "direct_interest_snapshot.issue_id = issue.id AND direct_interest_snapshot.event = issue.latest_snapshot_event")
138 selector:add_order_by('direct_interest_snapshot.weight DESC')
139 return selector
140 end
141 }
143 Issue:add_reference{
144 mode = '11',
145 to = "DelegatingInterestSnapshot",
146 this_key = 'id',
147 that_key = 'issue_id',
148 ref = 'delegating_interest_snapshot_for_member',
149 back_ref = 'issue',
150 selector_generator = function(list, options)
151 local member_id = assert(options.member_id)
153 -- build list of issue ids
154 local ids = { sep = ", " }
155 for i, object in ipairs(list) do
156 local id = object.id
157 if id ~= nil then
158 ids[#ids+1] = {"?", id}
159 end
160 end
162 if #ids == 0 then
163 return DelegatingInterestSnapshot:new_selector():empty_list_mode()
164 end
166 local selector = DelegatingInterestSnapshot:new_selector()
167 selector:join("issue", nil, "delegating_interest_snapshot.issue_id = issue.id AND delegating_interest_snapshot.event = issue.latest_snapshot_event")
168 selector:add_where{ 'delegating_interest_snapshot.issue_id IN ($)', ids }
169 selector:add_where{ 'delegating_interest_snapshot.member_id = ?', member_id }
171 return selector
172 end
173 }
175 Issue:add_reference{
176 mode = '11',
177 to = "Interest",
178 this_key = 'id',
179 that_key = 'issue_id',
180 ref = 'interest_for_member',
181 back_ref = 'issue',
182 selector_generator = function(list, options)
184 local member_id = assert(options.member_id)
186 -- build list of issue ids
187 local ids = { sep = ", " }
188 for i, object in ipairs(list) do
189 local id = object.id
190 if id ~= nil then
191 ids[#ids+1] = {"?", id}
192 end
193 end
195 if #ids == 0 then
196 return Interest:new_selector():empty_list_mode()
197 end
199 local selector = Interest:new_selector()
200 selector:add_where{ 'interest.issue_id IN ($)', ids }
201 selector:add_where{ 'interest.member_id = ?', member_id }
202 return selector
204 end
205 }
207 Issue:add_reference{
208 mode = '1m',
209 to = "Delegation",
210 this_key = 'id',
211 that_key = 'issue_id',
212 ref = 'outgoing_delegations_for_member',
213 back_ref = 'issue',
214 selector_generator = function(list, options)
216 local member_id = assert(options.member_id)
218 -- build list of issue ids
219 local ids = { sep = ", " }
220 for i, object in ipairs(list) do
221 local id = object.id
222 if id ~= nil then
223 ids[#ids+1] = {"?", id}
224 end
225 end
227 if #ids == 0 then
228 return Delegation:new_selector():empty_list_mode()
229 end
231 local selector = Delegation:new_selector()
232 selector:add_where{ 'delegation.issue_id IN ($)', ids }
233 selector:add_where{ 'delegation.truster_id = ?', member_id }
234 return selector
236 end
237 }
241 function Issue:get_state_name_for_state(value)
242 local state_name_table = {
243 new = _"New",
244 accepted = _"Discussion",
245 frozen = _"Frozen",
246 voting = _"Voting",
247 finished = _"Finished",
248 cancelled = _"Cancelled"
249 }
250 return state_name_table[value] or value or ''
251 end
253 function Issue:get_search_selector(search_string)
254 return self:new_selector()
255 :join('"initiative"', nil, '"initiative"."issue_id" = "issue"."id"')
256 :join('"draft"', nil, '"draft"."initiative_id" = "initiative"."id"')
257 :add_where{ '"initiative"."text_search_data" @@ "text_search_query"(?) OR "draft"."text_search_data" @@ "text_search_query"(?)', search_string, search_string }
258 :add_group_by('"issue"."id"')
259 :add_group_by('"issue"."area_id"')
260 :add_group_by('"issue"."policy_id"')
261 :add_group_by('"issue"."created"')
262 :add_group_by('"issue"."accepted"')
263 :add_group_by('"issue"."half_frozen"')
264 :add_group_by('"issue"."fully_frozen"')
265 :add_group_by('"issue"."closed"')
266 :add_group_by('"issue"."ranks_available"')
267 :add_group_by('"issue"."cleaned"')
268 :add_group_by('"issue"."snapshot"')
269 :add_group_by('"issue"."latest_snapshot_event"')
270 :add_group_by('"issue"."population"')
271 :add_group_by('"issue"."vote_now"')
272 :add_group_by('"issue"."vote_later"')
273 :add_group_by('"issue"."voter_count"')
274 :add_group_by('"issue"."admission_time"')
275 :add_group_by('"issue"."discussion_time"')
276 :add_group_by('"issue"."verification_time"')
277 :add_group_by('"issue"."voting_time"')
278 :add_group_by('"_interest"."member_id"')
279 --:set_distinct()
280 end
282 function Issue:modify_selector_for_state(initiatives_selector, state)
283 if state == "new" then
284 initiatives_selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL")
285 elseif state == "accepted" then
286 initiatives_selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL")
287 elseif state == "frozen" then
288 initiatives_selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL AND issue.closed ISNULL")
289 elseif state == "voting" then
290 initiatives_selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL")
291 elseif state == "finished" then
292 initiatives_selector:add_where("issue.fully_frozen NOTNULL AND issue.closed NOTNULL")
293 elseif state == "cancelled" then
294 initiatives_selector:add_where("issue.fully_frozen ISNULL AND issue.closed NOTNULL")
295 else
296 error("Invalid state")
297 end
298 end
300 function Issue:build_selector(args)
301 local selector = self:new_selector()
302 if args.area_id then
303 selector:add_where{ "issue.area_id = ?", args.area_id }
304 end
305 if args.phase == "closed" then
306 selector:add_where("issue.closed NOTNULL")
307 elseif args.phase == "voting" then
308 selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL")
309 elseif args.phase == "frozen" then
310 selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL AND issue.closed ISNULL")
311 elseif args.phase == "discussion" then
312 selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL")
313 elseif args.phase == "new" then
314 selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL")
315 end
316 if args.order == "time_left" then
317 selector:add_order_by("issue.closed DESC")
318 elseif args.order == "last_change" then
319 selector:add_order_by("issue.closed DESC")
320 elseif args.order == "interest" then
321 selector:add_order_by("issue.population DESC")
322 end
324 return selector
325 end
327 function Issue.object_get:state()
328 if self.closed then
329 if self.fully_frozen then
330 return "finished"
331 else
332 return "cancelled"
333 end
334 elseif self.fully_frozen then
335 return "voting"
336 elseif self.half_frozen then
337 return "frozen"
338 elseif self.accepted then
339 return "accepted"
340 else
341 return "new"
342 end
344 end
346 function Issue.object_get:phase()
347 local state = self.state
348 if state == "finished" or state == "cancelled" then
349 return "closed"
350 else
351 return state
352 end
353 end
355 function Issue.object_get:state_name()
356 return Issue:get_state_name_for_state(self.state)
357 end
359 function Issue.object_get:state_time_left()
360 local state = self.state
361 local last_event_time
362 local duration
363 if state == "new" then
364 last_event_time = self.created
365 duration = self.admission_time
366 elseif state == "accepted" then
367 last_event_time = self.accepted
368 duration = self.discussion_time
369 elseif state == "frozen" then
370 last_event_time = self.half_frozen
371 duration = self.verification_time
372 elseif state == "voting" then
373 last_event_time = self.fully_frozen
374 duration = self.voting_time
375 end
376 return db:query{ "SELECT ?::timestamp + ?::interval - CURRENT_TIMESTAMP(0) as time_left", last_event_time, duration }[1].time_left
377 end
379 function Issue.object_get:next_states()
380 local state = self.state
381 local next_states
382 if state == "new" then
383 next_states = { "accepted", "cancelled" }
384 elseif state == "accepted" then
385 next_states = { "frozen" }
386 elseif state == "frozen" then
387 next_states = { "voting" }
388 elseif state == "voting" then
389 next_states = { "finished" }
390 end
391 return next_states
392 end
394 function Issue.object_get:next_states_names()
395 local next_states = self.next_states
396 if not next_states then
397 return
398 end
399 local state_names = {}
400 for i, state in ipairs(self.next_states) do
401 state_names[#state_names+1] = Issue:get_state_name_for_state(state)
402 end
403 return table.concat(state_names, ", ")
404 end

Impressum / About Us