bsw/jbe@0: Initiative = mondelefant.new_class() bsw/jbe@0: Initiative.table = 'initiative' bsw/jbe@0: bsw/jbe@0: Initiative:add_reference{ bsw/jbe@0: mode = 'm1', bsw/jbe@0: to = "Issue", bsw/jbe@0: this_key = 'issue_id', bsw/jbe@0: that_key = 'id', bsw/jbe@0: ref = 'issue', bsw/jbe@0: } bsw/jbe@0: bsw/jbe@0: Initiative:add_reference{ bsw@1045: mode = 'm1', bsw@1045: to = "Member", bsw@1045: this_key = 'revoked_by_member_id', bsw@1045: that_key = 'id', bsw@1045: ref = 'revoked_by_member', bsw@1045: } bsw@1045: bsw@1045: Initiative:add_reference{ bsw/jbe@0: mode = '1m', bsw/jbe@0: to = "Draft", bsw/jbe@0: this_key = 'id', bsw/jbe@0: that_key = 'initiative_id', bsw/jbe@0: ref = 'drafts', bsw/jbe@0: back_ref = 'initiative', bsw/jbe@19: default_order = '"id" DESC' bsw/jbe@0: } bsw/jbe@0: bsw/jbe@0: Initiative:add_reference{ bsw/jbe@0: mode = '1m', bsw/jbe@0: to = "Suggestion", bsw/jbe@0: this_key = 'id', bsw/jbe@0: that_key = 'initiative_id', bsw/jbe@0: ref = 'suggestions', bsw/jbe@0: back_ref = 'initiative', bsw@1045: default_order = '"proportional_order" NULLS LAST, id' bsw/jbe@0: } bsw/jbe@0: bsw/jbe@0: Initiative:add_reference{ bsw/jbe@0: mode = '1m', bsw/jbe@0: to = "Initiator", bsw/jbe@0: this_key = 'id', bsw/jbe@0: that_key = 'initiative_id', bsw/jbe@0: ref = 'initiators', bsw@10: back_ref = 'initiative' bsw/jbe@0: } bsw/jbe@0: bsw/jbe@0: Initiative:add_reference{ bsw/jbe@0: mode = '1m', bsw/jbe@0: to = "Supporter", bsw/jbe@0: this_key = 'id', bsw/jbe@0: that_key = 'initiative_id', bsw/jbe@0: ref = 'supporters', bsw/jbe@0: back_ref = 'initiative', bsw/jbe@0: default_order = '"id"' bsw/jbe@0: } bsw/jbe@0: bsw/jbe@0: Initiative:add_reference{ bsw/jbe@0: mode = '1m', bsw/jbe@0: to = "Opinion", bsw/jbe@0: this_key = 'id', bsw/jbe@0: that_key = 'initiative_id', bsw/jbe@0: ref = 'opinions', bsw/jbe@0: back_ref = 'initiative', bsw/jbe@0: default_order = '"id"' bsw/jbe@0: } bsw/jbe@0: bsw/jbe@0: Initiative:add_reference{ bsw/jbe@0: mode = '1m', bsw/jbe@0: to = "Vote", bsw/jbe@0: this_key = 'id', bsw/jbe@0: that_key = 'initiative_id', bsw/jbe@0: ref = 'votes', bsw/jbe@0: back_ref = 'initiative', bsw/jbe@0: default_order = '"member_id"' bsw/jbe@0: } bsw/jbe@0: bsw/jbe@0: Initiative:add_reference{ bsw@10: mode = 'm1', bsw@10: to = "Initiative", bsw@10: this_key = 'suggested_initiative_id', bsw@10: that_key = 'id', bsw@10: ref = 'suggested_initiative', bsw@10: } bsw@10: bsw@10: Initiative:add_reference{ bsw/jbe@0: mode = 'mm', bsw/jbe@0: to = "Member", bsw/jbe@0: this_key = 'id', bsw/jbe@0: that_key = 'id', bsw/jbe@0: connected_by_table = '"initiator"', bsw/jbe@0: connected_by_this_key = 'initiative_id', bsw/jbe@0: connected_by_that_key = 'member_id', bsw/jbe@0: ref = 'initiating_members' bsw/jbe@0: } bsw/jbe@0: bsw/jbe@0: Initiative:add_reference{ bsw/jbe@0: mode = 'mm', bsw/jbe@0: to = "Member", bsw/jbe@0: this_key = 'id', bsw/jbe@0: that_key = 'id', bsw/jbe@0: connected_by_table = '"supporter"', bsw/jbe@0: connected_by_this_key = 'initiative_id', bsw/jbe@0: connected_by_that_key = 'member_id', bsw/jbe@0: ref = 'supporting_members' bsw/jbe@0: } bsw/jbe@0: bsw@3: Initiative:add_reference{ bsw@3: mode = 'mm', bsw@3: to = "Member", bsw@3: this_key = 'id', bsw@3: that_key = 'id', bsw@3: connected_by_table = 'direct_supporter_snapshot', bsw@3: connected_by_this_key = 'initiative_id', bsw@3: connected_by_that_key = 'member_id', bsw@3: ref = 'supporting_members_snapshot' bsw@3: } bsw@3: bsw@551: Initiative:add_reference{ bsw@551: mode = "11", bsw@551: to = mondelefant.class_prototype, bsw@551: this_key = "id", bsw@551: that_key = "initiative_id", bsw@551: ref = "member_info", bsw@551: back_ref = "initiative", bsw@551: selector_generator = function(list, options) bsw@551: assert(options.member_id, "member_id mandatory for member_info") bsw@551: local ids = { sep = ", " } bsw@551: local issue_ids = { sep = ", " } bsw@551: for i, object in ipairs(list) do bsw@551: local id = object.id bsw@551: if id ~= nil then bsw@551: ids[#ids+1] = {"?", id} bsw@551: issue_ids[#issue_ids+1] = { "?", object.issue_id } bsw@551: end bsw@551: end bsw@551: bsw@551: local sub_selector = Issue:get_db_conn():new_selector() bsw@551: if #ids == 0 then bsw@551: return sub_selector:empty_list_mode() bsw@551: end bsw@551: sub_selector:from("issue") bsw@551: sub_selector:add_field("issue.id", "issue_id") bsw@551: sub_selector:add_field{ '(delegation_info(?, null, null, issue.id, ?)).*', options.member_id, options.trustee_id } bsw@551: sub_selector:add_where{ 'issue.id IN ($)', issue_ids } bsw@551: bsw@551: local selector = Initiative:get_db_conn():new_selector() bsw@551: selector:add_from("initiative") bsw@551: selector:add_field("initiative.id", "initiative_id") bsw@551: selector:join("issue", nil, "issue.id = initiative.issue_id") bsw@551: selector:join(sub_selector, "delegation_info", "delegation_info.issue_id = issue.id") bsw@551: selector:add_field("delegation_info.*") bsw@551: bsw@551: selector:left_join("supporter", nil, "supporter.initiative_id = initiative.id AND supporter.member_id = delegation_info.participating_member_id") bsw@551: bsw/jbe@1309: selector:left_join("delegating_interest_snapshot", "delegating_interest_s", { "delegating_interest_s.snapshot_id = issue.latest_snapshot_id AND delegating_interest_s.issue_id = issue.id AND delegating_interest_s.member_id = ?", options.member_id }) bsw@551: bsw/jbe@1309: selector:left_join("direct_supporter_snapshot", "supporter_s", { "supporter_s.snapshot_id = issue.latest_snapshot_id AND supporter_s.initiative_id = initiative.id AND (supporter_s.member_id = ? OR supporter_s.member_id = delegating_interest_s.delegate_member_ids[array_upper(delegating_interest_s.delegate_member_ids, 1)])", options.member_id }) bsw@551: bsw@551: selector:add_field("CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN supporter.member_id NOTNULL ELSE supporter_s.member_id NOTNULL END", "supported") bsw@551: selector:add_field({ "CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN delegation_info.own_participation AND supporter.member_id NOTNULL ELSE supporter_s.member_id = ? END", options.member_id }, "directly_supported") bsw@551: bsw@551: selector:add_field("CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN supporter.member_id NOTNULL AND NOT EXISTS(SELECT 1 FROM critical_opinion WHERE critical_opinion.initiative_id = initiative.id AND critical_opinion.member_id = delegation_info.participating_member_id) ELSE supporter_s.satisfied NOTNULL END", "satisfied") bsw@551: bsw@551: bsw@551: --selector:add_field("", "informed") bsw@551: selector:left_join("initiator", nil, { "initiator.initiative_id = initiative.id AND initiator.member_id = ? AND initiator.accepted", options.member_id }) bsw@551: selector:add_field("initiator.member_id NOTNULL", "initiated") bsw@551: bsw@551: return selector bsw@551: end bsw@551: } bsw@551: bsw@551: function Initiative.list:load_everything_for_member_id(member_id) bsw@551: if member_id then bsw@551: self:load("member_info", { member_id = member_id }) bsw@551: end bsw@551: end bsw@551: bsw@551: function Initiative.object:load_everything_for_member_id(member_id) bsw@551: if member_id then bsw@551: self:load("member_info", { member_id = member_id }) bsw@551: end bsw@551: end bsw@551: bsw@558: function Initiative:selector_for_updated_drafts(member_id) bsw@558: return Initiative:new_selector() bsw@558: :join("issue", "_issue_state", "_issue_state.id = initiative.issue_id AND _issue_state.closed ISNULL AND _issue_state.fully_frozen ISNULL") bsw@558: :join("current_draft", "_current_draft", "_current_draft.initiative_id = initiative.id") bsw@558: :join("supporter", "supporter", { "supporter.member_id = ? AND supporter.initiative_id = initiative.id AND supporter.draft_id < _current_draft.id", member_id }) bsw@558: :add_where("initiative.revoked ISNULL") bsw@558: end bsw@2: bsw@1045: function Initiative:getSpecialSelector( args ) bsw@1045: local selector = Initiative:new_selector() bsw@1045: selector:join( "issue", nil, "issue.id = initiative.issue_id" ) bsw@1045: selector:join( "area", nil, "area.id = issue.area_id" ) bsw@1045: if args.area_id then bsw@1045: selector:add_where{ "area.id = ?", args.area_id } bsw@1045: elseif args.unit_id then bsw@1045: selector:add_where{ "area.unit_id = ?", args.unit_id } bsw@1045: end bsw@1045: selector:limit( 1 ) bsw@1045: selector:optional_object_mode() bsw@1045: return selector bsw@1045: end bsw@1045: bsw@1045: function Initiative:getLastWinner( args ) bsw@1045: local selector = Initiative:getSpecialSelector( args ) bsw@1045: selector:add_where( "issue.state = 'finished_with_winner'" ) bsw@1045: selector:add_order_by( "issue.closed DESC, id DESC" ) bsw@1045: return selector:exec() bsw@1045: end bsw@1045: bsw@1045: function Initiative:getLastLoser( args ) bsw@1045: local selector = Initiative:getSpecialSelector( args ) bsw@1045: selector:add_where( "issue.state = 'finished_without_winner'" ) bsw@1045: selector:add_order_by( "issue.closed DESC, id DESC" ) bsw@1045: return selector:exec() bsw@1045: end bsw@1045: bsw@1045: function Initiative:getNextEndingVoting( args ) bsw@1045: local selector = Initiative:getSpecialSelector( args ) bsw@1045: selector:add_where( "issue.state = 'voting'" ) bsw@1045: selector:add_order_by( "issue.fully_frozen + issue.verification_time DESC, id DESC" ) bsw@1045: return selector:exec() bsw@1045: end bsw@1045: bsw@1045: function Initiative:getNextEndingVerification( args ) bsw@1045: local selector = Initiative:getSpecialSelector( args ) bsw@1045: selector:add_where( "issue.state = 'verification'" ) bsw@1045: selector:add_order_by( "issue.half_frozen + issue.verification_time DESC, id DESC" ) bsw@1045: return selector:exec() bsw@1045: end bsw@1045: bsw@1045: function Initiative:getNextEndingDiscussion( args ) bsw@1045: local selector = Initiative:getSpecialSelector( args ) bsw@1045: selector:add_where( "issue.state = 'discussion'" ) bsw@1045: selector:add_order_by( "issue.accepted + issue.discussion_time DESC, id DESC" ) bsw@1045: return selector:exec() bsw@1045: end bsw@1045: bsw@1045: function Initiative:getBestInAdmission( args ) bsw@1045: local selector = Initiative:getSpecialSelector( args ) bsw@1045: selector:add_where( "issue.state = 'admission'" ) bsw@1234: selector:add_order_by( "issue.created + issue.max_admission_time DESC, id DESC" ) bsw@1045: return selector:exec() bsw@1045: end bsw@2: bsw/jbe@0: function Initiative.object_get:current_draft() bsw/jbe@0: return Draft:new_selector() bsw/jbe@0: :add_where{ '"initiative_id" = ?', self.id } bsw/jbe@0: :add_order_by('"id" DESC') bsw/jbe@0: :single_object_mode() bsw/jbe@0: :exec() bsw/jbe@0: end bsw/jbe@0: bsw/jbe@0: function Initiative.object_get:shortened_name() bsw/jbe@0: local name = self.name bsw/jbe@0: if #name > 100 then bsw/jbe@0: name = name:sub(1,100) .. "..." bsw/jbe@0: end bsw/jbe@0: return name bsw/jbe@0: end bsw/jbe@52: bsw@1045: function Initiative.object_get:display_name() bsw@1045: return "i" .. self.id .. ": " .. self.name bsw@1045: end bsw@1045: bsw/jbe@52: function Initiative.object_get:initiator_names() bsw/jbe@52: local members = Member:new_selector() bsw/jbe@52: :join("initiator", nil, "initiator.member_id = member.id") bsw/jbe@52: :add_where{ "initiator.initiative_id = ?", self.id } bsw/jbe@52: :add_where{ "initiator.accepted" } bsw/jbe@52: :exec() bsw/jbe@52: bsw/jbe@52: local member_names = {} bsw/jbe@52: for i, member in ipairs(members) do bsw/jbe@52: member_names[#member_names+1] = member.name bsw/jbe@52: end bsw/jbe@52: return member_names bsw/jbe@52: end bsw/jbe@52: bsw@1045: function Initiative.object_get:potential_supporter_count() bsw@1045: if self.supporter_count and self.satisfied_supporter_count then bsw@1045: return self.supporter_count - self.satisfied_supporter_count bsw@1045: end bsw@1045: end