liquid_feedback_frontend

view model/issue.lua @ 217:73dbc9e2bfd4

Cummulative patch for enhancements at next generation frontend
author bsw
date Sat Mar 12 19:22:50 2011 +0100 (2011-03-12)
parents 4f6e6b213fb8
children 7ea52c710503
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 }
239 Issue:add_reference{
240 mode = 'mm',
241 to = "Member",
242 this_key = 'id',
243 that_key = 'mm_ref_',
244 ref = 'trusters_for_member',
245 back_ref = 'issue',
246 selector_generator = function(list, options)
248 local member_id = assert(options.member_id)
250 -- build list of issue ids
251 local ids = { sep = ", " }
252 for i, object in ipairs(list) do
253 local id = object.id
254 if id ~= nil then
255 ids[#ids+1] = {"?", id}
256 end
257 end
259 if #ids == 0 then
260 return Delegation:new_selector():empty_list_mode()
261 end
263 local selector = Member:new_selector()
264 selector:join("delegating_interest_snapshot", nil, { "delegating_interest_snapshot.delegate_member_ids[1] = ? AND delegating_interest_snapshot.member_id = member.id", member_id })
265 selector:join("issue", nil, "delegating_interest_snapshot.issue_id = issue.id AND delegating_interest_snapshot.event = issue.latest_snapshot_event")
266 selector:add_where{ 'delegating_interest_snapshot.issue_id IN ($)', ids }
267 selector:add_field("delegating_interest_snapshot.issue_id", "mm_ref_")
268 selector:add_field("delegating_interest_snapshot.weight", "weight")
269 selector:add_order_by("delegating_interest_snapshot.weight DESC, member.id")
270 return selector
272 end
273 }
277 function Issue:get_state_name_for_state(value)
278 local state_name_table = {
279 new = _"New",
280 accepted = _"Discussion",
281 frozen = _"Frozen",
282 voting = _"Voting",
283 finished = _"Finished",
284 cancelled = _"Cancelled"
285 }
286 return state_name_table[value] or value or ''
287 end
289 function Issue:get_search_selector(search_string)
290 return self:new_selector()
291 :join('"initiative"', nil, '"initiative"."issue_id" = "issue"."id"')
292 :join('"draft"', nil, '"draft"."initiative_id" = "initiative"."id"')
293 :add_where{ '"initiative"."text_search_data" @@ "text_search_query"(?) OR "draft"."text_search_data" @@ "text_search_query"(?)', search_string, search_string }
294 :add_group_by('"issue"."id"')
295 :add_group_by('"issue"."area_id"')
296 :add_group_by('"issue"."policy_id"')
297 :add_group_by('"issue"."created"')
298 :add_group_by('"issue"."accepted"')
299 :add_group_by('"issue"."half_frozen"')
300 :add_group_by('"issue"."fully_frozen"')
301 :add_group_by('"issue"."closed"')
302 :add_group_by('"issue"."ranks_available"')
303 :add_group_by('"issue"."cleaned"')
304 :add_group_by('"issue"."snapshot"')
305 :add_group_by('"issue"."latest_snapshot_event"')
306 :add_group_by('"issue"."population"')
307 :add_group_by('"issue"."vote_now"')
308 :add_group_by('"issue"."vote_later"')
309 :add_group_by('"issue"."voter_count"')
310 :add_group_by('"issue"."admission_time"')
311 :add_group_by('"issue"."discussion_time"')
312 :add_group_by('"issue"."verification_time"')
313 :add_group_by('"issue"."voting_time"')
314 :add_group_by('"_interest"."member_id"')
315 --:set_distinct()
316 end
318 function Issue:modify_selector_for_state(initiatives_selector, state)
319 if state == "new" then
320 initiatives_selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL")
321 elseif state == "accepted" then
322 initiatives_selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL")
323 elseif state == "frozen" then
324 initiatives_selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL AND issue.closed ISNULL")
325 elseif state == "voting" then
326 initiatives_selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL")
327 elseif state == "finished" then
328 initiatives_selector:add_where("issue.fully_frozen NOTNULL AND issue.closed NOTNULL")
329 elseif state == "cancelled" then
330 initiatives_selector:add_where("issue.fully_frozen ISNULL AND issue.closed NOTNULL")
331 else
332 error("Invalid state")
333 end
334 end
336 function Issue:build_selector(args)
337 local selector = self:new_selector()
338 if args.unit_id then
339 selector:join("area", nil, "area.id = issue.area_id")
340 selector:add_where{ "area.unit_id = ?", args.unit_id }
341 end
342 if args.area_id then
343 selector:add_where{ "issue.area_id = ?", args.area_id }
344 end
345 if args.phase == "closed" then
346 selector:add_where("issue.closed NOTNULL")
347 elseif args.phase == "voting" then
348 selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL")
349 elseif args.phase == "frozen" then
350 selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL AND issue.closed ISNULL")
351 elseif args.phase == "discussion" then
352 selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL")
353 elseif args.phase == "new" then
354 selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL")
355 end
356 if args.order == "time_left" then
357 selector:add_order_by("issue.closed DESC")
358 elseif args.order == "last_change" then
359 selector:add_order_by("issue.closed DESC")
360 elseif args.order == "interest" then
361 selector:add_order_by("issue.population DESC")
362 end
364 return selector
365 end
367 function Issue.object_get:state()
368 if self.closed then
369 if self.fully_frozen then
370 return "finished"
371 else
372 return "cancelled"
373 end
374 elseif self.fully_frozen then
375 return "voting"
376 elseif self.half_frozen then
377 return "frozen"
378 elseif self.accepted then
379 return "accepted"
380 else
381 return "new"
382 end
384 end
386 function Issue.object_get:phase()
387 local state = self.state
388 if state == "finished" or state == "cancelled" then
389 return "closed"
390 else
391 return state
392 end
393 end
395 function Issue.object_get:state_name()
396 return Issue:get_state_name_for_state(self.state)
397 end
399 function Issue.object_get:state_time_left()
400 local state = self.state
401 local last_event_time
402 local duration
403 if state == "new" then
404 last_event_time = self.created
405 duration = self.admission_time
406 elseif state == "accepted" then
407 last_event_time = self.accepted
408 duration = self.discussion_time
409 elseif state == "frozen" then
410 last_event_time = self.half_frozen
411 duration = self.verification_time
412 elseif state == "voting" then
413 last_event_time = self.fully_frozen
414 duration = self.voting_time
415 end
416 return db:query{ "SELECT ?::timestamp + ?::interval - CURRENT_TIMESTAMP(0) as time_left", last_event_time, duration }[1].time_left
417 end
419 function Issue.object_get:next_states()
420 local state = self.state
421 local next_states
422 if state == "new" then
423 next_states = { "accepted", "cancelled" }
424 elseif state == "accepted" then
425 next_states = { "frozen" }
426 elseif state == "frozen" then
427 next_states = { "voting" }
428 elseif state == "voting" then
429 next_states = { "finished" }
430 end
431 return next_states
432 end
434 function Issue.object_get:next_states_names()
435 local next_states = self.next_states
436 if not next_states then
437 return
438 end
439 local state_names = {}
440 for i, state in ipairs(self.next_states) do
441 state_names[#state_names+1] = Issue:get_state_name_for_state(state)
442 end
443 return table.concat(state_names, ", ")
444 end

Impressum / About Us