Skip to content

Commit

Permalink
voting_phase: vote start/end config
Browse files Browse the repository at this point in the history
The number of days before the target date when voting starts can be configured
in voting phases and their voting phase types as a fallback.
  • Loading branch information
dpausp committed Jul 10, 2021
1 parent 40b17b0 commit d916d8c
Show file tree
Hide file tree
Showing 11 changed files with 173 additions and 64 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""voting_days for VotingPhase and VotingPhaseType
Revision ID: ec225b9c33e3
Revises: 50a310f352b0
Create Date: 2021-07-10 16:11:51.416233
"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'ec225b9c33e3'
down_revision = '50a310f352b0'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
'voting_phase_types',
sa.Column('voting_days', sa.Integer(), nullable=True, comment='voting duration in days; ends at target date')
)
op.add_column(
'votingphases',
sa.Column('voting_days', sa.Integer(), nullable=True, comment='voting duration in days; ends at target date')
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('votingphases', 'voting_days')
op.drop_column('voting_phase_types', 'voting_days')
# ### end Alembic commands ###
21 changes: 11 additions & 10 deletions src/ekklesia_portal/concepts/voting_phase/voting_phase_cells.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,17 @@ def show_new_button(self):
@App.cell(VotingPhase)
class VotingPhaseCell(LayoutCell):
model_properties = [
'ballots', 'department', 'description', 'name', 'phase_type', 'secret', 'status', 'target', 'title'
'ballots',
'department',
'description',
'name',
'phase_type',
'secret',
'status',
'target',
'title',
'voting_end',
'voting_start',
]

def show_edit_button(self):
Expand All @@ -43,15 +53,6 @@ def show_voting(self):
def propositions(self):
return [p for b in self._model.ballots for p in b.propositions]

def voting_start(self):
if self._model.target is None:
return
# XXX: Fixed time interval for voting! We need a proper setting here.
return self._model.target - datetime.timedelta(days=14)

def voting_end(self):
return self._model.target

def votings(self):
votings = []
for name, settings in self._model.department.voting_module_settings.items():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class VotingPhaseSchema(Schema):
department_id = int_property(title=_('department'))
phase_type_id = int_property(title=_('voting_phase_type'))
secret = bool_property(title=_('secret_voting_possible'))
voting_days = int_property(title=_('voting_days'), missing=None)
description = string_property(title=_('description'), validator=Length(min=10, max=65536), missing='')
voting_module_data = json_property(title=_('voting_module_data'), missing={})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
dd= abbreviation
dt= _('voting_type')
dd= voting_type|enum_value
if voting_days
dt= _('voting_days')
dd= voting_days
dt= _('secret_voting_possible')
dd= secret_voting_possible|yesno

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class VotingPhaseTypeCell(LayoutCell):
'name',
'secret_voting_possible',
'voting_type',
'voting_days',
]

def show_edit_button(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from colander import Length
from deform import Button
from deform.widget import Select2Widget, TextAreaWidget
from ekklesia_common.contract import Schema, Form, bool_property, string_property, enum_property
from ekklesia_common.contract import Schema, Form, bool_property, int_property, string_property, enum_property
from ekklesia_common.translation import _

from ekklesia_portal.enums import VotingType
Expand All @@ -12,6 +12,7 @@ class VotingPhaseTypeSchema(Schema):
abbreviation = string_property(title=_('abbreviation'), validator=Length(max=6))
secret_voting_possible = bool_property(title=_('secret_voting_possible'))
voting_type = enum_property(VotingType, title=_('voting_type'))
voting_days = int_property(title=_('voting_days'), missing=None)
description = string_property(title=_('description'), validator=Length(min=10, max=2000), missing='')


Expand Down
34 changes: 27 additions & 7 deletions src/ekklesia_portal/datamodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# For more details see the file COPYING.

from datetime import datetime
from datetime import datetime, timedelta
import math

from ekklesia_common.database import Base, C, LIDType, integer_pk
Expand Down Expand Up @@ -49,7 +49,9 @@ class Group(Base):
id: int = C(Integer, Sequence('id_seq', optional=True), primary_key=True)
name: str = C(Text, unique=True, nullable=False)
is_admin_group: bool = C(Boolean, nullable=False, server_default='false')
members = association_proxy('group_members', 'member', creator=lambda u: GroupMember(member=u)) # <-GroupMember-> User
members = association_proxy(
'group_members', 'member', creator=lambda u: GroupMember(member=u)
) # <-GroupMember-> User


class User(Base):
Expand All @@ -73,7 +75,9 @@ class User(Base):
)
# actions: submit/support proposition, voting, or explicit, deactivate after 2 periods
profile = relationship("UserProfile", uselist=False, back_populates="user")
groups = association_proxy('member_groups', 'group', creator=lambda g: GroupMember(group=g)) # <-GroupMember-> Group
groups = association_proxy(
'member_groups', 'group', creator=lambda g: GroupMember(group=g)
) # <-GroupMember-> Group
# from user/membership/ all_nested_groups
departments = association_proxy('member_departments', 'department') # <-DepartmentMember-> Department
areas = association_proxy('member_areas', 'area') # <-AreaMember-> SubjectArea
Expand Down Expand Up @@ -318,19 +322,19 @@ class VotingPhaseType(Base):
abbreviation: str = C(Text, server_default='', comment='abbreviated name')
secret_voting_possible: bool = C(Boolean, nullable=False)
voting_type = C(Enum(VotingType), nullable=False) # online, urn, assembly, board
voting_days: int = C(Integer, comment='voting duration in days; ends at target date')
description: str = C(Text, server_default='')


class VotingPhase(Base): # Abstimmungsperiode
__tablename__ = 'votingphases'
__table_args__ = (
CheckConstraint(
"status='PREPARING' OR (status!='PREPARING' AND target IS NOT NULL)", 'state_valid'
),
CheckConstraint("status='PREPARING' OR (status!='PREPARING' AND target IS NOT NULL)", 'state_valid'),
)
id: int = C(Integer, Sequence('id_seq', optional=True), primary_key=True)
status: VotingStatus = C(Enum(VotingStatus), nullable=False, server_default='PREPARING')
target: datetime = C(DateTime, comment='constrained by §4.1')
voting_days: int = C(Integer, comment='voting duration in days; ends at target date')
department_id: int = C(Integer, ForeignKey('departments.id'), nullable=False)
phase_type_id: int = C(Integer, ForeignKey('voting_phase_types.id'), nullable=False)
secret: bool = C(
Expand Down Expand Up @@ -361,7 +365,23 @@ def ballots_can_be_added(self):

@property
def voting_can_be_created(self):
return self.status == VotingStatus.PREPARING and self.target is not None
return self.status == VotingStatus.PREPARING and self.voting_start is not None and self.voting_end is not None

@property
def voting_start(self):
if self.target is None:
return

days = self.voting_days or self.phase_type.voting_days

if days is None:
return

return self.target - timedelta(days=days)

@property
def voting_end(self):
return self.target


class Supporter(Base): # §3.5
Expand Down
43 changes: 27 additions & 16 deletions src/ekklesia_portal/translations/de/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2021-07-06 23:07+0000\n"
"POT-Creation-Date: 2021-07-10 22:49+0000\n"
"PO-Revision-Date: 2015-09-06 22:42+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: de\n"
Expand Down Expand Up @@ -50,8 +50,8 @@ msgstr "Ausführlich"
#: src/ekklesia_portal/concepts/proposition_type/proposition_type_contracts.py:18
#: src/ekklesia_portal/concepts/subject_area/subject_area_contracts.py:17
#: src/ekklesia_portal/concepts/user/user_contracts.py:18
#: src/ekklesia_portal/concepts/voting_phase/voting_phase_contracts.py:25
#: src/ekklesia_portal/concepts/voting_phase_type/voting_phase_type_contracts.py:21
#: src/ekklesia_portal/concepts/voting_phase/voting_phase_contracts.py:26
#: src/ekklesia_portal/concepts/voting_phase_type/voting_phase_type_contracts.py:22
msgid "submit"
msgstr "Senden"

Expand Down Expand Up @@ -301,9 +301,9 @@ msgstr "Neue Textanpassung"
#: src/ekklesia_portal/concepts/proposition_type/templates/proposition_type.j2.jade:12
#: src/ekklesia_portal/concepts/subject_area/subject_area_contracts.py:11
#: src/ekklesia_portal/concepts/subject_area/templates/subject_area.j2.jade:12
#: src/ekklesia_portal/concepts/voting_phase/voting_phase_contracts.py:18
#: src/ekklesia_portal/concepts/voting_phase_type/templates/voting_phase_type.j2.jade:19
#: src/ekklesia_portal/concepts/voting_phase_type/voting_phase_type_contracts.py:15
#: src/ekklesia_portal/concepts/voting_phase/voting_phase_contracts.py:19
#: src/ekklesia_portal/concepts/voting_phase_type/templates/voting_phase_type.j2.jade:21
#: src/ekklesia_portal/concepts/voting_phase_type/voting_phase_type_contracts.py:16
msgid "description"
msgstr "Beschreibung"

Expand Down Expand Up @@ -571,7 +571,7 @@ msgstr "Minimale Anzahl an Unterstützern"

#: src/ekklesia_portal/concepts/policy/policy_contracts.py:16
#: src/ekklesia_portal/concepts/policy/templates/policy.j2.jade:16
#: src/ekklesia_portal/concepts/proposition/templates/proposition_support_action.j2.jade:13
#: src/ekklesia_portal/concepts/proposition/templates/proposition_support.j2.jade:15
msgid "qualification_quorum"
msgstr "Unterstützer-Quorum zur Zulassung zur Abstimmung"

Expand Down Expand Up @@ -787,24 +787,24 @@ msgstr "Begründung"
msgid "changes"
msgstr "Änderungen"

#: src/ekklesia_portal/concepts/proposition/templates/proposition_secret_voting_action.j2.jade:5
#: src/ekklesia_portal/concepts/proposition/templates/proposition_secret_voting.j2.jade:5
msgid "button_retract_secret_voting"
msgstr "Forderung auf Papierabstimmung zurückziehen"

#: src/ekklesia_portal/concepts/proposition/templates/proposition_secret_voting_action.j2.jade:8
#: src/ekklesia_portal/concepts/proposition/templates/proposition_secret_voting.j2.jade:8
msgid "button_request_secret_voting"
msgstr "Papierabstimmung fordern"

#: src/ekklesia_portal/concepts/proposition/templates/proposition_secret_voting_action.j2.jade:13
#: src/ekklesia_portal/concepts/proposition/templates/proposition_secret_voting.j2.jade:13
msgid "abbr_secret_voters_count"
msgstr "Anzahl Befürworter für Papierabstimmung"

#: src/ekklesia_portal/concepts/proposition/templates/proposition_secret_voting_action.j2.jade:13
#: src/ekklesia_portal/concepts/proposition/templates/proposition_secret_voting.j2.jade:13
msgid "abbr_secret_voting_quorum"
msgstr "Quorum für Papierabstimmung"

#: src/ekklesia_portal/concepts/proposition/templates/proposition_small.j2.jade:10
#: src/ekklesia_portal/concepts/proposition/templates/proposition_support_action.j2.jade:13
#: src/ekklesia_portal/concepts/proposition/templates/proposition_support.j2.jade:15
#: src/ekklesia_portal/concepts/proposition/templates/status/proposition_status_scheduled.j2.jade:2
#: src/ekklesia_portal/concepts/proposition/templates/status/proposition_status_submitted.j2.jade:2
msgid "supporter"
Expand Down Expand Up @@ -836,14 +836,19 @@ msgstr ""
msgid "title_notice"
msgstr "Hinweis"

#: src/ekklesia_portal/concepts/proposition/templates/proposition_support_action.j2.jade:5
#: src/ekklesia_portal/concepts/proposition/templates/proposition_support.j2.jade:5
msgid "button_retract_support"
msgstr "Unterstützung zurückziehen"

#: src/ekklesia_portal/concepts/proposition/templates/proposition_support_action.j2.jade:8
#: src/ekklesia_portal/concepts/proposition/templates/proposition_support.j2.jade:8
msgid "button_support"
msgstr "Unterstützen"

#: src/ekklesia_portal/concepts/proposition/templates/proposition_support.j2.jade:10
#: src/ekklesia_portal/concepts/proposition/templates/proposition_support.j2.jade:19
msgid "supporters"
msgstr "Unterstützer"

#: src/ekklesia_portal/concepts/proposition/templates/propositions.j2.jade:6
msgid "btn_sort_by_identifier_or_title"
msgstr "Nach Kennung/Titel sortieren"
Expand Down Expand Up @@ -1238,12 +1243,18 @@ msgid "voting_phase_type"
msgstr "Art des Abstimmungszeitraums"

#: src/ekklesia_portal/concepts/voting_phase/voting_phase_contracts.py:17
#: src/ekklesia_portal/concepts/voting_phase_type/templates/voting_phase_type.j2.jade:15
#: src/ekklesia_portal/concepts/voting_phase_type/templates/voting_phase_type.j2.jade:17
#: src/ekklesia_portal/concepts/voting_phase_type/voting_phase_type_contracts.py:13
msgid "secret_voting_possible"
msgstr "Geheime Abstimmung möglich?"

#: src/ekklesia_portal/concepts/voting_phase/voting_phase_contracts.py:19
#: src/ekklesia_portal/concepts/voting_phase/voting_phase_contracts.py:18
#: src/ekklesia_portal/concepts/voting_phase_type/templates/voting_phase_type.j2.jade:15
#: src/ekklesia_portal/concepts/voting_phase_type/voting_phase_type_contracts.py:15
msgid "voting_days"
msgstr "Dauer der Abstimmung in Tagen"

#: src/ekklesia_portal/concepts/voting_phase/voting_phase_contracts.py:20
msgid "voting_module_data"
msgstr "Daten für externe Abstimmungssysteme"

Expand Down
Loading

0 comments on commit d916d8c

Please sign in to comment.