liquid_feedback_frontend
view model/issue.lua @ 218:7ea52c710503
Some little changes for next generation frontend
author | bsw |
---|---|
date | Sun Mar 13 16:53:33 2011 +0100 (2011-03-13) |
parents | 73dbc9e2bfd4 |
children |
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 admission = _"New",
280 accepted = _"Discussion",
281 frozen = _"Frozen",
282 voting = _"Voting",
283 finished = _"Finished",
284 cancelled = _"Cancelled",
285 canceled_issue_not_accepted = _"Cancelled"
286 }
287 return state_name_table[value] or value or ''
288 end
290 function Issue:get_search_selector(search_string)
291 return self:new_selector()
292 :join('"initiative"', nil, '"initiative"."issue_id" = "issue"."id"')
293 :join('"draft"', nil, '"draft"."initiative_id" = "initiative"."id"')
294 :add_where{ '"initiative"."text_search_data" @@ "text_search_query"(?) OR "draft"."text_search_data" @@ "text_search_query"(?)', search_string, search_string }
295 :add_group_by('"issue"."id"')
296 :add_group_by('"issue"."area_id"')
297 :add_group_by('"issue"."policy_id"')
298 :add_group_by('"issue"."created"')
299 :add_group_by('"issue"."accepted"')
300 :add_group_by('"issue"."half_frozen"')
301 :add_group_by('"issue"."fully_frozen"')
302 :add_group_by('"issue"."closed"')
303 :add_group_by('"issue"."ranks_available"')
304 :add_group_by('"issue"."cleaned"')
305 :add_group_by('"issue"."snapshot"')
306 :add_group_by('"issue"."latest_snapshot_event"')
307 :add_group_by('"issue"."population"')
308 :add_group_by('"issue"."vote_now"')
309 :add_group_by('"issue"."vote_later"')
310 :add_group_by('"issue"."voter_count"')
311 :add_group_by('"issue"."admission_time"')
312 :add_group_by('"issue"."discussion_time"')
313 :add_group_by('"issue"."verification_time"')
314 :add_group_by('"issue"."voting_time"')
315 :add_group_by('"_interest"."member_id"')
316 --:set_distinct()
317 end
319 function Issue:modify_selector_for_state(initiatives_selector, state)
320 if state == "new" then
321 initiatives_selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL")
322 elseif state == "accepted" then
323 initiatives_selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL")
324 elseif state == "frozen" then
325 initiatives_selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL AND issue.closed ISNULL")
326 elseif state == "voting" then
327 initiatives_selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL")
328 elseif state == "finished" then
329 initiatives_selector:add_where("issue.fully_frozen NOTNULL AND issue.closed NOTNULL")
330 elseif state == "cancelled" then
331 initiatives_selector:add_where("issue.fully_frozen ISNULL AND issue.closed NOTNULL")
332 else
333 error("Invalid state")
334 end
335 end
337 function Issue:build_selector(args)
338 local selector = self:new_selector()
339 if args.unit_id then
340 selector:join("area", nil, "area.id = issue.area_id")
341 selector:add_where{ "area.unit_id = ?", args.unit_id }
342 end
343 if args.area_id then
344 selector:add_where{ "issue.area_id = ?", args.area_id }
345 end
346 if args.phase == "closed" then
347 selector:add_where("issue.closed NOTNULL")
348 elseif args.phase == "voting" then
349 selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL")
350 elseif args.phase == "frozen" then
351 selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL AND issue.closed ISNULL")
352 elseif args.phase == "discussion" then
353 selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL")
354 elseif args.phase == "new" then
355 selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL")
356 end
357 if args.order == "time_left" then
358 selector:add_order_by("issue.closed DESC")
359 elseif args.order == "last_change" then
360 selector:add_order_by("issue.closed DESC")
361 elseif args.order == "interest" then
362 selector:add_order_by("issue.population DESC")
363 end
365 return selector
366 end
368 --[[
369 function Issue.object_get:state()
370 if self.closed then
371 if self.fully_frozen then
372 return "finished"
373 else
374 return "cancelled"
375 end
376 elseif self.fully_frozen then
377 return "voting"
378 elseif self.half_frozen then
379 return "frozen"
380 elseif self.accepted then
381 return "accepted"
382 else
383 return "new"
384 end
386 end
387 --]]
389 function Issue.object_get:phase()
390 local state = self.state
391 if state == "finished" or state == "cancelled" then
392 return "closed"
393 else
394 return state
395 end
396 end
398 function Issue.object_get:state_name()
399 return Issue:get_state_name_for_state(self.state)
400 end
402 function Issue.object_get:state_time_left()
403 local state = self.state
404 local last_event_time
405 local duration
406 if state == "admission" then
407 last_event_time = self.created
408 duration = self.admission_time
409 elseif state == "accepted" then
410 last_event_time = self.accepted
411 duration = self.discussion_time
412 elseif state == "frozen" then
413 last_event_time = self.half_frozen
414 duration = self.verification_time
415 elseif state == "voting" then
416 last_event_time = self.fully_frozen
417 duration = self.voting_time
418 end
419 return db:query{ "SELECT ?::timestamp + ?::interval - CURRENT_TIMESTAMP(0) as time_left", last_event_time, duration }[1].time_left
420 end
422 function Issue.object_get:next_states()
423 local state = self.state
424 local next_states
425 if state == "new" then
426 next_states = { "accepted", "cancelled" }
427 elseif state == "accepted" then
428 next_states = { "frozen" }
429 elseif state == "frozen" then
430 next_states = { "voting" }
431 elseif state == "voting" then
432 next_states = { "finished" }
433 end
434 return next_states
435 end
437 function Issue.object_get:next_states_names()
438 local next_states = self.next_states
439 if not next_states then
440 return
441 end
442 local state_names = {}
443 for i, state in ipairs(self.next_states) do
444 state_names[#state_names+1] = Issue:get_state_name_for_state(state)
445 end
446 return table.concat(state_names, ", ")
447 end