| rev | 
   line source | 
| 
bsw/jbe@0
 | 
     1 local issue
 | 
| 
bsw/jbe@0
 | 
     2 local area
 | 
| 
bsw/jbe@0
 | 
     3 
 | 
| 
bsw/jbe@0
 | 
     4 local issue_id = param.get("issue_id", atom.integer)
 | 
| 
bsw/jbe@0
 | 
     5 if issue_id then
 | 
| 
bsw@969
 | 
     6   issue = Issue:new_selector():add_where{"id=?",issue_id}:for_share():single_object_mode():exec()
 | 
| 
bsw/jbe@5
 | 
     7   if issue.closed then
 | 
| 
bsw/jbe@5
 | 
     8     slot.put_into("error", _"This issue is already closed.")
 | 
| 
bsw/jbe@5
 | 
     9     return false
 | 
| 
bsw/jbe@5
 | 
    10   elseif issue.fully_frozen then 
 | 
| 
bsw/jbe@5
 | 
    11     slot.put_into("error", _"Voting for this issue has already begun.")
 | 
| 
bsw/jbe@5
 | 
    12     return false
 | 
| 
bsw@967
 | 
    13   elseif issue.phase_finished then
 | 
| 
bsw@967
 | 
    14     slot.put_into("error", _"Current phase is already closed.")
 | 
| 
bsw@967
 | 
    15     return false
 | 
| 
bsw/jbe@5
 | 
    16   end
 | 
| 
bsw/jbe@0
 | 
    17   area = issue.area
 | 
| 
bsw/jbe@0
 | 
    18 else
 | 
| 
bsw/jbe@0
 | 
    19   local area_id = param.get("area_id", atom.integer)
 | 
| 
bsw/jbe@0
 | 
    20   area = Area:new_selector():add_where{"id=?",area_id}:single_object_mode():exec()
 | 
| 
bsw/jbe@52
 | 
    21   if not area.active then
 | 
| 
bsw/jbe@52
 | 
    22     slot.put_into("error", "Invalid area.")
 | 
| 
bsw/jbe@52
 | 
    23     return false
 | 
| 
bsw/jbe@52
 | 
    24   end
 | 
| 
bsw/jbe@0
 | 
    25 end
 | 
| 
bsw/jbe@0
 | 
    26 
 | 
| 
bsw@281
 | 
    27 if not app.session.member:has_voting_right_for_unit_id(area.unit_id) then
 | 
| 
bsw/jbe@1309
 | 
    28   return execute.view { module = "index", view = "403" }
 | 
| 
bsw@281
 | 
    29 end
 | 
| 
bsw@281
 | 
    30 
 | 
| 
bsw@904
 | 
    31 local policy_id = param.get("policy_id", atom.integer)
 | 
| 
bsw@904
 | 
    32 local policy
 | 
| 
bsw@904
 | 
    33 if policy_id then
 | 
| 
bsw@904
 | 
    34   policy = Policy:by_id(policy_id)
 | 
| 
bsw@904
 | 
    35 end
 | 
| 
bsw@904
 | 
    36 
 | 
| 
bsw@904
 | 
    37 if not issue then
 | 
| 
bsw@904
 | 
    38   if policy_id == -1 then
 | 
| 
bsw@904
 | 
    39     slot.put_into("error", _"Please choose a policy")
 | 
| 
bsw@904
 | 
    40     return false
 | 
| 
bsw@904
 | 
    41   end
 | 
| 
bsw@904
 | 
    42   if not policy.active then
 | 
| 
bsw@904
 | 
    43     slot.put_into("error", "Invalid policy.")
 | 
| 
bsw@904
 | 
    44     return false
 | 
| 
bsw@904
 | 
    45   end
 | 
| 
bsw@904
 | 
    46   if policy.polling and not app.session.member:has_polling_right_for_unit_id(area.unit_id) then
 | 
| 
bsw/jbe@1309
 | 
    47     return execute.view { module = "index", view = "403" }
 | 
| 
bsw@904
 | 
    48   end
 | 
| 
bsw@904
 | 
    49   if not area:get_reference_selector("allowed_policies")
 | 
| 
bsw@904
 | 
    50     :add_where{ "policy.id = ?", policy_id }
 | 
| 
bsw@904
 | 
    51     :optional_object_mode()
 | 
| 
bsw@904
 | 
    52     :exec()
 | 
| 
bsw@904
 | 
    53   then
 | 
| 
bsw/jbe@1309
 | 
    54     slot.put_into("error", "policy not allowed")
 | 
| 
bsw/jbe@1309
 | 
    55     return false
 | 
| 
bsw@904
 | 
    56   end
 | 
| 
bsw@904
 | 
    57 end
 | 
| 
bsw@904
 | 
    58 
 | 
| 
bsw@904
 | 
    59 local is_polling = (issue and param.get("polling", atom.boolean)) or (policy and policy.polling) or false
 | 
| 
bsw@904
 | 
    60 
 | 
| 
bsw@904
 | 
    61 local tmp = db:query({ "SELECT text_entries_left, initiatives_left FROM member_contingent_left WHERE member_id = ? AND polling = ?", app.session.member.id, is_polling }, "opt_object")
 | 
| 
bsw@904
 | 
    62 if not tmp or tmp.initiatives_left < 1 then
 | 
| 
bsw@904
 | 
    63   slot.put_into("error", _"Sorry, your contingent for creating initiatives has been used up. Please try again later.")
 | 
| 
bsw@904
 | 
    64   return false
 | 
| 
bsw@904
 | 
    65 end
 | 
| 
bsw@904
 | 
    66 if tmp and tmp.text_entries_left < 1 then
 | 
| 
bsw@904
 | 
    67   slot.put_into("error", _"Sorry, you have reached your personal flood limit. Please be slower...")
 | 
| 
bsw@904
 | 
    68   return false
 | 
| 
bsw@904
 | 
    69 end
 | 
| 
bsw@904
 | 
    70 
 | 
| 
bsw/jbe@6
 | 
    71 local name = param.get("name")
 | 
| 
bsw/jbe@6
 | 
    72 
 | 
| 
bsw/jbe@6
 | 
    73 local name = util.trim(name)
 | 
| 
bsw/jbe@6
 | 
    74 
 | 
| 
bsw/jbe@6
 | 
    75 if #name < 3 then
 | 
| 
bsw@1045
 | 
    76   slot.put_into("error", _"Please enter a meaningful title for your initiative!")
 | 
| 
bsw@1045
 | 
    77   return false
 | 
| 
bsw@1045
 | 
    78 end
 | 
| 
bsw@1045
 | 
    79 
 | 
| 
bsw@1045
 | 
    80 if #name > 140 then
 | 
| 
bsw@1045
 | 
    81   slot.put_into("error", _"This title is too long!")
 | 
| 
bsw/jbe@6
 | 
    82   return false
 | 
| 
bsw/jbe@6
 | 
    83 end
 | 
| 
bsw/jbe@6
 | 
    84 
 | 
| 
bsw@1092
 | 
    85 local timing
 | 
| 
bsw@1096
 | 
    86 if not issue and policy.free_timeable then
 | 
| 
bsw@1092
 | 
    87   local free_timing_string = util.trim(param.get("free_timing"))
 | 
| 
bsw@1092
 | 
    88   if not free_timing_string or #free_timing_string < 1 then
 | 
| 
bsw@1092
 | 
    89     slot.put_into("error", _"Choose timing")
 | 
| 
bsw@1092
 | 
    90     return false
 | 
| 
bsw@1092
 | 
    91   end
 | 
| 
bsw@1092
 | 
    92   local available_timings
 | 
| 
bsw@1092
 | 
    93   if config.free_timing and config.free_timing.available_func then
 | 
| 
bsw@1092
 | 
    94     available_timings = config.free_timing.available_func(policy)
 | 
| 
bsw@1092
 | 
    95     if available_timings == false then
 | 
| 
bsw/jbe@1309
 | 
    96       slot.put_into("error", "error in free timing config")
 | 
| 
bsw/jbe@1309
 | 
    97       return false
 | 
| 
bsw@1092
 | 
    98     end
 | 
| 
bsw@1092
 | 
    99   end
 | 
| 
bsw@1092
 | 
   100   if available_timings then
 | 
| 
bsw@1092
 | 
   101     local timing_available = false
 | 
| 
bsw@1092
 | 
   102     for i, available_timing in ipairs(available_timings) do
 | 
| 
bsw@1092
 | 
   103       if available_timing.id == free_timing_string then
 | 
| 
bsw@1092
 | 
   104 	timing_available = true
 | 
| 
bsw@1092
 | 
   105       end
 | 
| 
bsw@1092
 | 
   106     end
 | 
| 
bsw@1092
 | 
   107     if not timing_available then
 | 
| 
bsw@1092
 | 
   108       slot.put_into("error", _"Invalid timing")
 | 
| 
bsw@1092
 | 
   109       return false
 | 
| 
bsw@1092
 | 
   110     end
 | 
| 
bsw@1092
 | 
   111   end
 | 
| 
bsw@1092
 | 
   112   timing = config.free_timing.calculate_func(policy, free_timing_string)
 | 
| 
bsw@1092
 | 
   113   if not timing then
 | 
| 
bsw/jbe@1309
 | 
   114     slot.put_into("error", "error in free timing config")
 | 
| 
bsw/jbe@1309
 | 
   115     return false
 | 
| 
bsw@1092
 | 
   116   end
 | 
| 
bsw@1092
 | 
   117 end
 | 
| 
bsw@1092
 | 
   118 
 | 
| 
bsw/jbe@1309
 | 
   119 local draft_text = param.get("draft")
 | 
| 
bsw/jbe@1309
 | 
   120 
 | 
| 
bsw/jbe@1309
 | 
   121 if not draft_text then
 | 
| 
bsw/jbe@1309
 | 
   122   return false
 | 
| 
bsw/jbe@1309
 | 
   123 end
 | 
| 
bsw/jbe@1309
 | 
   124 
 | 
| 
bsw/jbe@1309
 | 
   125 local draft_text = util.wysihtml_preproc(draft_text)
 | 
| 
bsw/jbe@1309
 | 
   126 
 | 
| 
bsw/jbe@1309
 | 
   127 local valid_html, error_message = util.html_is_safe(draft_text)
 | 
| 
bsw/jbe@1309
 | 
   128 if not valid_html then
 | 
| 
bsw/jbe@1309
 | 
   129   slot.put_into("error", _("Draft contains invalid formatting or character sequence: #{error_message}", { error_message = error_message }) )
 | 
| 
bsw/jbe@1309
 | 
   130   return false
 | 
| 
bsw/jbe@1309
 | 
   131 end
 | 
| 
bsw/jbe@1309
 | 
   132 
 | 
| 
bsw/jbe@1309
 | 
   133 if config.initiative_abstract then
 | 
| 
bsw/jbe@1309
 | 
   134   local abstract = param.get("abstract")
 | 
| 
bsw/jbe@1309
 | 
   135   if not abstract then
 | 
| 
bsw/jbe@1309
 | 
   136     return false
 | 
| 
bsw/jbe@1309
 | 
   137   end
 | 
| 
bsw/jbe@1309
 | 
   138   abstract = encode.html(abstract)
 | 
| 
bsw/jbe@1309
 | 
   139   draft_text = abstract .. "<!--END_OF_ABSTRACT-->" .. draft_text
 | 
| 
bsw/jbe@1309
 | 
   140 end
 | 
| 
bsw/jbe@1309
 | 
   141 
 | 
| 
bsw/jbe@1309
 | 
   142 local location = param.get("location")
 | 
| 
bsw/jbe@1309
 | 
   143 if location == "" then
 | 
| 
bsw/jbe@1309
 | 
   144   location = nil
 | 
| 
bsw/jbe@1309
 | 
   145 end
 | 
| 
bsw/jbe@1309
 | 
   146 
 | 
| 
bsw@1045
 | 
   147 if param.get("preview") or param.get("edit") then
 | 
| 
bsw@95
 | 
   148   return
 | 
| 
bsw@95
 | 
   149 end
 | 
| 
bsw@81
 | 
   150 
 | 
| 
bsw/jbe@0
 | 
   151 local initiative = Initiative:new()
 | 
| 
bsw/jbe@0
 | 
   152 
 | 
| 
bsw/jbe@0
 | 
   153 if not issue then
 | 
| 
bsw/jbe@0
 | 
   154   issue = Issue:new()
 | 
| 
bsw/jbe@0
 | 
   155   issue.area_id = area.id
 | 
| 
bsw@7
 | 
   156   issue.policy_id = policy_id
 | 
| 
bsw@898
 | 
   157   
 | 
| 
bsw@898
 | 
   158   if policy.polling then
 | 
| 
bsw@898
 | 
   159     issue.accepted = 'now'
 | 
| 
bsw@898
 | 
   160     issue.state = 'discussion'
 | 
| 
bsw@898
 | 
   161     initiative.polling = true
 | 
| 
bsw@901
 | 
   162     
 | 
| 
bsw@901
 | 
   163     if policy.free_timeable then
 | 
| 
bsw@901
 | 
   164       issue.discussion_time = timing.discussion
 | 
| 
bsw@901
 | 
   165       issue.verification_time = timing.verification
 | 
| 
bsw@901
 | 
   166       issue.voting_time = timing.voting
 | 
| 
bsw@901
 | 
   167     end
 | 
| 
bsw@901
 | 
   168     
 | 
| 
bsw@898
 | 
   169   end
 | 
| 
bsw@898
 | 
   170   
 | 
| 
bsw/jbe@0
 | 
   171   issue:save()
 | 
| 
bsw@286
 | 
   172 
 | 
| 
bsw@286
 | 
   173   if config.etherpad then
 | 
| 
bsw@286
 | 
   174     local result = net.curl(
 | 
| 
bsw@286
 | 
   175       config.etherpad.api_base 
 | 
| 
bsw@286
 | 
   176       .. "api/1/createGroupPad?apikey=" .. config.etherpad.api_key
 | 
| 
bsw@286
 | 
   177       .. "&groupID=" .. config.etherpad.group_id
 | 
| 
bsw@286
 | 
   178       .. "&padName=Issue" .. tostring(issue.id)
 | 
| 
jbe@326
 | 
   179       .. "&text=" .. request.get_absolute_baseurl() .. "issue/show/" .. tostring(issue.id) .. ".html"
 | 
| 
bsw@286
 | 
   180     )
 | 
| 
bsw@286
 | 
   181   end
 | 
| 
bsw/jbe@0
 | 
   182 end
 | 
| 
bsw/jbe@0
 | 
   183 
 | 
| 
bsw@898
 | 
   184 if param.get("polling", atom.boolean) and app.session.member:has_polling_right_for_unit_id(area.unit_id) then
 | 
| 
bsw@898
 | 
   185   initiative.polling = true
 | 
| 
bsw@898
 | 
   186 end
 | 
| 
bsw/jbe@0
 | 
   187 initiative.issue_id = issue.id
 | 
| 
bsw/jbe@6
 | 
   188 initiative.name = name
 | 
| 
bsw/jbe@0
 | 
   189 initiative:save()
 | 
| 
bsw/jbe@0
 | 
   190 
 | 
| 
bsw/jbe@0
 | 
   191 local draft = Draft:new()
 | 
| 
bsw/jbe@0
 | 
   192 draft.initiative_id = initiative.id
 | 
| 
bsw/jbe@4
 | 
   193 draft.formatting_engine = formatting_engine
 | 
| 
bsw/jbe@1309
 | 
   194 draft.content = draft_text
 | 
| 
bsw/jbe@1309
 | 
   195 draft.location = location
 | 
| 
bsw/jbe@0
 | 
   196 draft.author_id = app.session.member.id
 | 
| 
bsw/jbe@0
 | 
   197 draft:save()
 | 
| 
bsw/jbe@0
 | 
   198 
 | 
| 
bsw/jbe@0
 | 
   199 local initiator = Initiator:new()
 | 
| 
bsw/jbe@0
 | 
   200 initiator.initiative_id = initiative.id
 | 
| 
bsw/jbe@0
 | 
   201 initiator.member_id = app.session.member.id
 | 
| 
bsw@10
 | 
   202 initiator.accepted = true
 | 
| 
bsw/jbe@0
 | 
   203 initiator:save()
 | 
| 
bsw/jbe@0
 | 
   204 
 | 
| 
bsw@944
 | 
   205 if not is_polling then
 | 
| 
bsw@944
 | 
   206   local supporter = Supporter:new()
 | 
| 
bsw@944
 | 
   207   supporter.initiative_id = initiative.id
 | 
| 
bsw@944
 | 
   208   supporter.member_id = app.session.member.id
 | 
| 
bsw@944
 | 
   209   supporter.draft_id = draft.id
 | 
| 
bsw@944
 | 
   210   supporter:save()
 | 
| 
bsw@944
 | 
   211 end
 | 
| 
bsw/jbe@0
 | 
   212 
 | 
| 
bsw/jbe@0
 | 
   213 slot.put_into("notice", _"Initiative successfully created")
 | 
| 
bsw/jbe@0
 | 
   214 
 | 
| 
bsw/jbe@0
 | 
   215 request.redirect{
 | 
| 
bsw/jbe@0
 | 
   216   module = "initiative",
 | 
| 
bsw/jbe@0
 | 
   217   view = "show",
 | 
| 
bsw/jbe@0
 | 
   218   id = initiative.id
 | 
| 
jbe@326
 | 
   219 }
 |