diff --git a/cms/admin.py b/cms/admin.py index b614bb5..6d0329f 100644 --- a/cms/admin.py +++ b/cms/admin.py @@ -1,10 +1,5 @@ from django.contrib import admin -from .models import ( - Enseignant, Domaine, Competence, SousCompetence, Objectif, - Ressource, Module, Processus, Concept, UploadDoc -) - from .forms import ( ProcessusAdminForm, ProcessusInlineAdminForm, ModuleAdminForm, DomaineAdminForm, CompetenceAdminForm, SousCompetenceInlineAdminForm, @@ -12,6 +7,11 @@ from .forms import ( SousCompetenceAdminForm, ConceptAdminForm, UploadAdminForm ) +from .models import ( + Enseignant, Domaine, Competence, SousCompetence, Objectif, + Ressource, Module, Processus, Concept, UploadDoc +) + class SousCompetenceInline(admin.TabularInline): form = SousCompetenceInlineAdminForm diff --git a/cms/forms.py b/cms/forms.py index 5fd0b75..e6e9f55 100644 --- a/cms/forms.py +++ b/cms/forms.py @@ -16,7 +16,6 @@ class ConceptAdminForm(forms.ModelForm): class Meta: model = Concept fields = ('titre', 'texte', 'published') - widgets = { 'texte': TinyMCE(attrs={'cols': 120, 'rows': 30}), } diff --git a/cms/models.py b/cms/models.py index 935d67d..1de405e 100644 --- a/cms/models.py +++ b/cms/models.py @@ -137,7 +137,6 @@ class Competence(models.Model): type = models.CharField(max_length=35, blank=True, default='') module = models.ForeignKey(Module, null=True, blank=True, default=None, on_delete=models.SET_NULL) proces_eval = models.ForeignKey(Processus, null=True, default=True, on_delete=models.SET_NULL) - list_display = ('code', 'nom', 'type', 'proces_eval') class Meta: ordering = ('code',) @@ -197,7 +196,7 @@ class UploadDoc(models.Model): def __str__(self): return self.titre - +""" class PDFResponse(HttpResponse): def __init__(self, filename, title='', portrait=True): @@ -261,3 +260,4 @@ class MyDocTemplateLandscape(SimpleDocTemplate): self.canv.setFontSize(8) self.canv.drawCentredString(self.CENTRE_WIDTH, 1*cm, "Page : " + str(self.canv.getPageNumber())) self.canv.restoreState() +""" diff --git a/cms/pdf.py b/cms/pdf.py index dde48b8..2203f66 100644 --- a/cms/pdf.py +++ b/cms/pdf.py @@ -1,24 +1,126 @@ - -from reportlab.platypus import ( - SimpleDocTemplate, Spacer, Frame, Paragraph, Preformatted, PageTemplate, NextPageTemplate, - FrameBreak, Table, TableStyle -) -from reportlab.lib.pagesizes import A4, landscape -from reportlab.lib.units import cm -from reportlab.lib.enums import TA_LEFT -from reportlab.lib import colors -from reportlab.lib.styles import ParagraphStyle as ps -from reportlab.pdfgen import canvas +import os +import tempfile from django.contrib.staticfiles.finders import find from django.conf import settings +from reportlab.lib import colors +from reportlab.lib.enums import TA_LEFT, TA_CENTER +from reportlab.lib.pagesizes import A4, landscape +from reportlab.lib.units import cm +from reportlab.lib.styles import ParagraphStyle as ps +from reportlab.pdfgen import canvas + +from reportlab.platypus import (Frame, FrameBreak, Flowable, NextPageTemplate, + Paragraph, PageTemplate, Preformatted, Spacer, + SimpleDocTemplate, Table, TableStyle + ) + style_normal = ps(name='CORPS', fontName='Helvetica', fontSize=9, alignment=TA_LEFT) style_bold = ps(name='CORPS', fontName='Helvetica-Bold', fontSize=10, alignment=TA_LEFT) +style_footer = ps(name='CORPS', fontName='Helvetica', fontSize=7, alignment=TA_CENTER) LOGO_EPC = find('img/logo_EPC.png') LOGO_ESNE = find('img/logo_ESNE.png') -FILIERE = 'Formation EDS' +LOGO_EPC_LONG = find('img/header.gif') + + +class HorLine(Flowable): + """Horizontal Line flowable --- draws a line in a flowable""" + + def __init__(self, width): + Flowable.__init__(self) + self.width = width + + def __repr__(self): + return "Line(w=%s)" % self.width + + def draw(self): + self.canv.line(0, 0, self.width, 0) + + +class EpcBaseDocTemplate(SimpleDocTemplate): + points = '.' * 93 + + def __init__(self, filename, section='', title='', orientation=A4): + path = os.path.join(tempfile.gettempdir(), filename) + self.section = section + self.title = title + super().__init__( + path, + pagesize=orientation, + lefMargin=2.5 * cm, bottomMargin=1 * cm, topMargin=1 * cm, rightMargin=2.5 * cm + ) + self.page_frame = Frame( + self.leftMargin, self.bottomMargin, self.width - 2.5, self.height - 4 * cm, + id='first_table', showBoundary=0, leftPadding=0 * cm + ) + self.story = [] + #self.title = title + + def header(self, canvas, doc): + canvas.saveState() + canvas.drawImage( + LOGO_EPC, doc.leftMargin, doc.height - 1.5 * cm, 5 * cm, 3 * cm, preserveAspectRatio=True + ) + canvas.drawImage( + LOGO_ESNE, doc.width - 2.5 * cm, doc.height - 1.2 * cm, 5 * cm, 3 * cm, preserveAspectRatio=True + ) + + x = doc.leftMargin + y = doc.height - 2.5 * cm + canvas.setFont('Helvetica-Bold', 10) + canvas.line(x, y, x + doc.width, y) + y -= 0.4 * cm + canvas.drawString(x, y, self.section) + canvas.drawRightString(x + doc.width, y, self.title) + y -= 0.2 * cm + canvas.line(x, y, x + doc.width, y) + + # Footer + canvas.line(doc.leftMargin, 1 * cm, doc.width + doc.leftMargin, 1 * cm) + footer = Paragraph(settings.PDF_FOOTER_TEXT, style_footer) + w, h = footer.wrap(doc.width, doc.bottomMargin) + footer.drawOn(canvas, doc.leftMargin, h ) + canvas.restoreState() + + def later_header(self, canvas, doc): + # Footer + canvas.line(doc.leftMargin, 1 * cm, doc.width + doc.leftMargin, 1 * cm) + footer = Paragraph(settings.PDF_FOOTER_TEXT, style_footer) + w, h = footer.wrap(doc.width, doc.bottomMargin) + footer.drawOn(canvas, doc.leftMargin, h) + canvas.restoreState() + + + def formating(self, text): + return Preformatted(text, style_normal, maxLineLength=25) + + def normal_template_page(self): + first_page_table_frame = Frame(self.leftMargin, self.bottomMargin, self.width + 1 * cm, self.height - 5 * cm, + id='first_table', showBoundary=0, leftPadding=0 * cm) + later_pages_table_frame = Frame(self.leftMargin, self.bottomMargin, self.width + 1 * cm, self.height - 2 * cm, + id='later_table', showBoundary=0, leftPadding=0 * cm) + # Page template + first_page = PageTemplate(id='FirstPage', frames=[first_page_table_frame], onPage=self.header) + later_pages = PageTemplate(id='LaterPages', frames=[later_pages_table_frame], onPage=self.later_header) + self.addPageTemplates([first_page, later_pages]) + self.story = [NextPageTemplate(['*', 'LaterPages'])] + + def six_semester_template_page(self): + frame_title = Frame(self.leftMargin, 24*cm, self.width, 1*cm, showBoundary=0, leftPadding=0) + frame_size = (7 * cm, 6 * cm,) + w, h = (7.5 * cm, 6.5 * cm,) + + x = [self.leftMargin, 11 * cm] * 3 + y = [17 * cm, 17 * cm, 10 * cm, 10 * cm, 3 * cm, 3 * cm] + frames = [Frame(x[f], y[f], width=w, height=h, showBoundary=0, leftPadding=0) for f in range(6)] + # Frame for total periods + frames.append(Frame(self.leftMargin, self.bottomMargin, self.width, 1.5 * cm, leftPadding=0)) + frames.insert(0,frame_title) + # Page template + frame_page = PageTemplate(id='FirstPage', frames=frames, onPage=self.header) + self.addPageTemplates(frame_page) class NumberedCanvas(canvas.Canvas): @@ -46,7 +148,7 @@ class NumberedCanvas(canvas.Canvas): self.setFont("Helvetica", 7) self.drawString(self._pagesize[0] / 2, 1 * cm, "Page {0} de {1}".format(self._pageNumber, page_count)) - +""" class EpcBaseDocTemplate(SimpleDocTemplate): def __init__(self, filename, title='', pagesize=A4): super().__init__(filename, pagesize=pagesize, _pageBreakQuick=0, lefMargin=1.5 * cm, bottomMargin=1.5 * cm, @@ -97,7 +199,7 @@ class EpcBaseDocTemplate(SimpleDocTemplate): # Page template frame_page = PageTemplate(id='FirstPage', frames=frames, onPage=self.header) self.addPageTemplates(frame_page) - +""" class ModuleDescriptionPdf(EpcBaseDocTemplate): """ @@ -105,60 +207,51 @@ class ModuleDescriptionPdf(EpcBaseDocTemplate): """ def __init__(self, filename): - super().__init__(filename, 'Module de formation', A4) + super().__init__(filename, 'Filière EDS', 'Module de formation') self.normal_template_page() def produce(self, module): - str_competence = '' - for c in module.competence_set.all(): - str_competence += '- {0} ({1})\n'.format(c.nom, c.code) - """ - if self.request.user.is_authenticated: - for sc in c.souscompetence_set.all(): - str_comp += ' -- {0}\n'.format(sc.nom) - """ + str_competence = ' \n'.join(['- {0} ({1})'.format(c.nom, c.code) for c in module.competence_set.all()]) + str_sous_competence = '' for c in module.competence_set.all(): for sc in c.souscompetence_set.all(): str_sous_competence += '- {0} (voir {1})\n'.format(sc.nom, c.code) - str_res = '' - for c in module.ressource_set.all(): - str_res += '- {0}\n'.format(c.nom) + str_res = ' \n'.join(['- {0}'.format(c.nom) for c in module.ressource_set.all()]) - str_objectif = '' - for c in module.objectif_set.all(): - str_objectif += '- {0}\n'.format(c.nom) + str_objectif = ' \n'.join(['- {0}'.format(c.nom) for c in module.objectif_set.all()]) self.story.append(Paragraph(module.__str__(), style_bold)) self.story.append(Spacer(0, 0.5 * cm)) data = [ - ['Domaine', module.processus.domaine.__str__()], - ['Processus', module.processus.__str__()], - ['Situation emblématique', module.situation], - ['Compétences visées', str_competence], - ['Plus-value sur le CFC ASE', str_sous_competence], - ['Objectifs', str_objectif], - ['Didactique', module.didactique], - ['Evaluation', module.evaluation], - ['Type', '{0}, obligatoire'.format(module.type)], - ['Semestre', 'Sem. {0}'.format(module.semestre)], - ['Présentiel', '{0} heures'.format(module.total_presentiel)], - ['Travail personnel', '{0} heures'.format(module.travail_perso)], - ['Responsable', module.processus.domaine.responsable.descr_pdf()] - ] + ['Domaine', module.processus.domaine.__str__()], + ['Processus', module.processus.__str__()], + ['Situation emblématique', module.situation], + ['Compétences visées', str_competence], + ['Plus-value sur le CFC ASE', str_sous_competence], + ['Objectifs', str_objectif], + ['Didactique', module.didactique], + ['Evaluation', module.evaluation], + ['Type', '{0}, obligatoire'.format(module.type)], + ['Semestre', 'Sem. {0}'.format(module.semestre)], + ['Présentiel', '{0} heures'.format(module.total_presentiel)], + ['Travail personnel', '{0} heures'.format(module.travail_perso)], + ['Responsable', module.processus.domaine.responsable.descr_pdf()] + ] formated_data = [] for foo in data: formated_data.append( - [Preformatted(foo[0], style_normal, maxLineLength=15), - Preformatted(foo[1], style_normal, maxLineLength=97), - ] + [ + Preformatted(foo[0], style_normal, maxLineLength=15), + Preformatted(foo[1], style_normal, maxLineLength=97), + ] ) - t = Table(formated_data, colWidths=[4 * cm, 13 * cm]) + t = Table(data=formated_data, colWidths=[4 * cm, 13 * cm]) t.hAlign = TA_LEFT t.setStyle( TableStyle( @@ -171,7 +264,7 @@ class ModuleDescriptionPdf(EpcBaseDocTemplate): ) ) self.story.append(t) - self.build(self.story, canvasmaker=NumberedCanvas) + self.build(self.story) class FormationPlanPdf(EpcBaseDocTemplate): @@ -180,7 +273,7 @@ class FormationPlanPdf(EpcBaseDocTemplate): """ def __init__(self, filename): - super().__init__(filename, 'Plan de formation', landscape(A4)) + super().__init__(filename, 'Filière EDS','Plan de formation', landscape(A4)) self.normal_template_page() def formating(self, el1='', length=40): @@ -188,6 +281,7 @@ class FormationPlanPdf(EpcBaseDocTemplate): return Preformatted(el1, style_normal, maxLineLength=length) def produce(self, domain, process): + data = [ ['Domaines', 'Processus', 'Sem1', 'Sem2', 'Sem3', 'Sem4', 'Sem5', 'Sem6'], [self.formating(domain[0]), self.formating(process[0], 60), 'M01', '', '', '', '', ''], @@ -206,7 +300,7 @@ class FormationPlanPdf(EpcBaseDocTemplate): [self.formating(domain[7]), self.formating(process[10], 60), 'Macc', '', '', '', '', ''], ] t = Table( - data, colWidths=[7 * cm, 9 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm], + data=data, colWidths=[7 * cm, 9 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm], spaceBefore=0.5 * cm, spaceAfter=1 * cm ) t.setStyle( @@ -266,7 +360,7 @@ class FormationPlanPdf(EpcBaseDocTemplate): ) t.hAlign = TA_LEFT self.story.append(t) - self.build(self.story, canvasmaker=NumberedCanvas) + self.build(self.story) class PeriodSemesterPdf(EpcBaseDocTemplate): @@ -275,10 +369,11 @@ class PeriodSemesterPdf(EpcBaseDocTemplate): """ def __init__(self, filename): - super().__init__(filename, 'Périodes de formation', A4) + super().__init__(filename, 'Filière EDS','Périodes de formation') self.six_semester_template_page() def produce(self, context): + for sem in range(1, 7): modules = context['sem{0}'.format(str(sem))] total = context['tot{0}'.format(str(sem))] @@ -286,18 +381,17 @@ class PeriodSemesterPdf(EpcBaseDocTemplate): for line in modules: value = getattr(line, 'sem{0}'.format(sem)) data.append([line.nom, '{0} h.'.format(value)]) - t = Table( - data, colWidths=[6.5 * cm, 1 * cm], spaceBefore=0.5 * cm, spaceAfter=1 * cm, hAlign=TA_LEFT, - style=[ - ('ALIGN', (0, 0), (0, 0), 'LEFT'), - ('ALIGN', (1, 0), (-1, -1), 'RIGHT'), - ('LINEBELOW', (0, 0), (1, 0), 1, colors.black), - ('SIZE', (0, 0), (-1, -1), 9), - ('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'), - ] + t = Table(data=data, colWidths=[6 * cm, 1 * cm], spaceBefore=0 * cm, spaceAfter=0.5 * cm, hAlign=TA_LEFT, + style=[ + ('ALIGN', (0, 0), (0, -1), 'LEFT'), + ('ALIGN', (1, 0), (1, -1), 'RIGHT'), + ('LINEBELOW', (0, 0), (1, 0), 1, colors.black), + ('SIZE', (0, 0), (-1, -1), 8), + ('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'), + ] ) self.story.append(t) self.story.append(FrameBreak()) self.story.append(Paragraph('Total de la formation: {0} heures'.format(context['tot']), style_bold)) - self.build(self.story, canvasmaker=NumberedCanvas) + self.build(self.story) diff --git a/common/settings.py b/common/settings.py index 232c25e..3cbed36 100644 --- a/common/settings.py +++ b/common/settings.py @@ -113,7 +113,6 @@ STATIC_ROOT = os.path.join(BASE_DIR, 'static/') MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media/') - DOMAINE_COULEURS = { 'D1': '#fcaf3e', 'D2': '#cc0000', @@ -137,4 +136,7 @@ TINYMCE_DEFAULT_CONFIG = { TINYMCE_SPELLCHECKER = True TINYMCE_COMPRESSOR = True +PDF_FOOTER_TEXT = 'Ecole Santé-social Pierre-Coullery | Prévoyance 82 - 2300 La Chaux-de-Fonds | 032 886 33 00 | cifom-epc@rpn.ch' + + from .local_settings import * \ No newline at end of file diff --git a/db/db_student.eds b/db/db_student.eds new file mode 100644 index 0000000..dff2fa6 Binary files /dev/null and b/db/db_student.eds differ diff --git a/templates/cms/base.html b/templates/cms/base.html index 9613606..a144356 100644 --- a/templates/cms/base.html +++ b/templates/cms/base.html @@ -1,7 +1,6 @@ {% load i18n static %} -{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %} - + {% block title %}{% endblock %} @@ -10,7 +9,6 @@ {% block extrastyle %}{% endblock %} - {% if LANGUAGE_BIDI %}{% endif %} {% block extrahead %}{% endblock %} {% block blockbots %}{% endblock %}