diff --git a/openslides/motion/pdf.py b/openslides/motion/pdf.py
new file mode 100644
index 000000000..bf048649c
--- /dev/null
+++ b/openslides/motion/pdf.py
@@ -0,0 +1,146 @@
+from reportlab.lib import colors
+from reportlab.lib.units import cm
+from reportlab.platypus import (
+ SimpleDocTemplate, PageBreak, Paragraph, Spacer, Table, TableStyle)
+from django.utils.translation import ugettext as _
+
+from openslides.config.models import config
+from openslides.utils.pdf import stylesheet
+
+from .models import Motion
+
+
+def motions_to_pdf(pdf):
+ motions = Motion.objects.all()
+ all_motion_cover(pdf, motions)
+ for motion in motions:
+ pdf.append(PageBreak())
+ motion_to_pdf(pdf, motion)
+
+def motion_to_pdf(pdf, motion):
+ pdf.append(Paragraph(_("Motion: %s") % motion.title, stylesheet['Heading1']))
+
+ motion_data = []
+
+ # submitter
+ cell1a = []
+ cell1a.append(Spacer(0, 0.2 * cm))
+ cell1a.append(Paragraph("%s:" % _("Submitter"), stylesheet['Heading4']))
+ cell1b = []
+ cell1b.append(Spacer(0, 0.2 * cm))
+ cell1b.append(Paragraph(unicode(motion.submitter), stylesheet['Normal']))
+ motion_data.append([cell1a, cell1b])
+
+ # TODO: choose this in workflow
+ if motion.state.edit_as_submitter:
+ # Cell for the signature
+ cell2a = []
+ cell2b = []
+ cell2a.append(Paragraph("%s:" % _("Signature"), stylesheet['Heading4']))
+ cell2b.append(Paragraph(42 * "_", stylesheet['Signaturefield']))
+ cell2b.append(Spacer(0, 0.1 * cm))
+ cell2b.append(Spacer(0, 0.2 * cm))
+ motion_data.append([cell2a, cell2b])
+
+ # supporters
+ if config['motion_min_supporters']:
+ cell3a = []
+ cell3b = []
+ cell3a.append(Paragraph("%s:" % _("Supporters"), stylesheet['Heading4']))
+ supporters = motion.supporter.all()
+ for supporter in supporters:
+ cell3b.append(Paragraph(". %s" % unicode(supporter), stylesheet['Signaturefield']))
+ if motion.state.support:
+ for count in range(config['motion_min_supporters'] - supporters.count()):
+ cell3b.append(Paragraph(". " + 42 * "_",stylesheet['Signaturefield']))
+ cell3b.append(Spacer(0, 0.2 * cm))
+ motion_data.append([cell3a, cell3b])
+
+ ## # status
+ ## cell4a = []
+ ## cell4b = []
+ ## note = " ".join(motion.notes)
+ ## cell4a.append(Paragraph("%s:" % _("Status"), stylesheet['Heading4']))
+ ## if note != "":
+ ## if motion.status == "pub":
+ ## cell4b.append(Paragraph(note, stylesheet['Normal']))
+ ## else:
+ ## cell4b.append(Paragraph("%s | %s" % (motion.get_status_display(), note), stylesheet['Normal']))
+ ## else:
+ ## cell4b.append(Paragraph("%s" % motion.get_status_display(), stylesheet['Normal']))
+ ## data.append([cell4a, cell4b])
+
+ # Motion state
+ cell4a = []
+ cell4b = []
+ cell4a.append(Paragraph("%s:" % _("State"), stylesheet['Heading4']))
+ cell4b.append(Paragraph(motion.state.name, stylesheet['Normal']))
+ motion_data.append([cell4a, cell4b])
+
+ # Version number (aid)
+ if motion.versions.count() > 1:
+ cell5a = []
+ cell5b = []
+ cell5a.append(Paragraph("%s:" % _("Version"), stylesheet['Heading4']))
+ cell5b.append(Paragraph("%s" % motion.version.version_number, stylesheet['Normal']))
+ motion_data.append([cell5a, cell5b])
+
+ # voting results
+ polls = []
+ for poll in motion.polls.all():
+ if not poll.has_votes():
+ continue
+ polls.append(poll)
+
+ if polls:
+ cell6a = []
+ cell6b = []
+ cell6a.append(Paragraph("%s:" % _("Vote results"), stylesheet['Heading4']))
+ ballotcounter = 0
+ for poll in polls:
+ ballotcounter += 1
+ option = poll.get_options()[0]
+ yes, no, abstain, invalid, votecast = (
+ option['Yes'], option['No'], option['Abstain'],
+ poll.print_voteinvalid(), poll.print_votecast())
+
+ if len(polls) > 1:
+ cell6b.append(Paragraph("%s. %s" % (ballotcounter, _("Vote")), stylesheet['Bold']))
+ cell6b.append(Paragraph(
+ "%s: %s
%s: %s
%s: %s
%s: %s
%s: %s" %
+ (_("Yes"), yes, _("No"), no, _("Abstention"), abstain, _("Invalid"),
+ invalid, _("Votes cast"), votecast), stylesheet['Normal']))
+ cell6b.append(Spacer(0, 0.2 * cm))
+ motion_data.append([cell6a, cell6b])
+
+ # Creating Table
+ table = Table(motion_data)
+ table._argW[0] = 4.5 * cm
+ table._argW[1] = 11 * cm
+ table.setStyle(TableStyle([('BOX', (0, 0), (-1, -1), 1, colors.black),
+ ('VALIGN', (0,0), (-1,-1), 'TOP')]))
+ pdf.append(table)
+ pdf.append(Spacer(0, 1 * cm))
+
+ pdf.append(Paragraph(motion.title, stylesheet['Heading3']))
+ pdf.append(Paragraph(motion.text.replace('\r\n','
'), stylesheet['Paragraph']))
+ if motion.reason:
+ pdf.append(Paragraph(_("Reason:"), stylesheet['Heading3']))
+ pdf.append(Paragraph(motion.reason.replace('\r\n','
'), stylesheet['Paragraph']))
+ return pdf
+
+
+def all_motion_cover(pdf, motions):
+ pdf.append(Paragraph(config["motion_pdf_title"], stylesheet['Heading1']))
+
+ preamble = config["motion_pdf_preamble"]
+ if preamble:
+ pdf.append(Paragraph("%s" % preamble.replace('\r\n','
'), stylesheet['Paragraph']))
+
+ pdf.append(Spacer(0, 0.75 * cm))
+
+ if not motions:
+ pdf.append(Paragraph(_("No motions available."), stylesheet['Heading3']))
+ else:
+ for motion in motions:
+ pdf.append(Paragraph(motion.title, stylesheet['Heading3']))
diff --git a/openslides/motion/urls.py b/openslides/motion/urls.py
index 6331439b0..883b4c953 100644
--- a/openslides/motion/urls.py
+++ b/openslides/motion/urls.py
@@ -92,4 +92,14 @@ urlpatterns = patterns('openslides.motion.views',
'create_agenda_item',
name='motion_create_agenda',
),
+
+ url(r'^pdf/$',
+ 'motion_list_pdf',
+ name='motion_list_pdf',
+ ),
+
+ url(r'^(?P\d+)/pdf/$',
+ 'motion_detail_pdf',
+ name='motion_detail_pdf',
+ ),
)
diff --git a/openslides/motion/views.py b/openslides/motion/views.py
index 3b13f9629..b562bf548 100644
--- a/openslides/motion/views.py
+++ b/openslides/motion/views.py
@@ -30,10 +30,12 @@ from openslides.projector.api import get_active_slide
from openslides.projector.projector import Widget, SLIDE
from openslides.config.models import config
from openslides.agenda.models import Item
+
from .models import Motion, MotionSubmitter, MotionSupporter, MotionPoll, MotionVersion
from .forms import (BaseMotionForm, MotionSubmitterMixin, MotionSupporterMixin,
MotionCreateNewVersionMixin, ConfigForm)
from .workflow import WorkflowError
+from .pdf import motions_to_pdf, motion_to_pdf
class MotionListView(ListView):
@@ -274,7 +276,7 @@ class PollCreateView(SingleObjectMixin, RedirectView):
def pre_redirect(self, request, *args, **kwargs):
self.poll = self.object.create_poll()
- self.object.write_log(ugettext_noop("Poll created"), user)
+ self.object.write_log(ugettext_noop("Poll created"), request.user)
messages.success(request, _("New vote was successfully created."))
def get_redirect_url(self, **kwargs):
@@ -370,6 +372,33 @@ class CreateAgendaItemView(SingleObjectMixin, RedirectView):
create_agenda_item = CreateAgendaItemView.as_view()
+class MotionPDFView(SingleObjectMixin, PDFView):
+ permission_required = 'motion.can_manage_motion'
+ model = Motion
+ top_space = 0
+ print_all_motions = False
+
+ def get(self, request, *args, **kwargs):
+ if not self.print_all_motions:
+ self.object = self.get_object()
+ return super(MotionPDFView, self).get(request, *args, **kwargs)
+
+ def get_filename(self):
+ if self.print_all_motions:
+ return _("Motions")
+ else:
+ return _("Motion: %s") % unicode(self.object)
+
+ def append_to_pdf(self, pdf):
+ if self.print_all_motions:
+ motions_to_pdf(pdf)
+ else:
+ motion_to_pdf(pdf, self.object)
+
+motion_list_pdf = MotionPDFView.as_view(print_all_motions=True)
+motion_detail_pdf = MotionPDFView.as_view(print_all_motions=False)
+
+
class Config(FormView):
permission_required = 'config.can_manage_config'
form_class = ConfigForm