コード例 #1
0
 def get(self, request, pk: int, *args, **kwargs) -> http.HttpResponse:
     student = get_object_or_404(Student, pk=pk)
     document = pdfs.create_statement(student)
     filename = strings.normalize(
         f'Statement_{student.firstname}_{student.surname}.pdf')
     return http.HttpResponse(
         document,
         content_type='application/pdf',
         headers={'Content-Disposition': f'inline;filename={filename}'})
コード例 #2
0
ファイル: views.py プロジェクト: timnyborg/redpot-unchained
    def get(self, request, pk: int, *args, **kwargs) -> http.HttpResponse:
        invoice = get_object_or_404(models.Invoice, pk=pk)
        document = pdfs.create_invoice(invoice)

        filename = strings.normalize(
            f'Invoice_{invoice}{invoice.invoiced_to}.pdf').replace(' ', '_')
        return http.HttpResponse(
            document,
            content_type='application/pdf',
            headers={'Content-Disposition': f'inline;filename={filename}'})
コード例 #3
0
ファイル: views.py プロジェクト: timnyborg/redpot-unchained
 def get(self, request, allocation: int, enrolment_id: int, *args,
         **kwargs) -> http.HttpResponse:
     enrolment = get_object_or_404(Enrolment, pk=enrolment_id)
     student = enrolment.qa.student
     document = pdfs.create_receipt(allocation=allocation, student=student)
     filename = strings.normalize(
         f'Receipt_{allocation}_{student.firstname}_{student.surname}.pdf')
     return http.HttpResponse(
         document,
         content_type='application/pdf',
         headers={'Content-Disposition': f'inline;filename={filename}'})
コード例 #4
0
def _render_statement(enrolment: models.Enrolment, student: Student,
                      address: Address, fees: list[Ledger]) -> bytes:
    module = enrolment.module
    pdf = ContedPDF()
    pdf.bottom_left_text = (
        f"In the event of a query please contact: {module.phone or ''} "  # todo: remove '' once phone null=False
        f"({module.email or '*****@*****.**'})")

    # Creating name and address information on the left
    pdf.set_font_size(12)
    name = f"{student.title or ''} {student.firstname} {student.surname}".strip(
    )
    pdf.cell(30, 4, name)
    pdf.cell(0, 4, date.today().strftime(DATE_FORMAT), 0, 1, 'R')

    pdf.address_block(FormattedAddress(address))

    # Invoice specific text above tables
    pdf.ln(40)
    pdf.multi_cell(0,
                   4,
                   f'Statement for course: {module.title} ({module.code})',
                   align='L')
    if module.start_date:
        pdf.set_font_size(9)
        pdf.cell(0,
                 10,
                 f'Starts {module.start_date.strftime(DATE_FORMAT)}',
                 ln=1)
        pdf.set_font_size(10)

    # Stripy colors
    fill = cycle([True, False])
    pdf.set_fill_color(231, 231, 231)  # Bootstrap-like striped-table grey

    # Create the table header, data array and column widths to pass to the table function
    pdf.set_widths([100, 40, 30])
    pdf.set_aligns(['L', 'L', 'R'])

    for fee in fees:
        data = [fee.narrative, fee.type.description, f'£{fee.amount:.2f}']
        pdf.improved_multi_cell_table(data=data,
                                      draw_border=False,
                                      fill=next(fill))

    footer = ['Remaining', f'£{enrolment.get_balance():.2f}']
    pdf.set_widths([150, 20])
    pdf.improved_multi_cell_table(footer=footer, footer_border=False)

    pdf.set_title(normalize(f'Statement: {module.code} - {student.surname}'))
    return pdf.output(dest='S').encode('latin-1')
コード例 #5
0
ファイル: views.py プロジェクト: timnyborg/redpot-unchained
 def render_document(*, contract: models.Contract) -> str:
     surname = normalize(contract.tutor_module.tutor.student.surname)
     context = {
         **contract.options,
         'identifier':
         f'{contract.tutor_module.module.code}-{surname.upper()}-{contract.id}',
         'preview_class': '' if contract.is_signed else 'highlight',
         'is_signed': contract.is_signed,
         'signatory': settings.CONTRACT_SIGNATORY,
         'signature_image': settings.CONTRACT_SIGNATURE_IMAGE,
     }
     template_map: dict[str, str] = {
         models.Types.CASUAL_TEACHING:
         'contract/pdfs/casual_teaching_contract.html',
         models.Types.GUEST_SPEAKER:
         'contract/pdfs/guest_speaker_letter.html',
     }
     view = template_map[contract.type]
     return render_to_string(view, context)
コード例 #6
0
ファイル: views.py プロジェクト: timnyborg/redpot-unchained
    def get(self, request, pk: int, *args, **kwargs) -> http.HttpResponse:
        contract = get_object_or_404(models.Contract, pk=pk)
        html_doc = self.render_document(contract=contract)

        font_config = FontConfiguration(
        )  # Makes @font-face and google fonts @import work
        output = HTML(
            string=html_doc,
            # Used fetch static images.  Could be done with system file paths, but this'll work for HTML or PDF
            base_url=settings.CANONICAL_URL,
        ).write_pdf(
            stylesheets=[
                CSS(Path(__file__).parent / 'static/css/tutor_contract.css',
                    font_config=font_config)
            ],
            font_config=font_config,
        )
        filename = normalize(
            f"contract_{contract.options['full_name']}_{contract.tutor_module.module.code}.pdf"
        )
        return http.HttpResponse(
            output,
            content_type='application/pdf',
            headers={'Content-Disposition': f'filename="{filename}"'})
コード例 #7
0
ファイル: pdfs.py プロジェクト: timnyborg/redpot-unchained
def _render_transcript(
    *,
    student: Student,
    address_lines: list[str],
    enrolments: list[Enrolment],
    level: str,
    header: bool,
) -> bytes:
    """Legacy routine: produces a transcript of all credit at a given level
    level takes 'undergraduate' and 'postgraduate' for undergraduate and postgraduate
    """

    pdf = TranscriptPDF(print_header=header, level=level)

    pdf.set_font('', 'B', 12)
    name = f"{student.title or ''} {student.firstname} {student.surname}".strip(
    )
    pdf.cell(30, 4, name, ln=1)

    pdf.address_block(address_lines)

    pdf.ln(-8)
    pdf.set_font('', 'B', 10)
    pdf.cell(140, 4, 'Date ', align='R')
    pdf.set_font('', '', 10)
    pdf.cell(0, 4, datetime.now().strftime(DATE_FORMAT), ln=1)

    pdf.set_font('', 'B', 10)
    pdf.cell(140, 4, 'Registration ', align='R')
    pdf.set_font('', '', 10)
    pdf.cell(0, 4, str(student.husid).zfill(13), ln=1)

    pdf.ln(15)

    pdf.set_font('', 'B', 14)
    pdf.cell(0, 10, 'Record of CATS Points', ln=1, align='C')

    # And now a lovely table
    pdf.set_widths([24, 58, 20, 12, 22, 22, 12])

    def table_header():
        pdf.improved_multi_cell_table(
            header=[
                'Module', 'Title', 'Result', 'FHEQ', 'Start date', 'End date',
                'Points'
            ],
            header_border=0,
            header_align='L',
        )

    table_header()

    pdf.set_aligns(['L', 'L', 'L', 'C', 'L', 'L', 'R'])

    # Stripy colors
    fill = cycle([True, False])
    pdf.set_fill_color(231, 231, 231)  # Bootstrap-like striped-table grey

    pdf.set_font('', '', 9)
    for enrolment in enrolments:
        # Handle multi_cells' inability to next-page in tables properly
        if pdf.y + 10 > pdf.page_break_trigger:
            pdf.add_page()
            table_header()
            pdf.set_font('', '', 9)

        pdf.improved_multi_cell_table(
            data=[
                enrolment.module.code,
                enrolment.module.title,
                str(enrolment.mark or '')
                if level == 'postgraduate' else 'Passed',
                str(enrolment.module.points_level.fheq_level),
                enrolment.module.start_date.strftime(DATE_FORMAT),
                enrolment.module.end_date.strftime(DATE_FORMAT),
                str(enrolment.points_awarded),
            ],
            draw_border=False,
            fill=next(fill),
        )

    pdf.set_widths([130, 25, 15])
    pdf.improved_multi_cell_table(
        header=[
            '', 'Total',
            str(sum(enrolment.points_awarded for enrolment in enrolments))
        ],
        header_border=0,
        header_align='R',
    )

    pdf.set_title(
        strings.normalize(
            f'{level.upper()} transcript: {student.firstname} {student.surname}'
        ))

    return pdf.output(dest='S').encode('latin-1')
コード例 #8
0
def _render_statement(*, student: models.Student, address: models.Address,
                      enrolments: list[Enrolment]) -> bytes:
    pdf = ContedPDF()

    pdf.bottom_left_text = 'In the event of a query please contact: [email protected]'

    pdf.set_font_size(12)
    name = f"{student.title or ''} {student.firstname} {student.surname}".strip(
    )
    pdf.cell(30, 4, name)
    pdf.cell(0, 4, date.today().strftime(DATE_FORMAT), 0, 1, 'R')

    for line in FormattedAddress(address):
        pdf.cell(30, 5, line, ln=1)

    pdf.ln(24)
    pdf.set_font('', 'B', 14)
    pdf.multi_cell(
        0,
        4,
        f'Financial statement for {student.firstname} {student.surname}',
        align='L')
    pdf.ln(8)

    pdf.set_fill_color(231, 231, 231)  # Bootstrap-like striped-table grey

    # Create the table header, data array and column widths to pass to the table function
    pdf.set_widths([25, 89, 16, 18, 22])
    pdf.set_aligns(['L', 'L', 'L', 'L', 'R'])

    for enrolment in enrolments:
        fill = cycle([True, False])
        pdf.set_font('', 'B', 11)
        pdf.multi_cell(
            170, 4,
            f'{enrolment.module.title} ({enrolment.module.code}) ({enrolment.status})'
        )

        pdf.set_font('', '', 9)
        for fee in enrolment.ledger_set.all():
            data = [
                fee.timestamp.strftime(DATE_FORMAT),
                fee.narrative or '',
                str(fee.invoice_ledger.invoice) if hasattr(
                    fee, 'invoice_ledger') else '',
                fee.type.description,
                f'£{fee.amount:.2f}',
            ]

            pdf.improved_multi_cell_table(data=data,
                                          draw_border=False,
                                          fill=next(fill))

        # Balance footer for each table
        pdf.set_font('', 'B', 9)
        enrolment.total = sum(fee.amount for fee in enrolment.ledger_set.all())
        pdf.improved_multi_cell_table(
            data=['', '', '', 'Balance', f'£{enrolment.total:.2f}'],
            draw_border=False,
        )

        pdf.ln(4)

    pdf.ln(4)
    pdf.set_font('', 'B', 12)
    pdf.cell(114)
    pdf.cell(34, 4, 'Total balance')
    total = sum(enrolment.total for enrolment in enrolments)
    pdf.cell(22, 4, f'£{total:.2f}', align='R', ln=1)

    pdf.set_title(
        strings.normalize(
            f'Financial statement for {student.firstname} {student.surname}'))
    return pdf.output(dest='S').encode('latin-1')