예제 #1
0
    style=[
        ("BOX", (0, 0), (-1, -1), 0.25, black),
        ("INNERGRID", (0, 0), (-1, -1), 0.25, black),
        ("ALIGN", (0, 0), (0, -1), "RIGHT"),
        ("ALIGN", (1, 0), (-1, -1), "CENTER"),
        ("SPAN", (0, -1), (1, -1)),
        ("ALIGN", (0, -1), (1, -1), "RIGHT"),
    ],
)

mtoe_doc_ending = [
    KeepTogether([
        Spacer(0, 2),
        Paragraph(
            "<b>RISERVATO ALLA COMMISSIONE</b>",
            ParagraphStyle("Title", alignment=TA_CENTER),
        ),
        mtoe_ending_table,
        Spacer(0, 2),
    ])
]


class XLine(Flowable):
    def __init__(self, x0, y0, x1, y1, thickness=None, dash=None):
        super().__init__()
        self.x0 = x0
        self.y0 = y0
        self.x1 = x1
        self.y1 = y1
        self.thickness = thickness
예제 #2
0
def endKeep(s):
    S = getStory()
    k = KeepTogether(S[s:])
    S[s:] = [k]
예제 #3
0
    def __init__(self, contacts: List[InterestPerContract]):
        snippets = get_custom_texts()

        self.buffer = io.BytesIO()

        story = []
        styles = getSampleStyleSheet()
        styleH = styles['Heading3']
        styleH.fontName = 'Times-BoldItalic'
        styleH.fontSize = 14
        styleN = styles['Normal']
        styleN.spaceAfter = 0.3 * cm
        styleN.fontName = 'Times-Italic'
        styleN.leading = 14
        styleN.fontSize = 12

        doc = BaseDocTemplate(self.buffer, pagesize=landscape(A4))
        doc.leftMargin = 1 * cm
        doc.rightMargin = 1 * cm
        doc.topMargin = 1 * cm
        doc.bottomMargin = 1 * cm

        frameWidth = doc.width / 2
        leftRightSpace = 3 * cm
        frameHeight = doc.height + 3 * cm

        frames = []
        for frame in range(2):
            leftMargin = doc.leftMargin + frame * (frameWidth + leftRightSpace)
            column = Frame(leftMargin, doc.bottomMargin, frameWidth,
                           frameHeight)
            frames.append(column)

        template = PageTemplate(frames=frames)
        doc.addPageTemplates(template)

        for contact in contacts:
            frame_floatables = []
            img = get_image(staticfiles_storage.path('custom/logo.png'),
                            width=self.LOGO_WIDTH)
            table_style = TableStyle([
                ('ALIGN', (0, 0), (0, 0), 'LEFT'),
                ('VALIGN', (0, 0), (0, 0), 'BOTTOM'),
                ('ALIGN', (0, 1), (0, 1), 'RIGHT'),
                ('VALIGN', (0, 1), (0, 1), 'TOP'),
                ('LEFTPADDING', (0, 0), (-1, -1), 0),
                ('RIGHTPADDING', (0, 0), (-1, -1), 0),
            ])
            frame_floatables.append(
                Table([[
                    Paragraph(f"Hallo {contact.first_name},", styleH),
                    img,
                ]],
                      style=table_style,
                      colWidths='*'))
            frame_floatables.append(Spacer(1, 0.4 * cm))
            frame_floatables.append(
                Paragraph(snippets["thanks_what_happened"], styleN))
            frame_floatables.append(Paragraph(snippets["next_year"], styleN))
            frame_floatables.append(Paragraph(snippets["invitation"], styleN))
            frame_floatables.append(Paragraph(snippets["wish"], styleN))
            frame_floatables.append(Spacer(1, 0.5 * cm))
            img = get_image(staticfiles_storage.path('custom/image.png'),
                            width=self.IMG_WIDTH)
            table_style = TableStyle([
                ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
                ('VALIGN', (0, 0), (-1, -1), 'TOP'),
                ('LEFTPADDING', (0, 0), (-1, -1), 0),
                ('RIGHTPADDING', (0, 0), (-1, -1), 0),
            ])
            frame_floatables.append(
                Table([[
                    img,
                    Paragraph(snippets["greetings"], styleN),
                ]],
                      style=table_style,
                      colWidths='*'))
            story.append(KeepTogether(frame_floatables))

        doc.build(story)
        self.buffer.seek(0)
예제 #4
0
    def build_table(self):
        colwidths = [30, 70, 55, 100, 60, 65, 60]

        right_align_paragraph_style = ParagraphStyle("adsadsa", alignment=TA_RIGHT, fontName="Helvetica", fontSize=9,
                                                     rightIndent=17)
        header = [
            Paragraph("<b>Pos</b>", style=size_nine_helvetica),
            Paragraph("<b>EAN / SKU</b>", style=size_nine_helvetica),
            Paragraph("<b>Zustand</b>", style=size_nine_helvetica),
            Paragraph("<b>Bezeichnung</b>", style=size_nine_helvetica),
            Paragraph("<b>Menge</b>", style=right_align_paragraph_style),
            Paragraph("<b>Einzelpreis</b>", style=right_align_paragraph_style),
            Paragraph("<b>Betrag</b>", style=right_align_paragraph_style),
        ]

        data = []
        data.append(header)
        pos = 1

        for productmission in self.mission.productmission_set.all():

            data.append(
                [
                    Paragraph(str(pos), style=size_nine_helvetica),
                    Paragraph(productmission.get_ean_or_sku(), style=size_nine_helvetica),
                    Paragraph(productmission.state, style=size_nine_helvetica),
                    Paragraph(productmission.product.title or "", style=size_nine_helvetica),
                    Paragraph(str(productmission.amount), style=right_align_paragraph_style),
                    Paragraph(format_number_thousand_decimal_points(productmission.netto_price),
                              style=right_align_paragraph_style),
                    Paragraph(format_number_thousand_decimal_points(
                        (productmission.netto_price * productmission.amount)),
                              style=right_align_paragraph_style),
                ],
            )

            pos += 1
        table = LongTable(data, splitByRow=True, colWidths=colwidths, repeatRows=1)
        table.setStyle(
            TableStyle([
                ('LEFTPADDING', (0, 0), (-1, -1), 0),
                ('RIGHTPADDING', (0, 0), (-1, -1), 0),
                ('VALIGN', (0, 0), (-1, -1), "TOP"),
            ])
        )

        total_netto = 0

        for productmission in self.mission.productmission_set.all():
            total_netto += productmission.amount * productmission.netto_price

        horizontal_line_betrag = Drawing(20, 1)
        horizontal_line_betrag.add(Line(425, 0, 200, 0))

        betrag_data = [
            [
                Paragraph(f"Nettobetrag",
                          style=right_align_paragraph_style),
                Paragraph(f"{format_number_thousand_decimal_points(total_netto)} €", style=right_align_paragraph_style),
            ],
            [
                Paragraph(f"+ Umsatzsteuer (19,00%)", style=right_align_paragraph_style),
                Paragraph(f"{format_number_thousand_decimal_points(total_netto*0.19)} €",
                          style=right_align_paragraph_style),
            ],
            [
                horizontal_line_betrag,
            ],
            [
                Paragraph(f"GESAMT", style=right_align_bold_paragraph_style),
                Paragraph(f"{format_number_thousand_decimal_points(total_netto+(total_netto*0.19))} €",
                          style=right_align_bold_paragraph_style),
            ]
        ]
        betrag_table = Table(betrag_data, colWidths=[None, 70, 75])
        betrag_table.setStyle(
            TableStyle([
                ('LEFTPADDING', (0, 0), (-1, -1), 0),
                ('RIGHTPADDING', (0, 0), (-1, -1), 0),
                ('VALIGN', (0, 0), (-1, -1), "TOP"),
            ])
        )

        self.story.extend([table, mission_horizontal_line, KeepTogether(betrag_table)])
예제 #5
0
for i in list:
    parsePublicationAndCitation(i, data, tableStyle)

colWidth = [100, 200, 70, 60]
t = Table(data,
          colWidths=colWidth,
          rowHeights=None,
          style=tableStyle,
          hAlign='LEFT')

authorName = sys.argv[2].replace("?", " ")

elements.append(
    generateFirstTable(authorName, round(totalCitationsScore, 2),
                       round(totalCitationsScore - cCitationsScore, 2)))
elements.append(KeepTogether(Spacer(1, 24)))
elements.append(t)

# write the document to disk

#buildCategoryTable("Gabi's first article", ["cited1", "cited2", "cited3"], ["A*", "A", "B"], [10, 20, 30], data, tableStyle)

doc.build(elements)

print(totalCitationsScore)

# publication = list[0];
# #print(publication.split("%"))
# print("!!!!!!")
# for i in publication.split("%"):
#     list2 = input.split("=")
예제 #6
0
def pdf_estudio(estudio):
    tabla, total_estudio = pdf_tabla_estudio(estudio)
    return [KeepTogether(Paragraph(f"Nro de orden: {estudio['nro_de_orden']}", styles["Normal"])),
        KeepTogether(Paragraph(f"Practica: {estudio['practica']['descripcion']}", styles["Normal"])),
        ENTER,
        tabla,] , total_estudio
예제 #7
0
파일: pdf.py 프로젝트: wilsonc86/ledger
def _create_renewal(renewal_buffer, approval, proposal):
    site_url = settings.SITE_URL
    every_page_frame = Frame(PAGE_MARGIN, PAGE_MARGIN, PAGE_WIDTH - 2 * PAGE_MARGIN,
                             PAGE_HEIGHT - 160, id='EveryPagesFrame')
    every_page_template = PageTemplate(id='EveryPages', frames=[every_page_frame], onPage=_create_approval_header)

    doc = BaseDocTemplate(renewal_buffer, pageTemplates=[every_page_template], pagesize=A4)

    # this is the only way to get data into the onPage callback function
    doc.approval = approval
    doc.site_url = site_url

    approval_table_style = TableStyle([('VALIGN', (0, 0), (-1, -1), 'TOP')])

    elements = []


    title = approval.title.encode('UTF-8')

    # additional information
    '''if approval.additional_information:
        elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
        elements.append(Paragraph('Additional Information', styles['BoldLeft']))
        elements += _layout_paragraphs(approval.additional_information)'''

    # delegation holds the dates, approvale and issuer details.
    delegation = []
    # proponent details
    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    address = proposal.applicant.organisation.postal_address
    address_paragraphs = [Paragraph(address.line1, styles['Left']), Paragraph(address.line2, styles['Left']),
                          Paragraph(address.line3, styles['Left']),
                          Paragraph('%s %s %s' % (address.locality, address.state, address.postcode), styles['Left']),
                          Paragraph(address.country.name, styles['Left'])]
    delegation.append(Table([[[Paragraph('Licensee:', styles['BoldLeft']), Paragraph('Address', styles['BoldLeft'])],
                              [Paragraph(_format_name(approval.applicant),
                                         styles['Left'])] + address_paragraphs]],
                            colWidths=(120, PAGE_WIDTH - (2 * PAGE_MARGIN) - 120),
                            style=approval_table_style))

    expiry_date = approval.expiry_date.strftime(DATE_FORMAT)
    full_name = proposal.submitter.get_full_name()

    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Paragraph('Dear {} '.format(full_name), styles['Left']))

    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Paragraph('This is a reminder that your approval: ', styles['Left']))

    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))

    title_with_number = '{} - {}'.format(approval.lodgement_number, title)

    delegation.append(Paragraph(title_with_number, styles['InfoTitleLargeLeft']))

    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Paragraph('is due to expire on {}'.format(expiry_date), styles['Left']))

    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Paragraph('Please note that if you have outstanding compliances these are required to be submitted before the approval can be renewed'
                                , styles['Left']))

    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Paragraph('If you have any queries, contact the {} '
                                'on {}.'.format(settings.DEP_NAME, settings.DEP_PHONE), styles['Left']))

    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Paragraph('Yours sincerely ', styles['Left']))
    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Paragraph('DIRECTOR GENERAL', styles['Left']))
    delegation.append(Paragraph('{}'.format(settings.DEP_NAME), styles['Left']))

    elements.append(KeepTogether(delegation))

    doc.build(elements)

    return renewal_buffer
예제 #8
0
 def __init__(self):
     self.content = []
     self.small_space = KeepTogether(Spacer(0, 0.1 * inch))
     self.large_space = KeepTogether(Spacer(0, 0.3 * inch))
     self.styles = getSampleStyleSheet()
예제 #9
0
    def _create_licence_purpose(elements, selected_activity, issued_purpose):
        '''
        Creates the licence purpose details per page available on the activity.
        '''

        # delegation holds the dates, licencee and issuer details.
        delegation = []
        sequence = purpose.purpose_sequence
        licence_display = '{0}-{1}-{2}'.format(licence.licence_number,
                                               sequence,
                                               issued_purpose.purpose.code)
        licence_purpose = issued_purpose.purpose.name
        elements.append(
            Paragraph(licence_purpose.upper(),
                      styles['InfoTitleVeryLargeCenter']))
        elements.append(
            Paragraph(
                'Regulation {}, Biodiversity Conservation Regulations 2018'.
                format(issued_purpose.purpose.regulation), styles['Center']))

        # applicant details
        delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
        if application.applicant_type \
                == application.APPLICANT_TYPE_ORGANISATION:
            address = application.org_applicant.address
            pass
        elif application.applicant_type == application.APPLICANT_TYPE_PROXY:
            address = application.proxy_applicant.residential_address
            pass
        else:
            # applic.applicant_type == application.APPLICANT_TYPE_SUBMITTER
            address = application.submitter.residential_address

        address_paragraphs = [
            Paragraph(address.line1, styles['Left']),
            Paragraph(address.line2, styles['Left']),
            Paragraph(address.line3, styles['Left']),
            Paragraph(
                '%s %s %s' %
                (address.locality, address.state, address.postcode),
                styles['Left']),
            Paragraph(address.country.name, styles['Left'])
        ]

        delegation.append(
            Table([[[
                Paragraph('Licence Number', styles['BoldLeft']),
                Paragraph('Licence Holder', styles['BoldLeft']),
                Paragraph('Address', styles['BoldLeft'])
            ], [Paragraph(licence_display, styles['Left'])] + [
                Paragraph(licence.current_application.applicant,
                          styles['Left'])
            ] + address_paragraphs]],
                  colWidths=(120, PAGE_WIDTH - (2 * PAGE_MARGIN) - 120),
                  style=licence_table_style))

        # dates
        dates_licensing_officer_table_style = TableStyle([
            ('VALIGN', (0, 0), (-2, -1), 'TOP'),
            ('VALIGN', (0, 0), (-1, -1), 'BOTTOM')
        ])

        delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
        date_headings = [
            Paragraph('Date of Issue', styles['BoldLeft']),
            Paragraph('Date Valid From', styles['BoldLeft']),
            Paragraph('Date of Expiry', styles['BoldLeft'])
        ]

        ltz = timezone.get_current_timezone()
        issue_date = ltz.normalize(issued_purpose.issue_date.astimezone(ltz))
        date_values = [
            Paragraph(issue_date.strftime('%d/%m/%Y'), styles['Left']),
            Paragraph(issued_purpose.start_date.strftime('%d/%m/%Y'),
                      styles['Left']),
            Paragraph(issued_purpose.expiry_date.strftime('%d/%m/%Y'),
                      styles['Left'])
        ]

        if issued_purpose.is_reissued:
            date_headings.insert(
                0, Paragraph('Original Date of Issue', styles['BoldLeft']))
            date_values.insert(
                0, Paragraph(issued_purpose.original_issue_date,
                             styles['Left']))

        delegation.append(
            Table([[date_headings, date_values]],
                  colWidths=(120, PAGE_WIDTH - (2 * PAGE_MARGIN) - 120),
                  style=dates_licensing_officer_table_style))

        delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))

        elements.append(KeepTogether(delegation))

        # species
        species_ids = issued_purpose.purpose.get_species_list
        if species_ids:
            elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
            elements.append(Paragraph('SPECIES', styles['BoldLeft']))
            elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
            species = LicenceSpecies.objects.values_list('data').filter(
                specie_id__in=species_ids)
            speciesList = ListFlowable([
                Paragraph(s[0][0]['vernacular_names'], styles['Left'])
                for s in species
            ],
                                       bulletFontName=BOLD_FONTNAME,
                                       bulletFontSize=MEDIUM_FONTSIZE)
            elements.append(speciesList)
            elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))

        try:
            # copy-to-licence sections with terms and additional information.
            activity_util = ActivitySchemaUtil(selected_activity.application)
            terms = selected_activity.additional_licence_info['terms']
            for term in terms:
                header = term['header']
                if not header:
                    continue
                elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
                elements.append(Paragraph(header.upper(), styles['BoldLeft']))
                elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
                text = activity_util.get_ctl_text(term)
                elements.append(Paragraph(text, styles['Left']))
                elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))

        except BaseException:
            pass

        # PurposeSpecies Section


#        for s in purpose.purpose_species_json:
#            if s.has_key('is_additional_info') and s['is_additional_info']:
#                continue
#
#            if s['details']:
#                parser = HtmlParser(s['details'])
#
#                # Get and Display Purpose Species Header
#                elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
#                elements.append(
#                    Paragraph(
#                        s['header'],
#                        styles['BoldLeft']
#                    )
#                )
#                elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
#
#                purposeSpeciesList = add_parsed_details(parser, list_flowable=False)
#                for info_item in purposeSpeciesList:
#                    elements.append(KeepTogether(info_item))

        for s in purpose.purpose_species_json:
            if 'is_additional_info' in s and s['is_additional_info']:
                continue

            if s['details']:
                elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
                purposeSpeciesList, listcounter = html_to_rl(
                    s['details'], styles)

                for info_item in purposeSpeciesList:
                    elements.append(KeepTogether(info_item))

        # End PurposeSpecies Section

        # application conditions
        activity_conditions = selected_activity.application.conditions.filter(
            licence_activity_id=selected_activity.licence_activity_id,
            licence_purpose_id=issued_purpose.purpose.id)

        if activity_conditions.exists():
            elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
            elements.append(Paragraph('CONDITIONS', styles['BoldLeft']))
            #elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))

            # Conditions Section
            #            conditionList = []
            #            for s in activity_conditions.order_by('order'):
            #                parser = HtmlParser(s.condition)
            #                conditionList += add_parsed_details(parser, list_flowable=False)
            #                #elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))

            #            conditionList = ListFlowable(
            #                conditionList,
            #                bulletFontName=BOLD_FONTNAME, bulletFontSize=MEDIUM_FONTSIZE
            #            )
            #            elements.append(conditionList)

            listcounter = 0
            conditionList = []
            for s in activity_conditions.order_by('order'):
                #_conditionList, listcounter += html_to_rl(s.condition, styles)
                _conditionList, listcounter = html_to_rl(
                    s.condition_text, styles, listcounter)
                conditionList += _conditionList

            for info_item in conditionList:
                elements.append(KeepTogether(info_item))

            # End Conditions Section

        elements += _layout_extracted_fields(licence.extracted_fields)
        elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))

        # signature block
        elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))

        issue_officer = '{} {}'.format(selected_activity.updated_by.first_name,
                                       selected_activity.updated_by.last_name)
        elements.append(Paragraph('____________________', styles['Left']))
        elements.append(Paragraph(issue_officer, styles['Left']))
        elements.append(Paragraph('LICENSING OFFICER', styles['Left']))
        elements.append(Paragraph('WILDLIFE PROTECTION BRANCH',
                                  styles['Left']))
        elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
        elements.append(Paragraph('Delegate of CEO', styles['ItalicLeft']))
        elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))

        # additional information
        for s in purpose.purpose_species_json:
            if 'is_additional_info' in s and s['is_additional_info'] and s[
                    'details']:
                # Get and Display Purpose Species Header
                elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
                purposeSpeciesInfoList, listcounter = html_to_rl(
                    s['details'], styles)

                for info_item in purposeSpeciesInfoList:
                    elements.append(KeepTogether(info_item))
        # End PurposeSpecies Section

        elements.append(PageBreak())
예제 #10
0
def generate_pdf(request,
                 obj,
                 bid_item_dict,
                 invoice,
                 employee,
                 save_to_disk=False,
                 return_file_object=False):
    buff = BytesIO()

    # The page width totals 18.6cm
    doc = SimpleDocTemplate(buff,
                            rightMargin=2 * cm,
                            leftMargin=2 * cm,
                            topMargin=1.5 * cm,
                            bottomMargin=3.75 * cm)

    def _header_footer(canvas, doc):
        # Save the state of our canvas so we can draw on it
        canvas.saveState()
        styles = getSampleStyleSheet()

        # Header
        header = Paragraph(
            'This is a multi-line header.  It goes on every page.   ' * 5,
            styles['Normal'])
        w, h = header.wrap(doc.width, doc.topMargin)
        header.drawOn(canvas, doc.leftMargin, doc.height + doc.topMargin - h)

        # Footer
        footer = Paragraph('Thank You For Your Business', styles['Normal'])
        w, h = footer.wrap(doc.width, doc.bottomMargin)
        footer.drawOn(canvas, doc.leftMargin, h)

        # Release the canvas
        canvas.restoreState()

    story = []

    # Styles
    styles = getSampleStyleSheet()
    styles.add(ParagraphStyle(name='Center', alignment=TA_CENTER))
    styles.add(ParagraphStyle(name='Right', alignment=TA_RIGHT))
    styles.add(ParagraphStyle(name='Left', alignment=TA_LEFT))
    styles.add(
        ParagraphStyle(name='Line_Data',
                       alignment=TA_LEFT,
                       fontSize=8,
                       leading=7))
    styles.add(
        ParagraphStyle(name='Line_Data_Small',
                       alignment=TA_LEFT,
                       fontSize=7,
                       leading=8))
    styles.add(
        ParagraphStyle(name='Line_Data_Medium',
                       alignment=TA_LEFT,
                       fontSize=10,
                       leading=8))
    styles.add(
        ParagraphStyle(name='Line_Data_Large',
                       alignment=TA_LEFT,
                       fontSize=12,
                       leading=12))
    styles.add(
        ParagraphStyle(name='Line_Data_Large_Right',
                       alignment=TA_RIGHT,
                       fontSize=12,
                       leading=12))
    styles.add(
        ParagraphStyle(name='Line_Data_Large_Center',
                       alignment=TA_CENTER,
                       fontSize=12,
                       leading=12))
    styles.add(
        ParagraphStyle(name='Invoice_Date',
                       alignment=TA_LEFT,
                       fontSize=12,
                       leading=12))
    styles.add(
        ParagraphStyle(name='Line_Data_Largest',
                       fontName='Times-BoldItalic',
                       alignment=TA_CENTER,
                       fontSize=22,
                       leading=15))
    styles.add(
        ParagraphStyle(name='Line_Label',
                       fontSize=10,
                       leading=12,
                       alignment=TA_LEFT))
    styles.add(
        ParagraphStyle(name='Line_Label_Center',
                       fontSize=7,
                       alignment=TA_CENTER))

    # Add Company Address, Logo and Invoice Info
    company_paragraph = """
        179 Marvy ST<br />
        Lino Lakes, MN 55014<br />
        (612) 508-2484 <br />
        [email protected] <br />
        MN License: BC690748
        """

    logo = os.path.join(settings.STATIC_ROOT, 'img/logo.jpg')
    denominator = 5
    image = Image(logo, width=800 / denominator, height=269 / denominator)

    if invoice:
        proposal_invoice_paragraph = """
            Date: {}<br />
            Invoice #: {:04d} <br />
        """.format(datetime.date.today().strftime('%x'), obj.id)
    else:
        proposal_invoice_paragraph = """
            Submitted By: <br />
            Tom Madsen <br />
            Date: {}<br />
            Proposal #: {:04d} <br />
        """.format(datetime.date.today().strftime('%x'), obj.id)

    data1 = [[
        Paragraph(company_paragraph, styles['Line_Data_Large']), image,
        Paragraph(proposal_invoice_paragraph, styles['Line_Data_Large'])
    ]]

    t1 = Table(data1, colWidths=(6.7 * cm, 8 * cm, 4.6 * cm))
    t1.setStyle(TableStyle([
        ('VALIGN', (0, 0), (-1, -1), 'TOP'),
    ]))

    story.append(t1)

    # Add Proposal or Invoice Title to PDF
    if invoice:
        pdf_type = 'Invoice'
    elif employee:
        pdf_type = 'Employee Copy'
    else:
        pdf_type = 'Proposal'

    data1 = [[Paragraph(pdf_type, styles["Line_Data_Largest"])]]

    t1 = Table(data1, colWidths=(18.6 * cm))
    t1.setStyle(TableStyle([('VALIGN', (0, 0), (-1, -1), 'TOP')]))

    story.append(t1)
    story.append(Spacer(2, 32))

    # Add Customer Info and Job Description
    telephone = obj.customer.telephone
    telephone = "({}) {}-{}".format(telephone[:3], telephone[3:6],
                                    telephone[6:])

    if obj.customer.company_name:
        company = "{}<br />".format(obj.customer.company_name)
    else:
        company = ""

    location_paragraph = """
        {first} {last}<br />
        {company}
        {street}<br />
        {city}, {state} {zip}<br />
        {telephone}<br />
        {email}""".format(first=obj.customer.first_name,
                          last=obj.customer.last_name,
                          company=company,
                          street=obj.address.street,
                          city=obj.address.city,
                          state=obj.address.state,
                          zip=obj.address.zip,
                          telephone=telephone,
                          email=obj.customer.email)

    if obj.billto_city_st_zip:  # check if this is an alternate billto field populated
        if len(obj.billto_telephone) == 10:
            billto_telephone = obj.billto_telephone
            billto_telephone = "({}) {}-{}".format(billto_telephone[:3],
                                                   billto_telephone[3:6],
                                                   billto_telephone[6:])
        else:
            billto_telephone = obj.billto_telephone

        billto_paragraph = """
        {name}<br />
        {street}<br />
        {city_st_zip}<br />
        {telephone}""".format(name=obj.billto_name,
                              street=obj.billto_street,
                              city_st_zip=obj.billto_city_st_zip,
                              telephone=billto_telephone)
    else:
        billto_paragraph = location_paragraph

    description_paragraph = obj.description

    if invoice:
        data1 = [[
            Paragraph('Bill To', styles["Line_Data_Large"]),
            Paragraph('Job Address', styles["Line_Data_Large"])
        ],
                 [
                     Paragraph(billto_paragraph, styles["Line_Data_Large"]),
                     Paragraph(location_paragraph, styles["Line_Data_Large"])
                 ]]

        t1 = Table(data1, colWidths=(9.3 * cm, 9.3 * cm))
        t1.setStyle(
            TableStyle([('VALIGN', (0, 0), (-1, -1), 'TOP'),
                        ('BACKGROUND', (0, 0), (1, 0), colors.lightgrey)]))

        story.append(t1)
        story.append(Spacer(4, 20))

        data1 = [[Paragraph('Job Description', styles["Line_Data_Large"])],
                 [Paragraph(description_paragraph, styles["Line_Data_Large"])]]

        t1 = Table(data1, colWidths=(18.6 * cm))
        t1.setStyle(
            TableStyle([('VALIGN', (0, 0), (-1, -1), 'TOP'),
                        ('BACKGROUND', (0, 0), (1, 0), colors.lightgrey)]))

        story.append(t1)

    else:  # Proposal

        data1 = [[
            Paragraph('Job Address', styles["Line_Data_Large"]),
            Paragraph('Job Description', styles["Line_Data_Large"])
        ],
                 [
                     Paragraph(billto_paragraph, styles["Line_Data_Large"]),
                     Paragraph(description_paragraph,
                               styles["Line_Data_Large"])
                 ]]

        t1 = Table(data1, colWidths=(7 * cm, 11.6 * cm))
        t1.setStyle(
            TableStyle([('VALIGN', (0, 0), (-1, -1), 'TOP'),
                        ('BACKGROUND', (0, 0), (1, 0), colors.lightgrey)]))

        story.append(t1)

        if obj.notes:
            story.append(Spacer(2, 10))
            data1 = [[Paragraph('Notes', styles["Line_Data_Large"])],
                     [Paragraph(obj.notes, styles["Line_Data_Large"])]]

            t1 = Table(data1, colWidths=(18.6 * cm))
            t1.setStyle(
                TableStyle([('VALIGN', (0, 0), (-1, -1), 'TOP'),
                            ('BACKGROUND', (0, 0), (1, 0), colors.lightgrey)]))

            story.append(t1)

    # Add Bid Items to PDF
    story.append(Spacer(4, 32))

    for job_name, items in bid_item_dict.items():
        title = [[
            Paragraph(job_name, styles["Line_Data_Large"]),
            Paragraph('', styles["Line_Data_Large"])
        ]]

        t1 = Table(title, colWidths=(15 * cm, 3.6 * cm))
        t1.setStyle(
            TableStyle([('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
                        ('BOX', (0, 0), (-1, -1), .25, colors.black),
                        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                        ('BACKGROUND', (0, 0), (-1, -1), colors.lightgrey)]))

        story.append(t1)

        if employee:  # Add quantities but remove pricing
            data1 = [[
                Paragraph(str(item.description), styles["Line_Data_Large"]),
                Paragraph(str(item.quantity), styles["Line_Data_Large_Right"])
            ] for item in items]

            t1 = Table(data1, colWidths=(15 * cm, 3.6 * cm))
            t1.setStyle(
                TableStyle([
                    ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
                    ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
                    ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                ]))

            story.append(t1)
            story.append(Spacer(4, 32))

        else:  # Add pricing but not quantity for end customer
            data1 = [[
                Paragraph(str(item.description), styles["Line_Data_Large"]),
                Paragraph(str("{0:.2f}".format(round(item.total, 2))),
                          styles["Line_Data_Large_Right"])
            ] for item in items]

            t1 = Table(data1, colWidths=(15 * cm, 3.6 * cm))
            t1.setStyle(
                TableStyle([
                    ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
                    ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
                    ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                ]))

            story.append(t1)

            # Calculate total per job and add to PDF
            total = items.aggregate(Sum('total'))['total__sum']
            total_text = "{} Total".format(job_name)
            data1 = [[
                Paragraph(total_text, styles["Line_Data_Large"]),
                Paragraph(str("${0:.2f}".format(total)),
                          styles['Line_Data_Large_Right'])
            ]]

            t1 = Table(data1, colWidths=(15 * cm, 3.6 * cm))
            t1.setStyle(
                TableStyle([
                    ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
                    ('BOX', (0, 0), (-1, -1), .25, colors.black),
                    ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                    ('BACKGROUND', (0, 0), (-1, -1), colors.lightgrey)
                ]))

            story.append(t1)
            story.append(Spacer(4, 32))

    # Calculate Bid Total
    items = BidItem.objects.all().filter(bid=obj.id)
    bid_total = items.aggregate(Sum('total'))['total__sum']

    if not bid_total:
        bid_total = 0

    if invoice:  # Calculate Balance Due and Payment History for Invoice
        payments = Payment.objects.all().filter(bid=obj.id)
        payment_total = payments.aggregate(Sum('amount'))['amount__sum']

        cents = Decimal('0.01')
        if payment_total:
            remaining_balance = Decimal(bid_total - payment_total).quantize(
                cents, ROUND_HALF_UP)
        else:
            remaining_balance = bid_total

        data1 = [
            [Paragraph('Invoice Summary', styles["Line_Data_Large"]), None],
            [
                Paragraph('Initial Balance', styles["Line_Data_Large"]),
                Paragraph(str("{0:.2f}".format(round(bid_total, 2))),
                          styles["Line_Data_Large_Right"])
            ],
        ]

        data2 = [[
            Paragraph(
                str("Received Payment on {}".format(
                    payment.date.strftime('%x'))), styles["Line_Data_Large"]),
            Paragraph(str("-{0:.2f}".format(round(payment.amount, 2))),
                      styles["Line_Data_Large_Right"])
        ] for payment in payments]

        last_row = len(data2) + 2

        data3 = [[
            Paragraph('Remaining Balance Due', styles["Line_Data_Large"]),
            Paragraph(str("${0:.2f}".format(round(remaining_balance, 2))),
                      styles["Line_Data_Large_Right"])
        ]]

        all_data = data1 + data2 + data3

        t1 = Table(all_data, colWidths=(14 * cm, 4.6 * cm))
        t1.setStyle(
            TableStyle([
                ('BOX', (0, 0), (-1, -1), .25, colors.black),
                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                ('BACKGROUND', (0, 0), (-1, 0),
                 colors.lightgrey),  # we propose
                ('BACKGROUND', (0, last_row), (-1, last_row),
                 colors.lightgrey),  # payment outline
            ]))

        story.append(KeepTogether(t1))

    elif employee:  # If employee skip rest of bid info
        pass

    else:  # Proposal

        if obj.custom_down_payment and obj.custom_down_payment != -1:
            down_payment = obj.custom_down_payment
        elif obj.custom_down_payment == -1:
            down_payment = 0
        else:
            if bid_total:
                down_payment = bid_total / 2
            else:
                down_payment = 0

        if bid_total:
            cents = Decimal('0.01')
            final_payment = Decimal(bid_total - down_payment).quantize(
                cents, ROUND_HALF_UP)
        else:
            final_payment = 0

        if not bid_total:
            bid_total = 0

        we_propose = 'Hereby to furnish material and labor complete in accordance with above specifications,' \
                     ' for the sum of'

        acceptance = """The above prices, specifications and conditions are satisfactory and are hereby accepted.
        You are authorized to do the work as specified. Payment will be made as outlined above.
        I have received a copy of the Pre-Lien notice."""

        data1 = [
            [Paragraph('We Propose', styles["Line_Data_Large"]), None],
            [
                Paragraph(we_propose, styles["Line_Data_Large"]),
                Paragraph(str("${0:.2f}".format(round(bid_total, 2))),
                          styles["Line_Data_Large_Right"])
            ],
            [Paragraph('Payment Outline', styles["Line_Data_Large"]), None],
            [
                Paragraph('Deposit', styles["Line_Data_Large"]),
                Paragraph(str("${0:.2f}".format(round(down_payment, 2))),
                          styles["Line_Data_Large_Right"])
            ],
            [
                Paragraph(
                    'Remaining Balance Due Upon Completion of the Contract',
                    styles["Line_Data_Large"]),
                Paragraph(str("${0:.2f}".format(round(final_payment, 2))),
                          styles["Line_Data_Large_Right"])
            ],
            [
                Paragraph('Acceptance of Proposal', styles["Line_Data_Large"]),
                None
            ],
            [Paragraph(acceptance, styles["Line_Data_Large"]), None],
            [
                Paragraph('Signature:', styles["Line_Label"]),
                Paragraph('Date:', styles["Line_Label"])
            ],
            [
                Paragraph(
                    'X__________________________________________________________________',
                    styles["Line_Label"]),
                Paragraph('_____________________', styles["Line_Label"])
            ],
        ]

        t1 = Table(data1, colWidths=(14 * cm, 4.6 * cm))
        t1.setStyle(
            TableStyle([
                ('BOX', (0, 0), (-1, -1), .25, colors.black),
                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                ('BACKGROUND', (0, 0), (-1, 0),
                 colors.lightgrey),  # we propose
                ('BACKGROUND', (0, 2), (-1, 2),
                 colors.lightgrey),  # payment outline
                ('BACKGROUND', (0, 5), (-1, 5),
                 colors.lightgrey),  # acceptance of proposal
                ('SPAN', (0, 6),
                 (-1, 6)),  # span acceptance text across both columns
                ('BOTTOMPADDING', (0, 7), (-1, 7), 40)
            ]))

        story.append(KeepTogether(t1))

        # Add Pre-Lien Notice to PDF
        story.append(PageBreak())

        pre_lien_notice = """
        <br />
        ANY PERSON OR COMPANY SUPPLYING LABOR OR MATERIALS FOR THIS IMPROVEMENT TO YOUR PROPERTY MAY FILE A LIEN
        AGAINST YOUR PROPERTY IF THAT PERSON OR COMPANY IS NOT PAID FOR THE CONTRIBUTIONS.<br /><br />

        UNDER MINNESOTA LAW, YOU HAVE THE RIGHT TO PAY PERSONS WHO SUPPLIED LABOR OR MATERIALS FOR THIS IMPROVEMENT
         DIRECTLY AND DEDUCT THIS AMOUNT FROM OUR CONTRACT PRICE, OR WITHHOLD THE AMOUNTS DUE THEM FROM US UNTIL
         120 DAYS AFTER COMPLETION OF THE IMPROVEMENT UNLESS WE GIVE YOU A LIEN WAIVER SIGNED BY PERSONS WHO SUPPLIED
         ANY LABOR OR MATERIAL FOR THE IMPROVEMENT AND WHO GAVE YOU TIMELY NOTICE.
        """

        data1 = [[
            Paragraph('PRE-LIEN NOTICE', styles["Line_Data_Large_Center"])
        ], [Paragraph(pre_lien_notice, styles["Line_Data_Large"])]]

        t1 = Table(data1)
        story.append(t1)

    # doc.build(story, onFirstPage=_header_footer, onLaterPages=_header_footer, canvasmaker=NumberedCanvas)
    doc.build(story, canvasmaker=NumberedCanvas)

    pdf = buff.getvalue()
    buff.close()

    if return_file_object:
        # For send pdf to employee which isnt stored to database, return the file object
        return pdf

    if save_to_disk:
        myfile = ContentFile(pdf)
        db_model = PDFImage()
        db_model.bid = obj
        if invoice:
            filename_temp = 'invoice'
        else:
            filename_temp = 'proposal'

        db_model.filename.save(filename_temp, myfile)
        messages.success(request, "PDF was saved successfully!")
        return redirect('bid_app:bid_detail', pk=obj.id)

    if invoice:
        filename = "{}_invoice_{}".format(
            obj.customer.__str__().replace(' ', '_').replace(',', '').lower(),
            datetime.date.today())
    else:
        filename = "{}_proposal_{}".format(
            obj.customer.__str__().replace(' ', '_').replace(',', '').lower(),
            datetime.date.today())
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'filename={}.pdf'.format(filename)
    response.write(pdf)

    return response
예제 #11
0
def _create_licence(licence_buffer, licence, application):
    site_url = settings.SITE_URL
    every_page_frame = Frame(PAGE_MARGIN, PAGE_MARGIN, PAGE_WIDTH - 2 * PAGE_MARGIN,
                             PAGE_HEIGHT - 160, id='EveryPagesFrame')
    every_page_template = PageTemplate(id='EveryPages', frames=[every_page_frame], onPage=_create_licence_header)

    doc = BaseDocTemplate(licence_buffer, pageTemplates=[every_page_template], pagesize=A4)

    # this is the only way to get data into the onPage callback function
    doc.licence = licence
    doc.site_url = site_url

    licence_table_style = TableStyle([('VALIGN', (0, 0), (-1, -1), 'TOP')])

    elements = []


    title = licence.title.encode('UTF-8')

    elements.append(Paragraph(title, styles['InfoTitleVeryLargeCenter']))
    elements.append(Paragraph(licence.activity, styles['InfoTitleLargeLeft']))
    elements.append(Paragraph(licence.region, styles['InfoTitleLargeLeft']))
    elements.append(Paragraph(licence.tenure if licence.tenure else '', styles['InfoTitleLargeRight']))

    # application conditions 
    if application.conditions.exists():
        elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
        elements.append(Paragraph('Conditions', styles['BoldLeft']))
        elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))

        conditionList = ListFlowable(
            [Paragraph(a.condition, styles['Left']) for a in application.conditions.order_by('order')],
            bulletFontName=BOLD_FONTNAME, bulletFontSize=MEDIUM_FONTSIZE)
        elements.append(conditionList)
    
    elements += _layout_extracted_fields(licence.extracted_fields)

    # additional information
    '''if licence.additional_information:
        elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
        elements.append(Paragraph('Additional Information', styles['BoldLeft']))
        elements += _layout_paragraphs(licence.additional_information)'''

    # delegation holds the dates, licencee and issuer details.
    delegation = []

    # dates and licensing officer
    dates_licensing_officer_table_style = TableStyle([('VALIGN', (0, 0), (-2, -1), 'TOP'),
                                                      ('VALIGN', (0, 0), (-1, -1), 'BOTTOM')])

    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    date_headings = [Paragraph('Date of Issue', styles['BoldLeft']), Paragraph('Valid From', styles['BoldLeft']),
                     Paragraph('Date of Expiry', styles['BoldLeft'])]
    date_values = [Paragraph(licence.issue_date.strftime(DATE_FORMAT), styles['Left']),
                   Paragraph(licence.start_date.strftime(DATE_FORMAT), styles['Left']),
                   Paragraph(licence.expiry_date.strftime(DATE_FORMAT), styles['Left'])]

    if licence.original_issue_date is not None:
        date_headings.insert(0, Paragraph('Original Date of Issue', styles['BoldLeft']))
        date_values.insert(0, Paragraph(licence.original_issue_date.strftime(DATE_FORMAT), styles['Left']))

    delegation.append(Table([[date_headings, date_values]],
                            colWidths=(120, PAGE_WIDTH - (2 * PAGE_MARGIN) - 120),
                            style=dates_licensing_officer_table_style))

    # proponent details
    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    address = application.applicant.organisation.postal_address
    address_paragraphs = [Paragraph(address.line1, styles['Left']), Paragraph(address.line2, styles['Left']),
                          Paragraph(address.line3, styles['Left']),
                          Paragraph('%s %s %s' % (address.locality, address.state, address.postcode), styles['Left']),
                          Paragraph(address.country.name, styles['Left'])]
    delegation.append(Table([[[Paragraph('Licensee:', styles['BoldLeft']), Paragraph('Address', styles['BoldLeft'])],
                              [Paragraph(_format_name(licence.applicant),
                                         styles['Left'])] + address_paragraphs]],
                            colWidths=(120, PAGE_WIDTH - (2 * PAGE_MARGIN) - 120),
                            style=licence_table_style))

    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Paragraph('Issued by a Wildlife Licensing Officer of the {} '
                                'under delegation from the Minister for Environment pursuant to section 133(1) '
                                'of the Conservation and Land Management Act 1984.'.format(settings.DEP_NAME), styles['Left']))

    elements.append(KeepTogether(delegation))

    doc.build(elements)

    return licence_buffer
예제 #12
0
def output_report(lines: List[ADRLine],
                  tc_display_format: TimecodeFormat,
                  font_name="Helvetica"):
    character_numbers = set([n.character_id for n in lines])
    #pdfmetrics.registerFont(TTFont('Futura', 'Futura.ttc'))

    for n in character_numbers:
        char_lines = [
            line for line in lines
            if not line.omitted and line.character_id == n
        ]
        character_name = char_lines[0].character_name

        sorted(char_lines, key=lambda line: line.start)

        title = "%s (%s) %s ADR Script" % (char_lines[0].title, character_name,
                                           n)
        filename = "%s_%s_%s_ADR Script.pdf" % (char_lines[0].title, n,
                                                character_name)

        doc = make_doc_template(page_size=letter,
                                filename=filename,
                                document_title=title,
                                title=char_lines[0].title,
                                document_subheader=char_lines[0].spot,
                                supervisor=char_lines[0].supervisor,
                                client=char_lines[0].client,
                                document_header=character_name)

        story = []

        prompt_style = getSampleStyleSheet()['Normal']
        prompt_style.fontName = font_name
        prompt_style.fontSize = 18.

        prompt_style.leading = 24.
        prompt_style.leftIndent = 1.5 * inch
        prompt_style.rightIndent = 1.5 * inch

        number_style = getSampleStyleSheet()['Normal']
        number_style.fontName = font_name
        number_style.fontSize = 14

        number_style.leading = 24
        number_style.leftIndent = 0.
        number_style.rightIndent = 0.

        for line in char_lines:
            start_tc = tc_display_format.seconds_to_smpte(line.start)
            finish_tc = tc_display_format.seconds_to_smpte(line.finish)
            data_block = [[
                Paragraph(line.cue_number, number_style),
                Paragraph(start_tc + " - " + finish_tc, number_style)
            ]]

            # RIGHTWARDS ARROW →
            # Unicode: U+2192, UTF-8: E2 86 92
            story.append(
                KeepTogether([
                    HRFlowable(width='50%', color=colors.black),
                    Table(data=data_block,
                          colWidths=[1.5 * inch, 6. * inch],
                          style=[('LEFTPADDING', (0, 0), (-1, -1), 0.)]),
                    Paragraph(line.prompt, prompt_style),
                    Spacer(1., inch * 1.5)
                ]))

        doc.build(story)
예제 #13
0
    def feedback_responses(self, clinic, responses):
        """Renders the Feedback Responses section."""
        cellBgColor = colors.grey.clone(alpha=0.2)
        flowables = []
        flowables.append(heading('Patient Feedback Responses'))
        flowables.append(
            p("""<para spaceafter=12>Summary of patient feedback responses
                           compared to LGA-wide averages.</para>"""))
        rows = [('Patients from %s said:' % clinic.name, '', '',
                 'Patients from other facilities said:', '', '')]
        for r in responses:
            if r[3] >= 10:
                symbol = u'\ue013'
            elif r[3] <= -10:
                symbol = u'\ue014'
            else:
                symbol = u''
            rows.append(('%d (%.0f%%)' % r[1], r[0],
                         u'\ue107' if r[1][1] < 30.0 else '  ',
                         '%d (%.0f%%)' % r[2], r[0], symbol))
        tbl = Table(rows, colWidths=[0.9 * inch, 2 * inch, 0.3 * inch] * 2)
        tbl.setStyle(
            TableStyle([
                ('SPAN', (0, 0), (2, 0)),
                ('SPAN', (3, 0), (5, 0)),
                ('BACKGROUND', (0, 1), (0, -1), cellBgColor),
                ('BACKGROUND', (3, 1), (3, -1), cellBgColor),
                ('FONTSIZE', (0, 0), (-1, -1), 9),
                ('FONTSIZE', (0, 0), (0, -1), 10),
                ('FONTSIZE', (3, 0), (3, -1), 10),
                ('LEFTPADDING', (0, 0), (-1, 0), 2),
                ('RIGHTPADDING', (0, 0), (-1, 0), 2),
                ('TOPPADDING', (0, 1), (-1, -1), 8),
                ('BOTTOMPADDING', (0, 1), (-1, -1), 8),
                ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                ('FONT', (2, 0), (2, -1), 'Glyphicons Halflings'),
                ('FONT', (5, 0), (5, -1), 'Glyphicons Halflings'),
                ('GRID', (0, 0), (-1, -1), 3, colors.white),
            ]))
        flowables.append(tbl)

        legend = Table([
            ('KEY', '', '', '', '', ''),
            (u'\ue107', 'Problem area;\nrequires attention', u'\ue014',
             '%s performed worse\nthan the LGA average' % clinic.name,
             u'\ue013',
             '%s performed better\nthan the LGA average' % clinic.name)
        ])
        legend.setStyle(
            TableStyle([
                ('SPAN', (0, 0), (-1, 0)),
                ('TOPPADDING', (0, 0), (-1, 0), 15),
                ('TOPPADDING', (0, 1), (-1, -1), 6),
                ('LINEBELOW', (0, 0), (-1, 0), 1, cellBgColor),
                ('FONT', (0, 1), (0, 1), 'Glyphicons Halflings'),
                ('FONT', (2, 1), (2, 1), 'Glyphicons Halflings'),
                ('FONT', (4, 1), (4, 1), 'Glyphicons Halflings'),
                ('FONTSIZE', (1, 1), (1, 1), 7),
                ('FONTSIZE', (3, 1), (3, 1), 7),
                ('FONTSIZE', (5, 1), (5, 1), 7),
                ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
                ('VALIGN', (0, 0), (-1, -1), 'TOP'),
            ]))
        flowables.append(legend)
        return KeepTogether(flowables)
예제 #14
0
def pdf(group, bill):
    """PDF version of bill"""

    width, height = A4
    margin = 1 * cm
    heading = 2 * cm

    logo_height = 1.5 * cm

    font_name = "Times-Roman"
    font_size = 16

    filename = "{}-{}-{}-{}".format(date.today(), group, _("bill"), bill.id)

    response = HttpResponse(content_type="application/pdf")
    response["Content-Disposition"] = "attachment; filename=%s.pdf" % (
        slugify(filename))

    show_logo = bool(group.logo and group.logo.storage.exists(group.logo.path))

    if show_logo:
        ratio = group.logo.width / group.logo.height
        logo = Image(group.logo.path,
                     width=logo_height * ratio,
                     height=logo_height)

    def draw_header(canvas, doc):
        if show_logo:
            logo.drawOn(
                canvas,
                width / 2 - 1 * margin - logo_height * ratio,
                height - margin - logo_height,
            )

        canvas.setFont(font_name, font_size)
        canvas.drawString(margin, height - margin - font_size,
                          _("Bill #%d") % (bill.id))
        canvas.setFont(font_name, font_size - 4)
        canvas.drawString(
            margin,
            height - margin - 2 * font_size,
            bill.created.strftime(_("%Y-%m-%d %H:%M").encode("utf-8")),
        )

    frames = [
        Frame(
            0,
            0,
            width / 2,
            height - heading,
            leftPadding=margin,
            bottomPadding=margin,
            rightPadding=margin / 2,
            topPadding=margin,
        ),
        Frame(
            width / 2,
            0,
            width / 2,
            height,
            leftPadding=margin / 2,
            bottomPadding=margin,
            rightPadding=margin,
            topPadding=margin,
        ),
    ]

    templates = [PageTemplate(frames=frames, onPage=draw_header)]

    doc = BaseDocTemplate(response, pagesize=(width, height))
    doc.addPageTemplates(templates)

    data = [[_("Description"), _("Amount")]]
    total = 0

    for line in bill.billingline_set.all():
        data.append([line.description, "%.2f" % line.amount])
        total += line.amount

    data.append(["", "%.2f" % total])

    table = Table(data, colWidths=[doc.width * 0.4, doc.width * 0.15])
    table.setStyle(table_style)
    table.hAlign = "LEFT"

    parts = []
    for line in bill.description.split("\n"):
        parts.append(Paragraph(escape(line), styles["Normal"]))
    parts.append(Spacer(0.2 * cm, 0.2 * cm))
    parts.append(KeepTogether(table))

    doc.build(parts)

    return response
예제 #15
0
 def _parseComponentEntryPoint(self, section, pdf):
     for component in section:
         componentSection = []
         name = component["COMPONENT/ENTRY POINT"]
         componentSection.append(
             Paragraph("%s : %s" % ("COMPONENT/ENTRY POINT", name),
                       styles['Heading3']))
         if 'COMPONENT DESCRIPTION' in component:
             # TODO: Each line should be its own Paragraph
             description = component["COMPONENT DESCRIPTION"]
             if type(description) is list:
                 description = " ".join(description)
             componentSection.append(
                 self._convertIndividualFieldValuePDF(
                     'COMPONENT DESCRIPTION', description, True))
             componentSection.append(Spacer(1, 20))
         if 'VARIABLES' in component:
             variables = component["VARIABLES"]
             table = []
             table.append(
                 generatePDFTableHeader(
                     ["VARIABLES", "TYPE", "VARIABLES DESCRIPTION"]))
             for variable in variables:
                 if type(variable) is dict:
                     row = []
                     _variables = variable['VARIABLES']
                     if type(_variables) is list:
                         _variables = _variables[0]
                         if "-" in _variables:
                             # TODO: This is a workaround for an error in original
                             # file, see ICR-639. This does not create an error
                             # when creating the html file, but the formating is
                             # incorrect.
                             variable['VARIABLES'] = _variables.split(
                                 "-")[0]
                             variable[
                                 'VARIABLES DESCRIPTION'] = _variables.split(
                                     "-")[1]
                         else:
                             # TODO: ICR-5317 VARIABLES are not
                             # parsed correctly. Skip them for now.
                             variable['VARIABLES'] = ""
                     row.append(
                         self._convertIndividualFieldValuePDF(
                             'VARIABLES', variable['VARIABLES'], False))
                     if 'TYPE' in variable:
                         if type(variable['TYPE']) is list:
                             # TODO: ICR-6551 VARIABLES are not
                             # parsed correctly. Skip them for now.
                             variable['TYPE'] = ""
                         row.append(
                             self._convertIndividualFieldValuePDF(
                                 'TYPE', variable['TYPE'], False, False))
                     else:
                         row.append(Paragraph("", styles['Normal']))
                     if 'VARIABLES DESCRIPTION' in variable:
                         description = variable['VARIABLES DESCRIPTION']
                         if type(description) is list:
                             description = " ".join(description)
                             if len(description) > 1000:
                                 # TODO: Skipping long descriptions for now
                                 # See ICR-2916, ICR-3486, etc.
                                 description = ""
                         row.append(
                             self._convertIndividualFieldValuePDF(
                                 'VARIABLES DESCRIPTION', description,
                                 False, False))
                     else:
                         row.append(Paragraph("", styles['Normal']))
                     table.append(row)
                 else:
                     # TODO: Parsing error! See ICR-28
                     pass
             columns = 10
             columnWidth = self.doc.width / columns
             t = Table(
                 table,
                 colWidths=[columnWidth * 2, columnWidth, columnWidth * 7])
             t.setStyle(
                 TableStyle([
                     ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
                     ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
                 ]))
             componentSection.append(t)
         pdf.append(KeepTogether(componentSection))
예제 #16
0
파일: report.py 프로젝트: tcpr1/vosae-app
 def end_keeptogether(self):
     keeptogether = KeepTogether(self.story[self.keeptogether_index:])
     self.story = self.story[:self.keeptogether_index]
     self.story.append(keeptogether)
예제 #17
0
from reportlab.lib.pagesizes import A4, landscape
from reportlab.lib.styles import StyleSheet1, getSampleStyleSheet
from reportlab.lib.units import cm, mm
from reportlab.lib.enums import TA_JUSTIFY
from reportlab.platypus import Table, Paragraph, KeepTogether
from reportlab.platypus.doctemplate import SimpleDocTemplate
from reportlab.platypus.flowables import Flowable
from reportlab.lib import colors
from common.reportlab import NumberedPageCanvas

from medicamento.models import TIPOS_MEDICAMENTOS

styles = getSampleStyleSheet()
styles["Normal"].fontSize = 10
styles["Heading1"].fontSize = 10
HLINE = KeepTogether(Paragraph('_'*93, styles["Normal"]))
ENTER = KeepTogether(Paragraph("<br/><br/>", styles["Normal"]))
TOPMARGIN = 50*mm
BOTTOMMARGIN = 15*mm
RIGHTMARGIN = 11*mm
LEFTMARGIN = 11*mm
COL1 = 80*mm
COL2 = 30*mm
COL3 = 70*mm

def generar_pdf_presentacion(response, presentacion):

    pdf = SimpleDocTemplate(
        response,
        pagesize = (A4),
        topMargin = TOPMARGIN,
예제 #18
0
def getCommentary():
    """Returns the story for the commentary - all the paragraphs."""

    styleSheet = getSampleStyleSheet()

    story = []
    story.append(
        Paragraph("""
        PLATYPUS User Guide and Test Script
        """, styleSheet['Heading1']))

    spam = """
    Welcome to PLATYPUS!

    Platypus stands for "Page Layout and Typography Using Scripts".  It is a high
    level page layout library which lets you programmatically create complex
    documents with a minimum of effort.

    This document is both the user guide &amp; the output of the test script.
    In other words, a script used platypus to create the document you are now
    reading, and the fact that you are reading it proves that it works.  Or
    rather, that it worked for this script anyway.  It is a first release!

    Platypus is built 'on top of' PDFgen, the Python library for creating PDF
    documents.  To learn about PDFgen, read the document testpdfgen.pdf.

    """

    for text in getParagraphs(spam):
        story.append(Paragraph(text, styleSheet['BodyText']))

    story.append(
        Paragraph(
            """
        What concepts does PLATYPUS deal with?
        """, styleSheet['Heading2']))
    story.append(
        Paragraph(
            """
        The central concepts in PLATYPUS are Flowable Objects, Frames, Flow
        Management, Styles and Style Sheets, Paragraphs and Tables.  This is
        best explained in contrast to PDFgen, the layer underneath PLATYPUS.
        PDFgen is a graphics library, and has primitive commans to draw lines
        and strings.  There is nothing in it to manage the flow of text down
        the page.  PLATYPUS works at the conceptual level fo a desktop publishing
        package; you can write programs which deal intelligently with graphic
        objects and fit them onto the page.
        """, styleSheet['BodyText']))

    story.append(
        Paragraph("""
        How is this document organized?
        """, styleSheet['Heading2']))

    story.append(
        Paragraph(
            """
        Since this is a test script, we'll just note how it is organized.
        the top of each page contains commentary.  The bottom half contains
        example drawings and graphic elements to whicht he commentary will
        relate.  Down below, you can see the outline of a text frame, and
        various bits and pieces within it.  We'll explain how they work
        on the next page.
        """, styleSheet['BodyText']))

    story.append(FrameBreak())
    #######################################################################
    #     Commentary Page 2
    #######################################################################

    story.append(
        Paragraph("""
        Flowable Objects
        """, styleSheet['Heading2']))
    spam = """
        The first and most fundamental concept is that of a 'Flowable Object'.
        In PDFgen, you draw stuff by calling methods of the canvas to set up
        the colors, fonts and line styles, and draw the graphics primitives.
        If you set the pen color to blue, everything you draw after will be
        blue until you change it again.  And you have to handle all of the X-Y
        coordinates yourself.

        A 'Flowable object' is exactly what it says.  It knows how to draw itself
        on the canvas, and the way it does so is totally independent of what
        you drew before or after.  Furthermore, it draws itself at the location
        on the page you specify.

        The most fundamental Flowable Objects in most documents are likely to be
        paragraphs, tables, diagrams/charts and images - but there is no
        restriction.  You can write your own easily, and I hope that people
        will start to contribute them.  PINGO users - we provide a "PINGO flowable" object to let
        you insert platform-independent graphics into the flow of a document.

        When you write a flowable object, you inherit from Flowable and
        must implement two methods.  object.wrap(availWidth, availHeight) will be called by other parts of
        the system, and tells you how much space you have.  You should return
        how much space you are going to use.  For a fixed-size object, this
        is trivial, but it is critical - PLATYPUS needs to figure out if things
        will fit on the page before drawing them.  For other objects such as paragraphs,
        the height is obviously determined by the available width.


        The second method is object.draw().  Here, you do whatever you want.
        The Flowable base class sets things up so that you have an origin of
        (0,0) for your drawing, and everything will fit nicely if you got the
        height and width right.  It also saves and restores the graphics state
        around your calls, so you don;t have to reset all the properties you
        changed.

        Programs which actually draw a Flowable don't
        call draw() this directly - they call object.drawOn(canvas, x, y).
        So you can write code in your own coordinate system, and things
        can be drawn anywhere on the page (possibly even scaled or rotated).
        """
    for text in getParagraphs(spam):
        story.append(Paragraph(text, styleSheet['BodyText']))

    #this should not cause an error
    story.append(KeepTogether([]))

    story.append(FrameBreak())
    #######################################################################
    #     Commentary Page 3
    #######################################################################

    story.append(
        Paragraph("""
        Available Flowable Objects
        """, styleSheet['Heading2']))

    story.append(
        Paragraph(
            """
        Platypus comes with a basic set of flowable objects.  Here we list their
        class names and tell you what they do:
        """, styleSheet['BodyText']))
    #we can use the bullet feature to do a definition list
    story.append(
        Paragraph(
            """
        <para color=green bcolor=red bg=pink>This is a <font bgcolor=yellow color=red>contrived</font> object to give an example of a Flowable -
        just a fixed-size box with an X through it and a centred string.</para>""",
            styleSheet['Definition'],
            bulletText='XBox  '  #hack - spot the extra space after
        ))

    story.append(
        Paragraph(
            """
        This is the basic unit of a document.  Paragraphs can be finely
        tuned and offer a host of properties through their associated
        ParagraphStyle.""",
            styleSheet['Definition'],
            bulletText='Paragraph  '  #hack - spot the extra space after
        ))

    story.append(
        Paragraph(
            """
        This is used for printing code and other preformatted text.
        There is no wrapping, and line breaks are taken where they occur.
        Many paragraph style properties do not apply.  You may supply
        an optional 'dedent' parameter to trim a number of characters
        off the front of each line.""",
            styleSheet['Definition'],
            bulletText='Preformatted  '  #hack - spot the extra space after
        ))
    story.append(
        Paragraph(
            """
        This is a straight wrapper around an external image file.  By default
        the image will be drawn at a scale of one pixel equals one point, and
        centred in the frame.  You may supply an optional width and height.""",
            styleSheet['Definition'],
            bulletText='Image  '  #hack - spot the extra space after
        ))

    story.append(
        Paragraph(
            """
        This is a table drawing class; it is intended to be simpler
        than a full HTML table model yet be able to draw attractive output,
        and behave intelligently when the numbers of rows and columns vary.
        Still need to add the cell properties (shading, alignment, font etc.)""",
            styleSheet['Definition'],
            bulletText='Table  '  #hack - spot the extra space after
        ))

    story.append(
        Paragraph(
            """
        This is a 'null object' which merely takes up space on the page.
        Use it when you want some extra padding betweene elements.""",
            styleSheet['Definition'],
            bulletText='Spacer '  #hack - spot the extra space after
        ))

    story.append(
        Paragraph(
            """
        A FrameBreak causes the document to call its handle_frameEnd method.""",
            styleSheet['Definition'],
            bulletText='FrameBreak  '  #hack - spot the extra space after
        ))

    story.append(
        Paragraph(
            """
        This is in progress, but a macro is basically a chunk of Python code to
        be evaluated when it is drawn.  It could do lots of neat things.""",
            styleSheet['Definition'],
            bulletText='Macro  '  #hack - spot the extra space after
        ))

    story.append(FrameBreak())

    story.append(
        Paragraph("The next example uses a custom font", styleSheet['Italic']))

    def code(txt, story=story, styleSheet=styleSheet):
        story.append(Preformatted(txt, styleSheet['Code']))

    code('''import reportlab.rl_config
    reportlab.rl_config.warnOnMissingFontGlyphs = 0

    from reportlab.pdfbase import pdfmetrics
    fontDir = os.path.join(_RL_DIR,'fonts')
    face = pdfmetrics.EmbeddedType1Face(os.path.join(fontDir,'DarkGardenMK.afm'),
            os.path.join(fontDir,'DarkGardenMK.pfb'))
    faceName = face.name  # should be 'DarkGardenMK'
    pdfmetrics.registerTypeFace(face)
    font = pdfmetrics.Font(faceName, faceName, 'WinAnsiEncoding')
    pdfmetrics.registerFont(font)


    # put it inside a paragraph.
    story.append(Paragraph(
        """This is an ordinary paragraph, which happens to contain
        text in an embedded font:
        <font name="DarkGardenMK">DarkGardenMK</font>.
        Now for the real challenge...""", styleSheet['Normal']))


    styRobot = ParagraphStyle('Robot', styleSheet['Normal'])
    styRobot.fontSize = 16
    styRobot.leading = 20
    styRobot.fontName = 'DarkGardenMK'

    story.append(Paragraph(
                "This whole paragraph is 16-point DarkGardenMK.",
                styRobot))''')

    story.append(FrameBreak())
    if _GIF:
        story.append(
            Paragraph("""We can use images via the file name""",
                      styleSheet['BodyText']))
        code('''    story.append(platypus.Image('%s'))''' % _GIFFSEnc)
        code('''    story.append(platypus.Image(fileName2FSEnc('%s')))''' %
             _GIFFSEnc)
        story.append(
            Paragraph(
                """They can also be used with a file URI or from an open python file!""",
                styleSheet['BodyText']))
        code('''    story.append(platypus.Image('%s'))''' % getFurl(_GIFFSEnc))
        code('''    story.append(platypus.Image(open_for_read('%s','b')))''' %
             _GIFFSEnc)
        story.append(FrameBreak())
        story.append(
            Paragraph("""Images can even be obtained from the internet.""",
                      styleSheet['BodyText']))
        code(
            '''    img = platypus.Image('http://www.reportlab.com/rsrc/encryption.gif')
    story.append(img)''')
        story.append(FrameBreak())

    if _JPG:
        story.append(
            Paragraph(
                """JPEGs are a native PDF image format. They should be available even if PIL cannot be used.""",
                styleSheet['BodyText']))
        story.append(FrameBreak())
    return story
예제 #19
0
파일: pdf.py 프로젝트: wilsonc86/ledger
def _create_approval(approval_buffer, approval, proposal, copied_to_permit, user):
    site_url = settings.SITE_URL
    every_page_frame = Frame(PAGE_MARGIN, PAGE_MARGIN, PAGE_WIDTH - 2 * PAGE_MARGIN,
                             PAGE_HEIGHT - 160, id='EveryPagesFrame')
    every_page_template = PageTemplate(id='EveryPages', frames=[every_page_frame], onPage=_create_approval_header)

    doc = BaseDocTemplate(approval_buffer, pageTemplates=[every_page_template], pagesize=A4)

    # this is the only way to get data into the onPage callback function
    doc.approval = approval
    doc.site_url = site_url
    region = approval.region if hasattr(approval, 'region') else ''
    district = approval.district if hasattr(approval, 'district') else ''
    region_district = '{} - {}'.format(region, district) if district else region

    approval_table_style = TableStyle([('VALIGN', (0, 0), (-1, -1), 'TOP')])

    elements = []


    title = approval.title.encode('UTF-8')

    #Organization details

    address = proposal.applicant.organisation.postal_address
    email = proposal.applicant.organisation.organisation_set.all().first().contacts.all().first().email
    elements.append(Paragraph(email,styles['BoldLeft']))
    elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    elements.append(Paragraph(_format_name(approval.applicant),styles['BoldLeft']))
    elements.append(Paragraph(address.line1, styles['BoldLeft']))
    elements.append(Paragraph(address.line2, styles['BoldLeft']))
    elements.append(Paragraph(address.line3, styles['BoldLeft']))
    elements.append(Paragraph('%s %s %s' % (address.locality, address.state, address.postcode), styles['BoldLeft']))
    elements.append(Paragraph(address.country.name, styles['BoldLeft']))
    elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    elements.append(Paragraph(approval.issue_date.strftime(DATE_FORMAT), styles['BoldLeft']))
    elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))

    #elements.append(Paragraph(title, styles['InfoTitleVeryLargeCenter']))
    #elements.append(Paragraph(approval.activity, styles['InfoTitleLargeLeft']))
    elements.append(Paragraph('APPROVAL OF PROPOSAL {} {} TO UNDERTAKE DISTURBANCE ACTIVITY IN {}'.format(title, proposal.lodgement_number, region_district), styles['InfoTitleLargeLeft']))
    #import ipdb; ipdb.set_trace()
    #elements.append(Paragraph(approval.tenure if hasattr(approval, 'tenure') else '', styles['InfoTitleLargeRight']))

    elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    elements.append(Paragraph('The submitted proposal {} {} has been assessed and approved. The approval is granted on the understanding that: '.format(title, proposal.lodgement_number), styles['BoldLeft']))
    elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))

    list_of_bullets= []
    list_of_bullets.append('The potential impacts of the proposal on values the department manages have been removed or minimised to a level \'As Low As Reasonably Practicable\' (ALARP) and the proposal is consistent with departmental objectives, associated management plans and the land use category/s in the activity area.')
    list_of_bullets.append('Approval is granted for the period {} to {}.  This approval is not valid if {} makes changes to what has been proposed or the proposal has expired.  To change the proposal or seek an extension, the proponent must re-submit the proposal for assessment.'.format(approval.start_date.strftime(DATE_FORMAT), approval.expiry_date.strftime(DATE_FORMAT),_format_name(approval.applicant)))
    list_of_bullets.append('The proponent accepts responsibility for advising {} of new information or unforeseen threats that may affect the risk of the proposed activity.'.format(settings.DEP_NAME_SHORT))
    list_of_bullets.append('Information provided by {0} for the purposes of this proposal will not be provided to third parties without permission from {0}.'.format(settings.DEP_NAME_SHORT))
    list_of_bullets.append('The proponent accepts responsibility for supervising and monitoring implementation of activity/ies to ensure compliance with this proposal. {} reserves the right to request documents and records demonstrating compliance for departmental monitoring and auditing.'.format(settings.DEP_NAME_SHORT))
    list_of_bullets.append('Non-compliance with the conditions of the proposal may trigger a suspension or withdrawal of the approval for this activity.')
    list_of_bullets.append('Management actions listed in Appendix 1 are implemented.')

    understandingList = ListFlowable(
            [ListItem(Paragraph(a, styles['Left']), bulletColour='black', value='circle') for a in list_of_bullets],
            bulletFontName=BOLD_FONTNAME, bulletFontSize=SMALL_FONTSIZE, bulletType='bullet')
            #bulletFontName=BOLD_FONTNAME
    elements.append(understandingList)

    # proposal requirements
    requirements = proposal.requirements.all().exclude(is_deleted=True)
    if requirements.exists():
        elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
        elements.append(Paragraph('The following requirements must be satisfied for the approval of the proposal not to be withdrawn:', styles['BoldLeft']))
        elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))

        conditionList = ListFlowable(
            [Paragraph(a.requirement, styles['Left']) for a in requirements.order_by('order')],
            bulletFontName=BOLD_FONTNAME, bulletFontSize=MEDIUM_FONTSIZE)
        elements.append(conditionList)

    # if copied_to_permit:
    #     elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    #     elements.append(Paragraph('Assessor Comments', styles['BoldLeft']))
    #     elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))

    #     for k,v in copied_to_permit:
    #         elements.append(Paragraph(v.encode('UTF-8'), styles['Left']))
    #         elements.append(Paragraph(k.encode('UTF-8'), styles['Left']))
    #         elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))

    elements += _layout_extracted_fields(approval.extracted_fields)

    # additional information
    '''if approval.additional_information:
        elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
        elements.append(Paragraph('Additional Information', styles['BoldLeft']))
        elements += _layout_paragraphs(approval.additional_information)'''

    # delegation holds the dates, approvale and issuer details.
    delegation = []

    # dates and licensing officer
    # dates_licensing_officer_table_style = TableStyle([('VALIGN', (0, 0), (-2, -1), 'TOP'),
    #                                                   ('VALIGN', (0, 0), (-1, -1), 'BOTTOM')])

    # delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    # date_headings = [Paragraph('Date of Issue', styles['BoldLeft']), Paragraph('Valid From', styles['BoldLeft']),
    #                  Paragraph('Date of Expiry', styles['BoldLeft'])]
    # date_values = [Paragraph(approval.issue_date.strftime(DATE_FORMAT), styles['Left']),
    #                Paragraph(approval.start_date.strftime(DATE_FORMAT), styles['Left']),
    #                Paragraph(approval.expiry_date.strftime(DATE_FORMAT), styles['Left'])]

    # if approval.original_issue_date is not None:
    #     date_headings.insert(0, Paragraph('Original Date of Issue', styles['BoldLeft']))
    #     date_values.insert(0, Paragraph(approval.original_issue_date.strftime(DATE_FORMAT), styles['Left']))

    # delegation.append(Table([[date_headings, date_values]],
    #                         colWidths=(120, PAGE_WIDTH - (2 * PAGE_MARGIN) - 120),
    #                         style=dates_licensing_officer_table_style))

    # proponent details
    # delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    # address = proposal.applicant.organisation.postal_address
    # address_paragraphs = [Paragraph(address.line1, styles['Left']), Paragraph(address.line2, styles['Left']),
    #                       Paragraph(address.line3, styles['Left']),
    #                       Paragraph('%s %s %s' % (address.locality, address.state, address.postcode), styles['Left']),
    #                       Paragraph(address.country.name, styles['Left'])]
    # delegation.append(Table([[[Paragraph('Licensee:', styles['BoldLeft']), Paragraph('Address', styles['BoldLeft'])],
    #                           [Paragraph(_format_name(approval.applicant),
    #                                      styles['Left'])] + address_paragraphs]],
    #                         colWidths=(120, PAGE_WIDTH - (2 * PAGE_MARGIN) - 120),
    #                         style=approval_table_style))
    if user.phone_number:
        contact_number = user.phone_number
    elif user.mobile_number:
        contact_number = user.mobile_number
    else:
        contact_number= settings.DEP_PHONE

    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Paragraph('Should you have any queries about this approval, please contact {} {}, '
                                'on {} or by email at {}'.format(user.first_name, user.last_name, contact_number, user.email), styles['Left']))
    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Paragraph('To provide feedback on the system used to submit the approval or update contact details, please '
        'contact {} Works Coordinator - {}'.format(settings.SYSTEM_NAME_SHORT, settings.SUPPORT_EMAIL), styles['Left']))
    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Paragraph('Approved on behalf of the', styles['Left']))
    delegation.append(Paragraph('{}'.format(settings.DEP_NAME), styles['BoldLeft']))
    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))

    delegation.append(Paragraph('{} {}'.format(user.first_name, user.last_name), styles['Left']))
    delegation.append(Paragraph('{}'.format(region_district), styles['Left']))
    delegation.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    delegation.append(Paragraph(approval.issue_date.strftime(DATE_FORMAT), styles['Left']))

    elements.append(KeepTogether(delegation))

    # Appendix section
    elements.append(PageBreak())
    elements.append(Paragraph('Appendix 1 - Management Actions', styles['BoldLeft']))
    elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
    if copied_to_permit:
        # for k,v in copied_to_permit:
        #     elements.append(Paragraph(v.encode('UTF-8'), styles['Left']))
        #     elements.append(Paragraph(k.encode('UTF-8'), styles['Left']))
        #     elements.append(Spacer(1, SECTION_BUFFER_HEIGHT))
        for item in copied_to_permit:
            for key in item:
               elements.append(Paragraph(key.encode('UTF-8'), styles['Left']))
               elements.append(Paragraph(item[key].encode('UTF-8'), styles['Left']))
    else:
        elements.append(Paragraph('There are no management actions.', styles['Left']))


    doc.build(elements)

    return approval_buffer
예제 #20
0
    def _print_paragraph(self, block, level=None, root=False, width=1.0):
        if isinstance(block, Code):
            return self._print_code(block, root)
        if isinstance(block, Table):
            return self._print_table(block, table_width=width)
        if isinstance(block, PageSpacer):
            if block.isbreak:
                if block.iscond:
                    return self._story.append(
                        CondPageBreak(block.height * self.PAGE_HEIGHT))
                return self._story.append(PageBreak())
            if block.style:
                self._set_page_template(block.style)
                # Break to a new page unless we already have whole page available. This trick
                # is used to render cheatsheets both in book and in separate PDF without extra page
                return self._story.append(NextPageTemplate(block.style))
            return self._story.append(
                Spacer(0, block.height * self.PAGE_HEIGHT))

        # Save state to get paragraphs
        if isinstance(block, FlowableIncut):
            width = block.coords.get('w', width)
            self._save_state()
        elif root and isinstance(block, Incut):
            self._save_state()

        # Pick paragraph style based on block nature
        style = self._styles['default']
        if isinstance(block, Header):
            style = self._styles['h{0}'.format(block.size)]
        elif isinstance(block, BlockQuote):
            style = self._styles['blockquote']
        elif root:
            style = self._styles['root']

        # Generate style for lists on-the-fly
        if level:
            style = ParagraphStyle('style{0}'.format(id(block)),
                                   parent=style,
                                   bulletIndent=(level * 10),
                                   spaceAfter=0,
                                   spaceBefore=0)

        # Generate paragraph's text. PLATYPUS doesn't support hiearchial paragraphs like HTML do,
        # so we linearize blocks into paragraphs list: each time subblock appear, we complete
        # current paragraph and start a new one.

        # For Incuts which may have subparagraphs, we add two colored paragraphs before and after
        # so they will be distinguishable. Span is another exception -- it doesn't rendered as
        # separate paragraph, but as a <span> within paragraph.
        out = self._start_block(block, True)

        for part in block.parts:
            if isinstance(part, Block) and not isinstance(part, Span):
                out = self._end_block(root, out, block, style)

                # Allow to use "root" style for root lists,  but forbid it in tables and incuts, etc.
                childroot = False
                if isinstance(part, ListEntry) or isinstance(part, ListBlock):
                    level = getattr(part, 'level', None)
                    childroot = root
                if isinstance(part, Code) or isinstance(part, Table):
                    childroot = root

                self._print_paragraph(part, level, root=childroot, width=width)
                continue

            if isinstance(part, Image):
                # Create separate paragraph for large images
                img = self._print_image(part, width)

                if not isinstance(img, RLImage) or (
                        img._width > self.MAX_INLINE_IMAGE_SIZE
                        or img._height > self.MAX_INLINE_IMAGE_SIZE):
                    out = self._end_block(root, out, block, style)

                    # We want to keep image together with a paragraph before
                    if self._story:
                        img = _ImageBlock(self._story.pop(), img)

                    self._story.append(img)
                    continue

            self._part_to_strio(part, out, style.fontSize)

        self._end_block(root, out, block, style, True)

        if isinstance(block, FlowableIncut):
            incut = _FlowableIncut(block.coords, self._restore_state())
            return self._story.append(incut)
        if root and isinstance(block, Incut):
            incut = KeepTogether(self._restore_state())
            return self._story.append(incut)
def pdf_instructions(basic_build: BasicBuild,
                     path: str = None,
                     assemblies_per_clip: int = 28):
    """Writes instructions to implement build to a pdf file.

    Args:
        basic_build: BasicBuild object the pdf lab instructions are written for.
        path (optional): path to pdf file. If none defaults to
            working directory with a time stamped name.
        assemblies_per_clip (optional): number of assemblies each purified clip reaction can support.

    Returns:
        str: filepath of created pdf
    """

    import pandas as pd
    import math

    def calculate_clip_num(assemblies: list):
        return math.ceil(len(assemblies) / assemblies_per_clip)

    COMPONENTS = pd.DataFrame({
        "Component": [
            "Promega T4 DNA Ligase 10x Buffer",
            "Water",
            "NEB BsaI-HFv2",
            "Promega T4 DNA Ligase",
        ],
        "Volume per clip (µL)": [3, 15.5, 1, 0.5],
    })

    total_clips = sum([
        calculate_clip_num(assemblies)
        for _, assemblies in basic_build.clips_data.items()
    ])
    dead_clips = math.ceil(total_clips / 20)
    array = COMPONENTS["Volume per clip (µL)"] * (total_clips + dead_clips)

    MASTER_MIX_BASIC_REACTION = [
        [
            "Component",
            "Volume per clip (µL)",
        ],
        [
            "Promega T4 DNA Ligase 10x Buffer",
            str(array[0]),
        ],
        [
            "Water",
            str(array[1]),
        ],
        [
            "NEB BsaI-HFv2",
            str(array[2]),
        ],
        [
            "Promega T4 DNA Ligase",
            str(array[3]),
        ],
    ]

    PROCESSED_MASTER_MIX_BASIC_REACTION = [
        list(map(lambda x: Paragraph(x, styleN), x))
        for x in MASTER_MIX_BASIC_REACTION
    ]

    zip_path = export_csvs(basic_build)
    with zipfile.ZipFile(zip_path, "r") as zip_ref:
        try:
            zip_ref.extractall("PDF_CSVS")
        finally:
            zip_ref.close()
            os.remove(zip_path)
    assemeblies_data = pd.read_csv(Path.cwd() / "PDF_CSVS" / "assemblies.csv")
    clips_data = pd.read_csv(Path.cwd() / "PDF_CSVS" / "clips.csv")
    os.remove(Path.cwd() / "PDF_CSVS" / "assemblies.csv")
    os.remove(Path.cwd() / "PDF_CSVS" / "clips.csv")
    os.rmdir(Path.cwd() / "PDF_CSVS")
    CLIPS_DATA = clips_data_from_pandas(clips_data)
    ASSEMBLIES_DATA = assembly_data_from_pandas(assemeblies_data)

    if path == None:
        now = datetime.now()
        pdf_filename = str(
            Path.cwd() /
            f"Manual_instructions_{now.strftime('%d-%m-%Y_%H.%M.%S')}.pdf")
    else:
        pdf_filename = path

    pdf = SimpleDocTemplate(pdf_filename, pagesizes=A4)

    elems = []
    with resources.path("basicsynbio.static", "introimg.png") as image_path:
        elems.append(Image(image_path, 12 * cm, 4 * cm))
    elems.append(Paragraph("Materials", styles["Heading1"]))
    elems.append(
        Table(PROCESSED_MATERIALS, colWidths=[10.5 * cm, 5 * cm], style=style))
    elems.append(PageBreak())
    elems.append(Paragraph("Method", styles["Heading1"]))
    elems.append(
        Paragraph("Preperation of BASIC linkers and parts",
                  styles["Heading2"]))
    elems.append(
        Paragraph(
            "BASIC linkers can be ordered from Biolegio ([email protected]) and will be delivered in a lyophilized format along with linker annealing buffer.",
            styles["BodyText"],
        ))
    elems.append(
        ListFlowable([
            Paragraph(
                "Spin down plates containing lyophilized linkers. ",
                styles["BodyText"],
            ),
            Paragraph(
                "Add 150 μl of linker annealing buffer to each well, seal the plate with a PCR foil and incubate for 1 hour at room temperate. ",
                styles["BodyText"],
            ),
            Paragraph(
                "Vortex the plate and collect liquid via centrifugation. ",
                styles["BodyText"],
            ),
            KeepTogether([
                Paragraph(
                    "Conduct the following incubation in a thermocycler: ",
                    styles["BodyText"],
                ),
                Spacer(1, 0.4 * cm),
                Table(
                    PROCESSED_INCUBATION_TIMES,
                    colWidths=[4 * cm, 4 * cm, 4 * cm],
                    style=style_no_split,
                ),
            ]),
            Paragraph(
                "Collect the liquid in wells via centrifugation.",
                styles["BodyText"],
            ),
            Paragraph(
                "Linkers are ready to use or can be stored at -20°C until required.",
                styles["BodyText"],
            ),
        ]))
    elems.append(Spacer(1, 0.4 * cm))
    ## Basic Reaction 1
    elems.append(Paragraph(
        "Clip reactions",
        styles["Heading2"],
    ))
    elems.append(
        Paragraph(
            "Below contains a table with each clip needed for the assemblies of the build.",
            styles["BodyText"],
        ))
    elems.append(Spacer(1, 0.4 * cm))
    elems.append(
        Table(
            CLIPS_DATA,
            colWidths=[
                2 * cm,
                1.9 * cm,
                3 * cm,
                3 * cm,
                2 * cm,
                2 * cm,
                2.3 * cm,
                2 * cm,
            ],
            style=style,
        ))
    elems.append(
        Paragraph(
            "Prepare a Master mix for clip reactions, the below table provides the required components for the master mix with sufficient quantities for all clip reactions.",
            styles["BodyText"],
        ))
    elems.append(Spacer(1, 0.4 * cm))
    elems.append(
        Table(
            PROCESSED_MASTER_MIX_BASIC_REACTION,
            colWidths=[7 * cm, 7 * cm],
            style=style_no_split,
        ))
    elems.append(
        Paragraph(
            "For each Clip reaction, setup 1 PCR tube with 30 μl total volume: ",
            styles["BodyText"],
        ))
    elems.append(
        Paragraph(
            "Dispense 20 uL master mix, 1 μl of each prefix and suffix Linker, 1 μl of part (or more depending on concentration) into a PCR tube and make up to 30 μl with water.",
            styles["BodyText"],
        ))
    elems.append(Spacer(1, 0.4 * cm))
    elems.append(Spacer(1, 0.4 * cm))
    elems.append(
        Paragraph(
            "After mixing, tubes are placed in a PCR machine running the following programme: ",
            styles["BodyText"],
        ))
    elems.append(Spacer(1, 0.4 * cm))
    elems.append(
        Table(
            PROCESSED_TEMPERATURE_PROFILE_1,
            colWidths=[4 * cm, 4 * cm, 4 * cm],
            style=style_joint_cell,
        ))
    ## Magbead Purification 2
    elems.append(Paragraph("Magbead purification", styles["Heading2"]))
    elems.append(
        Paragraph(
            "Prepare 70% EtOH (0.5 ml per BASIC reaction) and bring magnetic beads (AmpureXP or Ampliclean) stored at 4°C back into homogeneous mix by shaking thoroughly. ",
            styles["BodyText"],
        ))
    elems.append(
        ListFlowable([
            Paragraph(
                "Add 54 μl of magnetic beads into 96 well Falcon plate (one well per BASIC reaction) and add the 30 μl BASIC linker ligation from the PCR machine step, mix by pipetting 10 times. ",
                styles["BodyText"],
            ),
            Paragraph(
                "Wait 5 min to allow DNA binding to magbeads. ",
                styles["BodyText"],
            ),
            Paragraph(
                "Place Falcon plate on magnetic stand and wait for rings to form and solution to clear.",
                styles["BodyText"],
            ),
            Paragraph(
                "Aspirate most of the solution with a 200 µL pipette set to 80 µL.",
                styles["BodyText"],
            ),
            Paragraph(
                "Add 190 μl 70% EtOH to each well and wait 30 s. ",
                styles["BodyText"],
            ),
            Paragraph(
                "Remove solution from each well (pipette set to 200 μl volume) ",
                styles["BodyText"],
            ),
            Paragraph(
                "Add 190 μl 70% EtOH to each well and wait 30 s. ",
                styles["BodyText"],
            ),
            Paragraph(
                "Remove solution from each well (pipette set to 200 μl volume)",
                styles["BodyText"],
            ),
            Paragraph("Leave the plate to dry for 1-2 min.",
                      styles["BodyText"]),
            Paragraph(
                "Remove Falcon plate from magnet and resuspend magbeads in 32 μl dH20. ",
                styles["BodyText"],
            ),
            Paragraph("Wait 1 min for DNA to elute. ", styles["BodyText"]),
            Paragraph(
                "Place Falcon plate back on magnetic stand and allow ring to form and solution to clear. ",
                styles["BodyText"],
            ),
            Paragraph(
                "Transfer 30 μl of purified clip reaction into a clean microcentrifuge tube or well and store at at -20°C for up to 1 month.",
                styles["BodyText"],
            ),
        ]))
    # Assembly Reaction 3
    elems.append(Paragraph(
        "Assembly reactions",
        styles["Heading2"],
    ))
    elems.append(
        Paragraph(
            "Below contains a table with each BASIC assembly within your build",
            styles["BodyText"],
        ))
    elems.append(Spacer(1, 0.4 * cm))
    elems.append(
        Table(ASSEMBLIES_DATA,
              colWidths=[5.2 * cm, 5.2 * cm, 5.2 * cm],
              style=style))
    elems.append(
        Paragraph(
            "For each BASIC assembly, combine the required purified clip reactions in a final volume of 10 μl in 1x Assembly or NEB CutSmart buffer as follows:",
            styles["BodyText"],
        ))
    elems.append(Spacer(1, 0.4 * cm))
    elems.append(
        Table(
            PROCESSED_ASSEMBLY_REACTION_3,
            colWidths=[7 * cm, 4 * cm],
            style=style_no_split,
        ))
    elems.append(
        Paragraph(
            "Run assembly reaction in PCR machine with following programme",
            styles["BodyText"],
        ))
    elems.append(Spacer(1, 0.4 * cm))
    elems.append(
        Table(
            PROCESSED_PCR_MACHINE_3,
            colWidths=[7 * cm, 4 * cm],
            style=style_no_split,
        ))
    # Assembly Reaction 4
    elems.append(Paragraph(
        "Transformation",
        styles["Heading2"],
    ))
    elems.append(
        Paragraph(
            "Use 50 μl of chemically competent cells DH5alpha with high transformation efficiency  (10^9 CFU/μg pUC19, for instance NEB C2987) to transform 5 μl of each BASIC assembly: ",
            styles["BodyText"],
        ))
    elems.append(
        ListFlowable([
            Paragraph(
                "Chemically competent cells are stored at -80°C. ",
                styles["BodyText"],
            ),
            Paragraph(
                "Thaw competent cells on ice (takes 5-10 min); 50 μl per BASIC assembly to be transformed. ",
                styles["BodyText"],
            ),
            Paragraph(
                "Cool 5 μl of BASIC DNA assembly in 1.5 ml microcentrifuge tube on ice. ",
                styles["BodyText"],
            ),
            Paragraph(
                "Add 50 μl of competent cells to each precooled 5 μl BASIC reaction. ",
                styles["BodyText"],
            ),
            Paragraph("Incubate on ice for 20 min. ", styles["BodyText"]),
            Paragraph(
                "Apply heat shock in 42°C water bath for 45s and place back on ice for 2 min. ",
                styles["BodyText"],
            ),
            Paragraph(
                "Add 200 μl SOC medium to each tube and incubate shaking at 37°C for 1h recovery. ",
                styles["BodyText"],
            ),
            Paragraph(
                "Spot or plate cells on agar plates with appropriate antibiotics. Depending on number of parts assembled and transformation efficiency 2-250 μl might be spotted or plated. ",
                styles["BodyText"],
            ),
            Paragraph(
                "Incubate agar plates at 37°C overnight, next day pick colony for assay or miniprep. ",
                styles["BodyText"],
            ),
        ]))
    pdf.build(elems, canvasmaker=PageNumCanvas)

    return pdf_filename
예제 #22
0
def picklist_to_pdf(invoice, outf):
    normal_style = ParagraphStyle("normal", fontName="Helvetica")
    piece_condition_style = ParagraphStyle("piececondition", normal_style, fontSize=normal_style.fontSize - 2,
                                           leading=normal_style.leading - 2)
    piece_details_style = ParagraphStyle("pieceseller", piece_condition_style)

    def invoice_header(canvas, doc):
        draw_invoice_header(canvas, doc, invoice, "Pick-List for:")

    doc = SimpleDocTemplate(outf, pagesize=LETTER,
                            leftMargin=0.75 * inch, rightMargin=0.75 * inch,
                            topMargin=1.75 * inch, bottomMargin=0.75 * inch,
                            onFirstPage=invoice_header, onLaterPages=invoice_header)

    story = []

    body_data = [
        ["Loc.", "Code", "\u2714", "Description", "Amount", "\u2714"],
        [Paragraph('<para align="right">Confirm Bidder ID on each sheet</para>', normal_style), "", "", "", "", "[ ]"],
    ]

    num_items = 0
    for item in invoice.invoiceitem_set.order_by("piece__location", "piece__artist__artistid", "piece__pieceid"):
        num_items += 1
        piece = item.piece
        paragraphs = [
            Paragraph("<i>" + escape(piece.name) + "</i> \u2014 by " + escape(piece.artistname()), normal_style)]
        details_body_parts = [escape(piece.media)]
        if piece.condition:
            details_body_parts.append(escape(piece.condition))
        if piece.other_artist:
            details_body_parts.append(escape("sold by " + piece.artist.artistname()))
        paragraphs.append(Paragraph(" \u2014 ".join(details_body_parts), piece_details_style))
        body_data.append([piece.location, piece.code, "[ ]", paragraphs,
                          Paragraph("<para align=\"right\"><b>" + escape(str(item.price)) + "</b></para>",
                                    normal_style),
                          "[ ]"])

    body_data.append([Paragraph('<para align="right">Confirm <b>%s</b> items, <b>%s</b> '
                                'bid-sheets, then initial</para>' % (num_items, num_items),
                                normal_style), "", "", "", "", "__"])

    body_table_style = [
        ("FONTSIZE", (0, 0), (-1, 0), normal_style.fontSize - 4),
        ("FONT", (0, 0), (-1, 0), "Helvetica-Bold"),
        ("LEADING", (0, 0), (-1, 0), normal_style.leading - 4),
        ("VALIGN", (0, 0), (-1, -1), "TOP"),
        ("ALIGN", (4, 0), (4, -1), "RIGHT"),
        ("SPAN", (0, 1), (4, 1)),
        ("SPAN", (0, num_items + 2), (4, num_items + 2)),
        ("LINEBELOW", (0, 0), (-1, -1), 0.1, colors.black),
        # ("GRID", (0,0), (-1,-1), 0.1, colors.black),
    ]

    body_table = Table(body_data, colWidths=[0.5 * inch, 0.75 * inch, 0.25 * inch, 4.25 * inch, 1 * inch, 0.25 * inch],
                       style=body_table_style,
                       repeatRows=1)
    story.append(body_table)
    story.append(Spacer(0.25 * inch, 0.25 * inch))

    signature_block = KeepTogether([
        Paragraph(escape("I, %s, or a duly authorized agent, acknowledge receiving the above "
                         "%d items." % (invoice.payer.name(), num_items)), normal_style),
        Spacer(0.25 * inch, 0.25 * inch),
        Paragraph("Signature _______________________________________________", normal_style),
        Spacer(0.25 * inch, 0.25 * inch),
        Paragraph("Agent Name _______________________________________________", normal_style),
    ])
    story.append(signature_block)

    # TODO - Figure out a better way of handling this horrible hack.
    # "Paragraph" does not use the sequencer inside the Document, but instead the global sequencer :(
    getSequencer().reset("pageno", 0)

    doc.build(story, onFirstPage=invoice_header, onLaterPages=invoice_header)
예제 #23
0
story.append(inactivevendorwithnoinactivedate(data))
story.append(Spacer(1, .25 * inch))

story.append(PageBreak())
story.append(Spacer(1, .5 * inch))

a = Paragraph(
    "<strong>Vendor status active but they have inactive date</strong>",
    styleN)
x = Spacer(1, .10 * inch)
y = Paragraph(
    "The following lists Active vendors who have inactive dates coded in the system.",
    styleN)
b = Spacer(1, .25 * inch)
c = activestatusinactivedate(data)
story.append(KeepTogether([a, x, y, b, c]))
story.append(Spacer(1, .25 * inch))

story.append(PageBreak())
story.append(Spacer(1, .5 * inch))

story.append(Paragraph("<strong>vendors with no EIN TIN</strong>", styleN))
story.append(Spacer(1, .10 * inch))
story.append(
    Paragraph("The following lists Vendors who have no EIN TIN information.",
              styleN))
story.append(Spacer(1, .25 * inch))
story.append(vendorswithnoEINTIN(data))
story.append(Spacer(1, .25 * inch))

story.append(PageBreak())
예제 #24
0
def render_workout_day(day, nr_of_weeks):
    '''
    Render a table with reportlab with the contents of the training day
    '''

    data = []

    # Init some counters and markers, this will be used after the iteration to
    # set different borders and colours
    day_markers = []
    group_exercise_marker = {}

    # Background colour for days
    # Reportlab doesn't use the HTML hexadecimal format, but has a range of
    # 0 till 1, so we have to convert here.
    header_colour = colors.Color(
        int('73', 16) / 255.0,
        int('8a', 16) / 255.0,
        int('5f', 16) / 255.0)

    set_count = 1
    day_markers.append(len(data))

    p = Paragraph(
        u'<para align="center">%(days)s: %(description)s</para>' % {
            'days': day['days_of_week']['text'],
            'description': day['obj'].description
        }, styleSheet["Bold"])

    data.append([p])

    # Note: the _('Date') will be on the 3rd cell, but since we make a span
    #       over 3 cells, the value has to be on the 1st one
    data.append([_('Date') + ' ', '', ''] + [''] * nr_of_weeks)
    data.append([_('Nr.'), _('Exercise'), _('Reps')] +
                [_('Weight')] * nr_of_weeks)

    # Sets
    exercise_start = len(data)
    for set in day['set_list']:
        group_exercise_marker[set['obj'].id] = {
            'start': len(data),
            'end': len(data)
        }

        # Exercises
        for exercise in set['exercise_list']:
            group_exercise_marker[set['obj'].id]['end'] = len(data)

            data.append([
                set_count,
                Paragraph(exercise['obj'].name, styleSheet["Small"]),
                exercise['setting_text']
            ] + [''] * nr_of_weeks)
        set_count += 1

    table_style = [
        ('FONT', (0, 0), (-1, -1), 'OpenSans'),
        ('FONTSIZE', (0, 0), (-1, -1), 8),
        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
        ('LEFTPADDING', (0, 0), (-1, -1), 2),
        ('RIGHTPADDING', (0, 0), (-1, -1), 0),
        ('TOPPADDING', (0, 0), (-1, -1), 3),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 2),
        ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),

        # Header
        ('BACKGROUND', (0, 0), (-1, 0), header_colour),
        ('BOX', (0, 0), (-1, -1), 1.25, colors.black),
        ('BOX', (0, 1), (-1, -1), 1.25, colors.black),
        ('SPAN', (0, 0), (-1, 0)),

        # Cell with 'date'
        ('SPAN', (0, 1), (2, 1)),
        ('ALIGN', (0, 1), (2, 1), 'RIGHT')
    ]

    # Combine the cells for exercises on the same superset
    for marker in group_exercise_marker:
        start_marker = group_exercise_marker[marker]['start']
        end_marker = group_exercise_marker[marker]['end']

        table_style.append(
            ('VALIGN', (0, start_marker), (0, end_marker), 'MIDDLE'))
        table_style.append(('SPAN', (0, start_marker), (0, end_marker)))

    # Set an alternating background colour for rows with exercises.
    # The rows with exercises range from exercise_start till the end of the data
    # list
    for i in range(exercise_start, len(data) + 1):
        if not i % 2:
            table_style.append(
                ('BACKGROUND', (1, i - 1), (-1, i - 1), colors.lavender))

    # Put everything together and manually set some of the widths
    t = Table(data, style=table_style)
    if len(t._argW) > 1:
        t._argW[0] = 0.6 * cm  # Numbering
        t._argW[1] = 4 * cm  # Exercise
        t._argW[2] = 2 * cm  # Repetitions

    return KeepTogether(t)
예제 #25
0
    def get(self, request, *args, **kwargs):
        gerente = MinturUser.objects.get(groups=Group.objects.get(
            name='gerente_dggt'))
        context = ResolucionDetalle.as_view()(self.request, *args,
                                              **kwargs).context_data
        direccion = Direccion.objects.get(pst=context['resolucion'].pst)

        output = PdfFileWriter()
        #create response object
        response = HttpResponse(content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename=Resolucion.pdf'

        buffer = StringIO()
        doc = SimpleDocTemplate(buffer,
                                pagesize=letter,
                                rightMargin=72,
                                leftMargin=72,
                                topMargin=-50,
                                bottomMargin=100)
        styles = getSampleStyleSheet()
        styles.add(
            ParagraphStyle(name='Justify',
                           alignment=TA_JUSTIFY,
                           fontSize=12,
                           leading=15))
        styles.add(ParagraphStyle(name='Right', alignment=TA_RIGHT))
        styles.add(ParagraphStyle(name='Center', alignment=TA_CENTER))
        styles.add(
            ParagraphStyle(name='Left',
                           alignment=TA_LEFT,
                           fontSize=12,
                           leading=15))
        styles.add(
            ParagraphStyle(name='tit',
                           alignment=TA_CENTER,
                           leftIndent=25,
                           rightIndent=25,
                           fontSize=12,
                           leading=15))

        Story = []

        codigo = context['resolucion'].numero_documento
        fecha = textos.fecha_encabezado(datetime.date.today())
        primer_titulo = 'RESOLUCIÓN DE AJUSTES E IMPOSICIÓN DE SANCIONES VERIFICACION DE DEBERES FORMALES'
        seccion_uno = 'I. DE LOS HECHOS CONSTATADOS:'
        seccion_dos = 'II. DE LA CONCURRENCIA:'
        seccion_tres = 'III. DEL MONTO TOTAL DE LAS SANCIONES A PAGAR:'
        seccion_intereses_moratorios = 'III. DE LOS INTERESES MORATORIOS:'

        #CABECERA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ptext = '<font size=12>%s</font>' % codigo
        Story.append(Paragraph(ptext, styles["Normal"]))
        Story.append(Spacer(1, 12))

        ptext = '<font size=12>%s</font>' % fecha
        Story.append(Paragraph(ptext, styles["Right"]))
        Story.append(Spacer(1, 12))

        data = [['SUJETO PASIVO', context['resolucion'].pst.nombre_o_razon()],
                ['RIF Nº.:', context['resolucion'].pst.rif],
                ['RTN Nº:', context['resolucion'].pst.rtn],
                [
                    'DOMICILIO:',
                    Paragraph(unicode(direccion), styles["Normal"])
                ]]
        Story.append(
            Table(data,
                  colWidths=[100, 350],
                  style=[('GRID', (0, 0), (-1, -1), 0.25, colors.black),
                         ('VALIGN', (0, 0), (-1, -1), 'MIDDLE')]))
        Story.append(Spacer(1, 12))

        #MEMBRETE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ptext = '<u><b>%s</b></u>' % primer_titulo
        Story.append(Paragraph(ptext, styles["tit"]))
        Story.append(Spacer(1, 12))

        ptext = textos.primer_parrafo(datetime.date.today(), gerente)
        Story.append(Paragraph(ptext, styles["Justify"]))
        Story.append(Spacer(1, 12))

        #SECCION UNO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ptext = '<font size=12><b>%s</b></font>' % seccion_uno
        Story.append(Paragraph(ptext, styles["Normal"]))
        Story.append(Spacer(1, 12))

        ptext = textos.seccion_uno_inicio()
        Story.append(Paragraph(ptext, styles["Justify"]))
        Story.append(Spacer(1, 12))

        sancion_numero = 1
        for sancion, ilicitos in context['sanciones'].iteritems():
            ptext = textos.segundo_parrafo(sancion_numero,
                                           context['resolucion'], sancion,
                                           ilicitos)
            Story.append(Paragraph(ptext, styles["Justify"]))
            Story.append(Spacer(1, 12))
            sancion_numero += 1

            th = [
                Paragraph('Periodo', styles['Center']),
                Paragraph(u'Sanción (UT)', styles['Center']),
                Paragraph(u'Incremento por Reincidencia (UT)',
                          styles['Center']),
                Paragraph('Total (UT)', styles['Center']),
                Paragraph('Valor de la UT a la Fecha', styles['Center']),
                Paragraph('Equivalencia en Bs.', styles['Center'])
            ]
            if ilicitos[0].declaracion:
                th.insert(
                    1,
                    Paragraph(u'Fecha Límite de Declaración',
                              styles['Center']))
                th.insert(2,
                          Paragraph(u'Fecha de Declaración', styles['Center']))
            data = [
                th,
            ]
            for ilicito in ilicitos:
                tr = [
                    ilicito.periodo.strftime('%x'), ilicito.sancion.ut_min,
                    ilicito.sancion_ut - ilicito.sancion.ut_min,
                    ilicito.sancion_ut, ilicito.resolucion.valor_ut,
                    ilicito.sancion_ut * ilicito.resolucion.valor_ut
                ]
                if ilicitos[0].declaracion:
                    tr.insert(1,
                              ilicito.fecha_limite_declaracion.strftime('%x'))
                    tr.insert(
                        2,
                        ilicito.declaracion.fecha_presentacion.strftime('%x'))
                data.append(tr)
            Story.append(
                KeepTogether(
                    Table(data,
                          style=[('GRID', (0, 0), (-1, -1), 0.25,
                                  colors.black),
                                 ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                                 ('ALIGN', (0, 0), (-1, -1), 'CENTER')])))
            Story.append(Spacer(1, 12))

        #SECCION DOS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ptext = '<font size=12><b>%s</b></font>' % seccion_dos
        Story.append(Paragraph(ptext, styles["Normal"]))
        Story.append(Spacer(1, 12))

        ptext = textos.seccion_dos_inicio()
        Story.append(Paragraph(ptext, styles["Justify"]))
        Story.append(Spacer(1, 12))

        data = [
            [
                u'Ilícito', u'Sanción (BsF)', u'Tipo de Sanción',
                u'Total Sanción Agravada (BsF)'
            ],
        ]
        for sancion, decimal in context['concurrencia'][1].iteritems():
            data.append([
                u'Art. ' + unicode(sancion.cot_articulo), decimal * 2,
                u'Mitad de la Sanción', decimal
            ])
        data.append([
            u'Art. ' + unicode(context['concurrencia'][0][0].cot_articulo),
            context['concurrencia'][0][1], u'Sanción más Grave',
            context['concurrencia'][0][1]
        ])
        Story.append(
            KeepTogether(
                Table(data,
                      style=[('GRID', (0, 0), (-1, -1), 0.25, colors.black),
                             ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                             ('ALIGN', (0, 0), (-1, -1), 'CENTER')])))
        Story.append(Spacer(1, 12))

        # INTERESES MORATORIOS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        if context['intereses_moratorios']:
            seccion_tres = seccion_tres.replace(u'III', u'IV')

            periodos = [(lambda periodo: periodo[0].upper() + periodo[1:])(
                interes.declaracion.periodo.strftime('%B-%Y'))
                        for interes in context['intereses_moratorios']]

            ptext = '<font size=12><b>%s</b></font>' % seccion_intereses_moratorios
            Story.append(Paragraph(ptext, styles["Normal"]))
            Story.append(Spacer(1, 12))

            ptext = textos.seccion_intereses_moratorios_inicio(periodos)
            Story.append(Paragraph(ptext, styles["Justify"]))
            Story.append(Spacer(1, 12))

            data = [[
                u'Periodo',
                u'Fecha de\nVencimiento de\nla Obligación',
                u'Fecha de\nPago',
                u'Días de\nMora',
                u'Tributo Pagado\nExtemporaneamente\n(BsF)',
                u'Tasa de Interés\nFijada por el\nBCV según\nG.O. (%)',
                (u'Tasa de Interés\npara Cálculo de\nInterés de Mora\n'
                 u'Art. 66 C.O.T.\n(%)'),
                u'Factor',
                u'Monto\nIntereses\nMoratorios\n(BsF)',
            ]]

            for interes in context['intereses_moratorios']:
                pago = interes.declaracion.concepto_pago.pago

                data.append([
                    (lambda periodo: periodo[0].upper() + periodo[1:])(
                        interes.declaracion.periodo.strftime('%b-%y')),
                    pago.fecha_vencimiento.strftime('%d/%m/%Y'),
                    pago.fecha_liquidacion.strftime('%d/%m/%Y'),
                    interes.dias_mora,
                    pago.total,
                    interes.tasa_interes_bcv,
                    interes.art66cot,
                    interes.factor,
                    interes.monto_interes,
                ])

            Story.append(
                KeepTogether(
                    Table(data,
                          style=[('FONTSIZE', (0, 0), (-1, -1), 7),
                                 ('GRID', (0, 0), (-1, -1), 0.25,
                                  colors.black),
                                 ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                                 ('ALIGN', (0, 0), (-1, -1), 'CENTER')])))

            Story.append(Spacer(1, 12))

        #SECCION TRES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ptext = '<font size=12><b>%s</b></font>' % seccion_tres
        Story.append(Paragraph(ptext, styles["Normal"]))
        Story.append(Spacer(1, 12))

        ptext = textos.seccion_tres_inicio(
            context['resolucion'].pst.nombre_o_razon())
        Story.append(Paragraph(ptext, styles["Justify"]))
        Story.append(Spacer(1, 12))

        data = [
            ['Concepto', u'Sanción (BsF)'],
        ]
        for sancion, decimal in context['concurrencia'][1].iteritems():
            data.append([u'Sanción Nº ' + unicode(sancion.codigo), decimal])
        data.append([
            u'Sanción Nº ' + unicode(context['concurrencia'][0][0].codigo),
            context['concurrencia'][0][1]
        ])

        if context['total_intereses_moratorios']:
            data.append([(u'Intereses moratorios por pago extemporáneo'
                          u'(Art. 66 del COT)'),
                         context['total_intereses_moratorios']])

        data.append([u'Total General a Pagar:', context['total_pagar']])
        Story.append(
            KeepTogether(
                Table(data,
                      style=[('GRID', (0, 0), (-1, -1), 0.25, colors.black),
                             ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                             ('ALIGN', (0, 0), (-1, -1), 'CENTER')])))
        Story.append(Spacer(1, 12))

        ptext = textos.seccion_tres_fin(
            context['resolucion'].pst.nombre_o_razon())
        Story.append(Paragraph(ptext, styles["Justify"]))
        Story.append(Spacer(1, 12))

        #FOOTER ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Story.append(Spacer(1, 10 * 12))

        ptext = textos.footer_texto(gerente)
        footer_texto = Paragraph(ptext, styles["tit"])

        ptext = textos.footer_firma()
        footer_firma = Paragraph(ptext, styles["Left"])
        Story.append(KeepTogether([footer_texto, Spacer(1, 12), footer_firma]))

        Story.append(PageBreak())

        doc.build(Story)

        watermark = PdfFileReader(buffer)
        for page in xrange(watermark.getNumPages()):
            input = PdfFileReader(
                file(os.path.join(settings.PDF_ROOT, 'blanco.pdf'), 'rb'))
            tmp = input.getPage(0)
            tmp.mergePage(watermark.getPage(page))
            output.addPage(tmp)

        output.write(response)
        return response
예제 #26
0
파일: pdf.py 프로젝트: mfkiwl/drivers
 def endKeep(self, chapter, s):
     S = self.report[chapter]
     k = KeepTogether(S[s:])
     S[s:] = [k]
예제 #27
0
def render_workout_day(day,
                       nr_of_weeks=7,
                       images=False,
                       comments=False,
                       only_table=False):
    '''
    Render a table with reportlab with the contents of the training day

    :param day: a workout day object
    :param nr_of_weeks: the numbrer of weeks to render, default is 7
    :param images: boolean indicating whether to also draw exercise images
           in the PDF (actually only the main image)
    :param comments: boolean indicathing whether the exercise comments will
           be rendered as well
    :param only_table: boolean indicating whether to draw a table with space
           for weight logs or just a list of the exercises
    '''

    # If rendering only the table, reset the nr of weeks, since these columns
    # will not be rendered anyway.
    if only_table:
        nr_of_weeks = 0

    data = []

    # Init some counters and markers, this will be used after the iteration to
    # set different borders and colours
    day_markers = []
    group_exercise_marker = {}

    # Background colour for days
    # Reportlab doesn't use the HTML hexadecimal format, but has a range of
    # 0 till 1, so we have to convert here.
    header_colour = colors.Color(
        int('73', 16) / 255.0,
        int('8a', 16) / 255.0,
        int('5f', 16) / 255.0)

    set_count = 1
    day_markers.append(len(data))

    p = Paragraph(
        u'<para align="center">%(days)s: %(description)s</para>' % {
            'days': day['days_of_week']['text'],
            'description': day['obj'].description
        }, styleSheet["Bold"])

    data.append([p])

    # Note: the _('Date') will be on the 3rd cell, but since we make a span
    #       over 3 cells, the value has to be on the 1st one
    data.append([_('Date') + ' ', '', ''] + [''] * nr_of_weeks)
    data.append([_('Nr.'), _('Exercise'), _('Reps')] +
                [_('Weight')] * nr_of_weeks)

    # Sets
    exercise_start = len(data)
    for set in day['set_list']:
        group_exercise_marker[set['obj'].id] = {
            'start': len(data),
            'end': len(data)
        }

        # Exercises
        for exercise in set['exercise_list']:
            group_exercise_marker[set['obj'].id]['end'] = len(data)

            # Process the settings
            if exercise['has_weight']:
                setting_out = []
                for i in exercise['setting_text'].split(u'–'):
                    setting_out.append(
                        Paragraph(i, styleSheet["Small"], bulletText=''))
            else:
                setting_out = Paragraph(exercise['setting_text'],
                                        styleSheet["Small"])

            # Collect a list of the exercise comments
            item_list = [Paragraph('', styleSheet["Small"])]
            if comments:
                item_list = [
                    ListItem(Paragraph(i,
                                       style=styleSheet["ExerciseComments"]))
                    for i in exercise['comment_list']
                ]

            # Add the exercise's main image
            image = Paragraph('', styleSheet["Small"])
            if images:
                if exercise['obj'].main_image:

                    # Make the images somewhat larger when printing only the workout and not
                    # also the columns for weight logs
                    if only_table:
                        image_size = 2
                    else:
                        image_size = 1.5

                    image = Image(exercise['obj'].main_image.image)
                    image.drawHeight = image_size * cm * image.drawHeight / image.drawWidth
                    image.drawWidth = image_size * cm

            # Put the name and images and comments together
            exercise_content = [
                Paragraph(exercise['obj'].name, styleSheet["Small"]), image,
                ListFlowable(item_list,
                             bulletType='bullet',
                             leftIndent=5,
                             spaceBefore=7,
                             bulletOffsetY=-3,
                             bulletFontSize=3,
                             start='square')
            ]

            data.append([set_count, exercise_content, setting_out] +
                        [''] * nr_of_weeks)
        set_count += 1

    table_style = [
        ('FONT', (0, 0), (-1, -1), 'OpenSans'),
        ('FONTSIZE', (0, 0), (-1, -1), 8),
        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
        ('LEFTPADDING', (0, 0), (-1, -1), 2),
        ('RIGHTPADDING', (0, 0), (-1, -1), 0),
        ('TOPPADDING', (0, 0), (-1, -1), 3),
        ('BOTTOMPADDING', (0, 0), (-1, -1), 2),
        ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),

        # Header
        ('BACKGROUND', (0, 0), (-1, 0), header_colour),
        ('BOX', (0, 0), (-1, -1), 1.25, colors.black),
        ('BOX', (0, 1), (-1, -1), 1.25, colors.black),
        ('SPAN', (0, 0), (-1, 0)),

        # Cell with 'date'
        ('SPAN', (0, 1), (2, 1)),
        ('ALIGN', (0, 1), (2, 1), 'RIGHT')
    ]

    # Combine the cells for exercises on the same superset
    for marker in group_exercise_marker:
        start_marker = group_exercise_marker[marker]['start']
        end_marker = group_exercise_marker[marker]['end']

        table_style.append(
            ('VALIGN', (0, start_marker), (0, end_marker), 'MIDDLE'))
        table_style.append(('SPAN', (0, start_marker), (0, end_marker)))

    # Set an alternating background colour for rows with exercises.
    # The rows with exercises range from exercise_start till the end of the data
    # list
    for i in range(exercise_start, len(data) + 1):
        if not i % 2:
            table_style.append(
                ('BACKGROUND', (1, i - 1), (-1, i - 1), colors.lavender))

    # Put everything together and manually set some of the widths
    t = Table(data, style=table_style)
    if len(t._argW) > 1:
        if only_table:
            t._argW[0] = 0.6 * cm  # Numbering
            t._argW[1] = 8 * cm  # Exercise
            t._argW[2] = 3.5 * cm  # Repetitions
        else:
            t._argW[0] = 0.6 * cm  # Numbering
            t._argW[1] = 4 * cm  # Exercise
            t._argW[2] = 2.5 * cm  # Repetitions

    return KeepTogether(t)
예제 #28
0
    def run(self):
        outputfile = self.parameters['OUTPUTFILE'].value
        tag = self.parameters['TAG'].value
        silent = positive(self.parameters['SILENT'].value)

        #from reportlab.pdfgen import canvas
        from reportlab.lib import colors
        from reportlab.lib.units import cm
        from reportlab.lib.pagesizes import A4
        from reportlab.platypus import KeepTogether, SimpleDocTemplate, Table, TableStyle, Paragraph, PageBreak
        from reportlab.lib.styles import getSampleStyleSheet
        styles = getSampleStyleSheet()

        doc = SimpleDocTemplate(outputfile, pagesize=A4)
        entries = []
        
        #print(styles.list())
        # PREPARE STYLES
        titlestyle = styles['Title']
        heading1style = styles['Heading1']
        headingstyle = styles['Heading2']
        textstyle = styles['BodyText']

        # HEADING
        entries.append(Paragraph('<para align=center spaceAfter=20>VULNERABILITY ANALYSIS REPORT</para>', titlestyle))
        

        cves_lists = [x.get('cves') for x in tb[tag+'_filesystems']] if tag+'_filesystems' in tb else []
        exploits = {} if tag+'_exploits' not in tb else tb[tag+'_exploits']
        exploit_count = len(set([x for k,v in exploits.items() for x in v]))

        # ADD GENERAL INFO
        if tag+'_general' in tb:
            #entries.append(Paragraph('<para spaceBefore=30>General info<para>', headingstyle))
            data = [[x[0]+':', ', '.join(x[1]) if type(x[1]) in [list, tuple, set] else x[1]] for x in tb[tag+'_general']]
            if len(cves_lists) > 0:
                data.append(['Vulnerable:', Paragraph('<para><font color=%s><b>%s</b></font> (<i>%s</i> accuracy)</para>' % (('red', 'YES', tb[tag+'_accuracy']) if max([0]+[len(x) for x in cves_lists]) else ('green', 'NO', tb[tag+'_accuracy'])), textstyle)])
                data.append(['Known exploits:', Paragraph('<para><font color=%s><b>%s</b></font></para>' % (('red', exploit_count) if exploit_count>0 else ('green', exploit_count)), textstyle)])
            entries.append(Table(data, None, None, hAlign='LEFT'))
        
        # for each fs
        fscount = -1
        for fs in tb[tag+'_filesystems'] if tag+'_filesystems' in tb else []:
            fscount += 1
            entries.append(Paragraph('<para spaceBefore=20>File System #%d<para>' % (fscount), heading1style))
            data = [['Root:', fs['name']]]
            entries.append(Table(data, None, None, hAlign='LEFT'))
        
            # ADD SYSTEM INFO
            if 'system' in fs:
                entries.append(Paragraph('<para spaceBefore=20>System info<para>', headingstyle))
                data = [[x[0]+':', ', '.join(x[1]) if type(x[1]) in [list, tuple, set] else x[1]] for x in fs['system']+fs['os']]
                t = Table(data, None, None, hAlign='LEFT')
                t.setStyle(TableStyle([        
                    ('VALIGN', (0, 0), (-1, -1), 'TOP'),
                ]))
                entries.append(t)
       

            # ADD CRON ENTRIES
            data = []
            tospan = []
            if 'cron' in fs:
                for linec in range(len(fs['cron'])):
                    line = fs['cron'][linec]
                    if len(re.split('[ \t]+', line[0]))==1:
                        l = [line[0], '', '', '', '', line[1], Paragraph('<para>%s</para>' % (line[2]), textstyle)]
                        tospan.append(linec)
                    else:
                        l = re.split('[ \t]+', line[0])[:5]+[line[1], Paragraph('<para>%s</para>' %(line[2]), textstyle)]
                    data.append(l)
                if len(data)>0:
                    entries.append(Paragraph('<para>Cron entries:<para>', headingstyle))
                    t=Table(data, (None, None, None, None, None, None, 11*cm), None, hAlign='LEFT')
                    t.setStyle(TableStyle([('SPAN', (0, x), (4, x)) for x in tospan]+
                                          [('%sPADDING' % x, (0, 0), (-1, -1), 0) for x in ['TOP', 'BOTTOM']]+
                                          [('%sPADDING' % x, (0, 0), (-1, -1), 2) for x in ['LEFT', 'RIGHT']]+
                                          [
                                              ('VALIGN', (0, 0), (-1, -1), 'TOP'),
                                              #('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
                                          ]
                                         ))
                    entries.append(t)


            # ADD CVE SUMMARY
            entries.append(Paragraph('<para spaceBefore=30>Vulnerable packages</para>', headingstyle))
            data = [['Package', 'Version', 'Vulnerabilities', '', ''], ['', '', Paragraph('<para textColor=red align=center><b>HIGH</b></para>', textstyle), Paragraph('<para textColor=orange align=center><b>MEDIUM</b></para>', textstyle), Paragraph('<para textColor=yellowgreen align=center><b>LOW</b></para>', textstyle)]]
            vulnerable = {}
            totals = [0, 0, 0]
            if 'cves' in fs:
                for x in fs['cves']:
                    key = (x[1], x[14])
                    if key not in vulnerable:
                        vulnerable[key] = [0, 0, 0]
                    vulnerable[key][(0 if x[5] == 'High' else (1 if x[5] == 'Medium' else 2))] += 1
                notnull = lambda x: x if x > 0 else ''
            for x in sorted(vulnerable.keys(), key=lambda x: x[0]):
                name = self.get_name_with_origin(x[0])
                data.append((name, self.limit(x[1], 20), notnull(vulnerable[x][0]), notnull(vulnerable[x][1]), notnull(vulnerable[x][2])))
                for i in range(0, 3):
                    totals[i] += vulnerable[x][i]
            data.append(['Total:', '', totals[0], totals[1], totals[2]])
            data.append(['', '', sum(totals), '', ''])
            
            tvulnerable = Table(data, (6*cm, 4*cm, 2*cm, 2*cm, 2*cm), None, hAlign='LEFT')
            tvulnerable.setStyle(TableStyle([
                ('SPAN', (0, 0), (0, 1)), # product
                ('SPAN', (1, 0), (1, 1)), # version
                ('SPAN', (-3, 0), (-1, 0)), # vulnerabilities
                ('SPAN', (0, -2), (1, -1)), # total
                ('SPAN', (-3, -1), (-1, -1)), # grand total
                ('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
                ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ]))

            entries.append(tvulnerable)
            
            # ADD SPECIFIC CVEs
            if 'cves' in fs and len(fs['cves'])>0:
                entries.append(Paragraph('<para spaceBefore=30>Detected vulnerabilities<para>', headingstyle))
                # exploitable first
                for c in sorted(fs['cves'], key=lambda x: x[4] not in exploits): 
                    if len(c) < 14:
                        continue
                    if c[6] == '2.0': # CVSS 2.0
                        description = c[12].replace('<', '&lt;').replace('>', '&gt;')
                        para_exploits = '' if c[4] not in exploits.keys() else Paragraph('<para align=justify>Exploits: '+', '.join(exploits[c[4]])+'</para>', textstyle)
                        data = [['', c[4], '%s %s\n(%s %s %s)\n' % (self.get_name_with_origin(c[1]), self.limit(c[14], 20), c[0], c[1], c[2]), 'Base:', c[8]], ['', '', '', 'Impact:', c[9]], ['', '', '', 'Exploitability:', c[10]], ['', c[11], '', 'Score:', c[7]], [Paragraph('<para align=justify>'+description+'</para>', textstyle), '', '', '', ''], [para_exploits, '', '', '', '']]
                    else:
                        data = []
                    t = Table(data, colWidths=(0.5*cm, 6*cm, 7*cm, 2.5*cm, 1.5*cm))
                    color = colors.yellow # low severity
                    if c[5] == 'Medium':
                        color = colors.orange
                    elif c[5] == 'High':
                        color = colors.salmon
                    t.setStyle(TableStyle([
                        #('GRID', (0, -2), (-1, -2), 0.5, colors.grey),
                        ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                        #('BACKGROUND', (0, 0), (-1, 3), color),
                        ('BACKGROUND', (0, 0), (0, 3), color),
                        ('SPAN', (0, -1), (-1, -1)), # exploit
                        ('SPAN', (0, -2), (-1, -2)), # description
                        ('SPAN', (1, 0), (1, 2)), # cve
                        ('SPAN', (2, 0), (2, -3)), # package
                        ('ALIGN', (3, 0), (3, 4), 'RIGHT'),
                        ('FONTSIZE', (0, 0), (-1, -1), 10),
                        ('FONTSIZE', (1, 0), (1, 0), 15), # cve
                    ]))
                    entries.append(KeepTogether(t))
            entries.append(PageBreak()) # for every FS
        doc.build(entries)
        if not silent:
            log.ok('Report generated.')

        return None
예제 #29
0
    def _get_story(self, doc):
        has_taxes = any(il.tax_value for il in self.invoice.lines.all())

        story = [
            NextPageTemplate('FirstPage'),
            Paragraph((pgettext('invoice', 'Tax Invoice') if str(
                self.invoice.invoice_from_country) == 'AU' else pgettext(
                    'invoice', 'Invoice')) if not self.invoice.is_cancellation
                      else pgettext('invoice', 'Cancellation'),
                      self.stylesheet['Heading1']),
            Spacer(1, 5 * mm),
            NextPageTemplate('OtherPages'),
        ]
        story += self._get_intro()

        taxvalue_map = defaultdict(Decimal)
        grossvalue_map = defaultdict(Decimal)

        tstyledata = [
            ('ALIGN', (1, 0), (-1, -1), 'RIGHT'),
            ('VALIGN', (0, 0), (-1, -1), 'TOP'),
            ('FONTNAME', (0, 0), (-1, 0), self.font_bold),
            ('FONTNAME', (0, -1), (-1, -1), self.font_bold),
            ('LEFTPADDING', (0, 0), (0, -1), 0),
            ('RIGHTPADDING', (-1, 0), (-1, -1), 0),
        ]
        if has_taxes:
            tdata = [(
                pgettext('invoice', 'Description'),
                pgettext('invoice', 'Qty'),
                pgettext('invoice', 'Tax rate'),
                pgettext('invoice', 'Net'),
                pgettext('invoice', 'Gross'),
            )]
        else:
            tdata = [(
                pgettext('invoice', 'Description'),
                pgettext('invoice', 'Qty'),
                pgettext('invoice', 'Amount'),
            )]

        total = Decimal('0.00')
        for line in self.invoice.lines.all():
            if has_taxes:
                tdata.append((
                    Paragraph(line.description, self.stylesheet['Normal']),
                    "1",
                    localize(line.tax_rate) + " %",
                    money_filter(line.net_value, self.invoice.event.currency),
                    money_filter(line.gross_value,
                                 self.invoice.event.currency),
                ))
            else:
                tdata.append((
                    Paragraph(line.description, self.stylesheet['Normal']),
                    "1",
                    money_filter(line.gross_value,
                                 self.invoice.event.currency),
                ))
            taxvalue_map[line.tax_rate, line.tax_name] += line.tax_value
            grossvalue_map[line.tax_rate, line.tax_name] += line.gross_value
            total += line.gross_value

        if has_taxes:
            tdata.append([
                pgettext('invoice', 'Invoice total'), '', '', '',
                money_filter(total, self.invoice.event.currency)
            ])
            colwidths = [a * doc.width for a in (.50, .05, .15, .15, .15)]
        else:
            tdata.append([
                pgettext('invoice', 'Invoice total'), '',
                money_filter(total, self.invoice.event.currency)
            ])
            colwidths = [a * doc.width for a in (.65, .05, .30)]

        table = Table(tdata, colWidths=colwidths, repeatRows=1)
        table.setStyle(TableStyle(tstyledata))
        story.append(table)

        story.append(Spacer(1, 15 * mm))

        if self.invoice.payment_provider_text:
            story.append(
                Paragraph(self.invoice.payment_provider_text,
                          self.stylesheet['Normal']))

        if self.invoice.additional_text:
            story.append(
                Paragraph(self.invoice.additional_text,
                          self.stylesheet['Normal']))
            story.append(Spacer(1, 15 * mm))

        tstyledata = [
            ('ALIGN', (1, 0), (-1, -1), 'RIGHT'),
            ('LEFTPADDING', (0, 0), (0, -1), 0),
            ('RIGHTPADDING', (-1, 0), (-1, -1), 0),
            ('FONTSIZE', (0, 0), (-1, -1), 8),
            ('FONTNAME', (0, 0), (-1, -1), self.font_regular),
        ]
        thead = [
            pgettext('invoice', 'Tax rate'),
            pgettext('invoice', 'Net value'),
            pgettext('invoice', 'Gross value'),
            pgettext('invoice', 'Tax'), ''
        ]
        tdata = [thead]

        for idx, gross in grossvalue_map.items():
            rate, name = idx
            if rate == 0:
                continue
            tax = taxvalue_map[idx]
            tdata.append([
                localize(rate) + " % " + name,
                money_filter(gross - tax, self.invoice.event.currency),
                money_filter(gross, self.invoice.event.currency),
                money_filter(tax, self.invoice.event.currency), ''
            ])

        def fmt(val):
            try:
                return vat_moss.exchange_rates.format(
                    val, self.invoice.foreign_currency_display)
            except ValueError:
                return localize(
                    val) + ' ' + self.invoice.foreign_currency_display

        if len(tdata) > 1 and has_taxes:
            colwidths = [a * doc.width for a in (.25, .15, .15, .15, .3)]
            table = Table(tdata,
                          colWidths=colwidths,
                          repeatRows=2,
                          hAlign=TA_LEFT)
            table.setStyle(TableStyle(tstyledata))
            story.append(Spacer(5 * mm, 5 * mm))
            story.append(
                KeepTogether([
                    Paragraph(pgettext('invoice', 'Included taxes'),
                              self.stylesheet['FineprintHeading']), table
                ]))

            if self.invoice.foreign_currency_display and self.invoice.foreign_currency_rate:
                tdata = [thead]

                for idx, gross in grossvalue_map.items():
                    rate, name = idx
                    if rate == 0:
                        continue
                    tax = taxvalue_map[idx]
                    gross = round_decimal(gross *
                                          self.invoice.foreign_currency_rate)
                    tax = round_decimal(tax *
                                        self.invoice.foreign_currency_rate)
                    net = gross - tax

                    tdata.append([
                        localize(rate) + " % " + name,
                        fmt(net),
                        fmt(gross),
                        fmt(tax), ''
                    ])

                table = Table(tdata,
                              colWidths=colwidths,
                              repeatRows=2,
                              hAlign=TA_LEFT)
                table.setStyle(TableStyle(tstyledata))

                story.append(
                    KeepTogether([
                        Spacer(1, height=2 * mm),
                        Paragraph(
                            pgettext(
                                'invoice',
                                'Using the conversion rate of 1:{rate} as published by the European Central Bank on '
                                '{date}, this corresponds to:').
                            format(rate=localize(
                                self.invoice.foreign_currency_rate),
                                   date=date_format(
                                       self.invoice.foreign_currency_rate_date,
                                       "SHORT_DATE_FORMAT")),
                            self.stylesheet['Fineprint']),
                        Spacer(1, height=3 * mm), table
                    ]))
        elif self.invoice.foreign_currency_display and self.invoice.foreign_currency_rate:
            story.append(Spacer(1, 5 * mm))
            story.append(
                Paragraph(
                    pgettext(
                        'invoice',
                        'Using the conversion rate of 1:{rate} as published by the European Central Bank on '
                        '{date}, the invoice total corresponds to {total}.').
                    format(rate=localize(self.invoice.foreign_currency_rate),
                           date=date_format(
                               self.invoice.foreign_currency_rate_date,
                               "SHORT_DATE_FORMAT"),
                           total=fmt(total)), self.stylesheet['Fineprint']))

        return story
예제 #30
0
def format_doc(filename, local_notams, area_notams, boring_notams,
               local_coords, header, date, mapinfo, mapdata):

    date_str = date.strftime('%a, %d %b %y')

    # Define Platypus template and paragraph styles
    doc = DocTemplate(filename,
                      date_str,
                      local_coords,
                      mapinfo,
                      mapdata,
                      leftMargin=15 * mm,
                      rightMargin=15 * mm,
                      bottomMargin=10 * mm,
                      topMargin=15 * mm,
                      title='NOTAM',
                      author='Freeflight')

    subStyle = ParagraphStyle('Sub',
                              fontName='Helvetica-Oblique',
                              fontSize=16,
                              spaceBefore=2 * mm,
                              spaceAfter=5 * mm)

    notamStyle = ParagraphStyle('Notam',
                                fontName='Helvetica',
                                fontSize=9,
                                bulletFontName='Helvetica-Bold',
                                bulletFontSize=10,
                                leftIndent=8 * mm,
                                spaceAfter=3 * mm)

    otherStyle = ParagraphStyle('Other',
                                fontName='Helvetica',
                                fontSize=9,
                                bulletFontName='Symbol',
                                bulletFontSize=10,
                                leftIndent=8 * mm,
                                spaceAfter=3 * mm)

    # Generate the NOTAM document.
    story = []
    story.append(PageBreak())

    story.append(Paragraph('<b>NOTAM Header</b>', subStyle))
    h = '\n'.join([hl for hl in header.splitlines() if hl])
    story.append(XPreformatted(h, otherStyle))
    story.append(Paragraph('<b>Plotted Navigation Warnings</b>', subStyle))
    story.append(Paragraph(
        'Plotted Navigation Warnings are Restrictions of all types '\
        'and Warnings of type: <i>Air Display</i>, <i>Aerobatics</i>, '\
        '<i>Glider Flying</i>, <i>Missile, Gun or Rocket Firing</i>, '\
        '<i>Parachute Dropping Area</i> and <i>Radioactive '\
        'Materials and Toxic Chemicals</i>. Also plotted are activation or '\
        'installation of Airspace types <i>CTZ</i>, <i>CTA</i>, <i>ATS '\
        'route</i>, <i>TMA</i> and <i>ATZ</i>', otherStyle))
    for n, notam in enumerate(local_notams):
        story.append(
            KeepTogether(
                XPreformatted(notam, notamStyle, bulletText=str(n + 1))))

    if area_notams:
        paras = [
            XPreformatted(n, otherStyle, bulletText="\N{BULLET}")
            for n in area_notams
        ]

        head = '<b>Non-Plotted Navigation Warnings</b> (Radius > 30nm)'
        story.append(KeepTogether([Paragraph(head, subStyle), paras[0]]))
        for p in paras[1:]:
            story.append(KeepTogether(p))

    if boring_notams:
        paras = [
            XPreformatted(n, otherStyle, bulletText="\N{BULLET}")
            for n in boring_notams
        ]

        head = '<b>All Other Navigation Warnings</b> (Sorted South to North)'
        story.append(KeepTogether([Paragraph(head, subStyle), paras[0]]))
        for p in paras[1:]:
            story.append(KeepTogether(p))

    doc.build(story, onFirstPage=drawFirstPage)