Beispiel #1
0
 def test_06_fontsize(self):
     from reportlab.lib.pagesizes import A4
     from reportlab.pdfgen.canvas import Canvas
     from reportlab.lib.units import inch
     from reportlab.lib.colors import red, magenta
     c = Canvas('demo.pdf', pagesize=A4)
     c.translate(inch, inch)
     c.setFont("Times-Roman", 20)
     c.setFillColor(red)
     c.saveState()
     c.drawCentredString(2.75 * inch, 2.5 * inch, "Font size excmples")
     c.setFillColor(magenta)
     size = 7
     x = 2.3 * inch
     y = 1.3 * inch
     for line in range(7):
         c.setFont("Helvetica", size)
         c.drawRightString(x, y, "%s points" % size)
         c.drawString(x, y, "test")
         y = y - size * 1.2
         size = size + 1.5
     c.restoreState()
     c.drawString(0, 0, "%s" % c.getAvailableFonts())
     c.showPage()
     c.save()
Beispiel #2
0
def projects(c: canvas.Canvas, info: dict, top: float, theme: dict):
    #header - left - red - line below
    c.setFont("Helvetica-Bold", 12)

    setColor(c, theme['accent'])
    top -= MARGIN / 4
    c.drawString(MARGIN, top, "Projects")
    top -= inch / 12
    c.line(MARGIN, top, WIDTH - MARGIN, top)

    #each project
    top -= inch / 6
    for project in info["Projects"]:
        #title
        setColor(c, theme['front'])
        c.setFont("Helvetica-Bold", 10)
        c.drawString(MARGIN + inch / 4, top, project["name"])

        #link
        c.setFont("Helvetica-Oblique", 9)
        setColor(c, theme['accent'])
        c.drawRightString(WIDTH - MARGIN, top, project["link"])
        x1 = WIDTH - MARGIN - c.stringWidth(project["link"])
        x2 = WIDTH - MARGIN
        c.linkURL("https://" + project["link"], (x1, top, x2, top + 9))

        #description
        c.setFont("Helvetica", 9)
        setColor(c, theme['front'])
        for line in project["description"]:
            top -= inch / 6
            c.drawString(MARGIN + inch / 3, top, "• " + line)
        top -= inch / 6
    return top + inch / 20
Beispiel #3
0
 def test_06_fontsize(self):
     from reportlab.lib.pagesizes import A4
     from reportlab.pdfgen.canvas import Canvas
     from reportlab.lib.units import inch
     from reportlab.lib.colors import red, magenta
     c = Canvas('demo.pdf', pagesize=A4)
     c.translate(inch, inch)
     c.setFont("Times-Roman", 20)
     c.setFillColor(red)
     c.saveState()
     c.drawCentredString(2.75*inch, 2.5*inch,"Font size excmples")
     c.setFillColor(magenta)
     size = 7
     x = 2.3 * inch
     y = 1.3 * inch
     for line in range(7):
         c.setFont("Helvetica", size)
         c.drawRightString(x, y, "%s points" % size)
         c.drawString(x,y, "test")
         y = y-size*1.2
         size = size+1.5
     c.restoreState()
     c.drawString(0,0, "%s" % c.getAvailableFonts())
     c.showPage()
     c.save()
Beispiel #4
0
def education(c: canvas.Canvas, info: dict, top: float, theme: dict):
    #header - left - red - line below
    c.setFont("Helvetica-Bold", 12)
    setColor(c, theme['accent'])
    top -= MARGIN / 4
    c.drawString(MARGIN, top, "Education")
    top -= inch / 12
    c.line(MARGIN, top, WIDTH - MARGIN, top)

    #university name - bold, black
    top -= inch / 6
    setColor(c, theme['front'])
    c.setFont("Helvetica-Bold", 10)
    c.drawString(MARGIN + inch / 4, top, info["Education"]["school"])

    #expected grad - bold
    c.drawRightString(
        WIDTH - MARGIN, top,
        "Expected Graduation: " + info["Education"]["graduation"])

    #major, gpa - small
    c.setFont("Helvetica", 9)
    top -= inch / 6
    c.drawString(
        MARGIN + inch / 3, top,
        info["Education"]["degree"] + " | " + info["Education"]["gpa"])

    return top - inch / 12
def add_footer():
    input_file = "/tmp/merged.pdf"
    output_file = "/tmp/merged_footer.pdf"

    # Get pages
    reader = PdfReader(input_file)
    pages = [pagexobj(p) for p in reader.pages]

    # Compose new pdf
    canvas = Canvas(output_file)

    for page_num, page in enumerate(pages, start=1):

        # # Add page
        canvas.setPageSize((page.BBox[2], page.BBox[3]))
        canvas.doForm(makerl(canvas, page))

        canvas.setFont("Helvetica", 10)

        if canvas._pagesize[0] > canvas._pagesize[1]:
            canvas.saveState()
            canvas.rotate(270)
            canvas.translate(-30, -A4[0] + 30)
            canvas.drawRightString(
                -10, A4[0], "%d de %d" % (canvas._pageNumber, len(pages)))
            canvas.restoreState()
        else:
            canvas.drawRightString(
                A4[0] - 60, 30, "%d de %d" % (canvas._pageNumber, len(pages)))

        canvas.showPage()

    canvas.save()
 def generateOfficePDF(self,response):
     #Attach name.pdf file to responses content disposition
     response['Content-Disposition'] = 'attachment; filename=office.pdf'
     
     #Create empty pdf document, hook pdf with response
     pdf = Canvas(response) 
     
     #Get Todays Events
     brains = sorted(util.gatherTodaysEvents(self), key=attrgetter('location')) #so awesome, sorts on any attribute!
     brains = sorted(brains, key=attrgetter('start')) #even better a secondary sort.
     
     #Header: Title Information and Settings
     pdf.setFont("Helvetica-Bold", 12)
     pdf.setStrokeColorRGB(0, 0, 0) #sets Line/Rectangle Colors
     
     #Header Left Title
     if brains != None and len(brains) > 0:
         pdf.drawString(15, 810, DateTime(brains[0].start).strftime("%A, %B %d, %Y") + " Schedule")
     else:
         pdf.drawString(15, 810, "No Groups scheduled for " + datetime.datetime.now().strftime("%A, %B %d, %Y"))
         
     #Header Right Title
     pdf.drawRightString(575, 810, "GroupFinder")
     
     #Body: List of Groups and Settings
     index = 792 #Pixel Index, starting at the top of the pdf page
     page = 1 #Page Number
     
     for brain in brains:
         pdf.setFont("Helvetica", 12)
         pdf.setStrokeColorRGB(0, 0, 0) #sets Line/Rectangle Colors
         pdf.rect(10, index-20, 575, 30, stroke=1, fill=0) #Rectangle around each Group
         pdf.drawString(15, index-3, brain.Title) #Group Description
         
         l = self.locationLookup(brain.location)
         pdf.drawString(15, index-15, DateTime(brain.start).strftime("%I:%M %p") + 
                                      " - " + DateTime(brain.end).strftime("%I:%M %p") +
                                      " in " + l['Name']) 
         index -= 30 #Move Pixel Index downwards
         
         #Reach Bottom of page?  Creates New Page.
         if index < 30:
             pdf.drawString(15, 5, "Page " + str(page))#add page number pages
             pdf.drawCentredString(300, 5, "Created on " + datetime.datetime.now().strftime("%m/%d/%Y at %I:%M %p"))
             page+=1
             index = 792
             pdf.showPage() #next page
     
     #add page number pages
     pdf.drawString(15, 5, "Page " + str(page))
     
     #add date PDF was created
     pdf.drawCentredString(300, 5, "Created on " + datetime.datetime.now().strftime("%m/%d/%Y at %I:%M %p"))
                     
     pdf.showPage() #next page, finalize last page.
     
     pdf.save() #save the pdf content
     return response #return response with hooked pdf.
Beispiel #7
0
    def _on_other_page(self, canvas: Canvas, doc):
        canvas.saveState()
        canvas.setFont('OpenSans', 8)
        canvas.drawRightString(self.pagesize[0] - 20 * mm, 10 * mm, pgettext("invoice", "Page %d") % (doc.page,))

        for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]):
            canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, line.strip())

        canvas.restoreState()
Beispiel #8
0
    def _on_other_page(self, canvas: Canvas, doc):
        canvas.saveState()
        canvas.setFont('OpenSans', 8)
        canvas.drawRightString(self.pagesize[0] - 20 * mm, 10 * mm, pgettext("invoice", "Page %d") % (doc.page,))

        for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]):
            canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, line.strip())

        canvas.restoreState()
Beispiel #9
0
def pdf_demo_9(file):
    c = Canvas(file, pagesize=A4)
    x, y = 50 * mm, 280 * mm
    for font in c.getAvailableFonts():
        c.setFont("Courier", 10)
        c.drawRightString(x - 5, y, font)
        c.setFont(font, 12)
        c.drawString(x + 5, y, "Quick brown fox jumped over the lazy dog")
        y -= 15  # Drop 15 point for each line
    c.setFont("Times-Italic", 10)
    c.drawCentredString(105 * mm, 10 * mm, "Page 1")
    c.save()
Beispiel #10
0
def header(c: canvas.Canvas,
           info: dict,
           theme: dict,
           top=HEIGHT - MARGIN) -> float:
    #smaller font, italic, red
    c.setFont("Helvetica-Oblique", 10)
    setColor(c, theme['accent'])

    #linkedin - left
    c.drawString(MARGIN, top, info["Info"]["linkedin"])
    c.linkURL("https://" + info["Info"]["linkedin"],
              (MARGIN, top, MARGIN + c.stringWidth(info["Info"]["linkedin"]),
               top + 10))

    #github - right
    c.drawRightString(WIDTH - MARGIN, HEIGHT - MARGIN, info["Info"]["github"])
    c.linkURL("https://" + info["Info"]["github"],
              (WIDTH - MARGIN - c.stringWidth(info["Info"]["github"]) - 3, top,
               WIDTH - MARGIN, top + 10))

    #name
    setColor(c, theme['front'])
    top -= inch / 3
    c.setFont("Helvetica-Bold", 20)
    c.drawRightString(WIDTH / 2 - 2, top, info["Info"]["name"][0])  #first
    setColor(c, theme['accent'])
    c.drawString(WIDTH / 2 + 2, top, info["Info"]["name"][1])  #last

    x1 = WIDTH / 2 - c.stringWidth(info["Info"]["name"][0])
    x2 = WIDTH / 2 + c.stringWidth(info["Info"]["name"][1])
    c.linkURL("https://" + info["Info"]["site"], (x1, top, x2, top + 20))

    #contact info - center below name
    top -= 20  #size of name
    setColor(c, theme['front'])
    c.setFont("Helvetica", 10)
    contact = info["Info"]["email"] + " | " + info["Info"][
        "phone-number"] + " | " + info["Info"]["site"]
    c.drawCentredString(WIDTH / 2, top, contact)

    #link site
    x2 = (WIDTH + c.stringWidth(contact)) / 2
    x1 = x2 - c.stringWidth(info["Info"]["site"])
    c.linkURL("https://" + info["Info"]["site"], (x1, top, x2, top + 10))

    #link email
    x1 = (WIDTH - c.stringWidth(contact)) / 2
    x2 = x1 + c.stringWidth(info["Info"]["email"])
    c.linkURL("mailto:" + info["Info"]["email"], (x1, top, x2, top + 10))

    #canvas.drawRightString(x, y, theme['front']), drawString(x, y, theme['front'])
    return top - inch / 20
Beispiel #11
0
def certifications(c: canvas.Canvas, info: dict, top: float, theme: dict):
    #header - left - red - line below
    c.setFont("Helvetica-Bold", 12)
    setColor(c, theme['accent'])
    top -= MARGIN / 4
    c.drawString(MARGIN, top, "Certifications")
    top -= inch / 12
    c.line(MARGIN, top, WIDTH - MARGIN, top)

    setColor(c, theme['front'])
    for cert in info["Certifications"]:
        #certifier - bold, black
        top -= inch / 6
        c.setFont("Helvetica-Bold", 10)
        c.drawString(MARGIN + inch / 4, top, cert["certifier"])

        #list of certs - small
        c.setFont("Helvetica", 9)
        certs = ', '.join(cert["certifications"])
        c.drawRightString(WIDTH - MARGIN, top, certs)

    return top - inch / 12
Beispiel #12
0
def experience(c: canvas.Canvas, info: dict, top: float, theme: dict):
    #header - left - red - line below
    c.setFont("Helvetica-Bold", 12)
    setColor(c, theme['accent'])
    top -= MARGIN / 4
    c.drawString(MARGIN, top, "Experience")
    top -= inch / 12
    c.line(MARGIN, top, WIDTH - MARGIN, top)

    #each xp
    top -= inch / 6
    for xp in info["Experience"]:
        #position
        setColor(c, theme['front'])
        c.setFont("Helvetica-Bold", 10)
        c.drawString(MARGIN + inch / 4, top, xp["position"] + " ")

        #dates
        c.drawRightString(WIDTH - MARGIN, top, xp["start"] + "-" + xp["end"])

        #company
        top -= inch / 6
        c.setFont("Helvetica", 10)
        c.drawString(MARGIN + inch / 4, top, xp["company"])

        #location
        c.setFont("Helvetica-Oblique", 9)
        c.drawRightString(WIDTH - MARGIN, top, xp["location"])

        #description
        setColor(c, theme['front'])
        c.setFont("Helvetica", 9)
        for line in xp["description"]:
            top -= inch / 6
            c.drawString(MARGIN + inch / 3, top, "• " + line)
        top -= inch / 6

    return top + inch / 20  #pull back up a little
Beispiel #13
0
def pdfout(parse, outfl, enableComments, font, page):
    if page.name == "A4":
        c = Canvas(outfl, pagesize=A4)
        width, height = A4
    else:
        c = Canvas(outfl, pagesize=letter)
        width, height = letter

    c.setFont('CourierPrime', 12)

    pgs = splitScriptText(parse, page, font, enableComments)

    if len(parse.titlePage) > 0:
        pdfTitlePage(c, parse, page, font)
        c.showPage()

    title = "UNTITLED"
    if "title" in parse.titlePage:
        title = " ".join(parse.titlePage["title"]).upper()

    for pgno in range(0, len(pgs)):
        c.setFont('CourierPrime', 12)
        if pgno > 0:
            c.drawRightString((page.width - page.marginRight) * inch, height - 0.5*inch, str(pgno+1)+".")
            c.drawString(page.marginLeft*inch, height - 0.5*inch, title)

        lineno = 0
        for e in pgs[pgno]:
            processPDFLine(c, e[0], e[1], lineno, page, font, width, height)
            lineno = lineno + 1

        c.showPage()



    c.save()
Beispiel #14
0
def skills(c: canvas.Canvas, info: dict, top: float, theme: dict) -> float:
    #header - left - red - line below
    c.setFont("Helvetica-Bold", 12)
    setColor(c, theme['accent'])

    top -= MARGIN / 4
    c.drawString(MARGIN, top, "Skills")
    top -= inch / 12
    c.line(MARGIN, top, WIDTH - MARGIN, top)

    #software development - black - bold
    top -= inch / 6
    setColor(c, theme['front'])
    c.setFont("Helvetica-Bold", 11)
    c.drawString(MARGIN + inch / 4, top, "Software Development")

    #proficient
    top -= inch / 6
    c.setFont("Helvetica", 9)
    c.drawString(MARGIN + inch / 2, top, "Proficient: ")
    skills = ", ".join(info["Skills"]["Software Development"]["Proficient"])
    c.drawRightString(WIDTH - MARGIN, top, skills)

    #familiar
    top -= inch / 6
    c.drawString(MARGIN + inch / 2, top, "Familiar: ")
    skills = ", ".join(info["Skills"]["Software Development"]["Familiar"])
    c.drawRightString(WIDTH - MARGIN, top, skills)

    #other - black - bold
    top -= inch / 6
    c.setFont("Helvetica-Bold", 11)
    c.drawString(MARGIN + inch / 4, top, "Other")

    #other skills list - small
    c.setFont("Helvetica", 9)
    skills = ", ".join(info["Skills"]["Other"])
    c.drawRightString(WIDTH - MARGIN, top, skills)

    return top - inch / 20  #the new bottom
Beispiel #15
0
def print_direction(c: Canvas, n, dir: Napravleniya, format_a6: bool = False):
    xn, yn = 0, 0
    if not format_a6:
        if n % 2 != 0:
            xn = 1
        if n > 2:
            yn = 1

    barcode = eanbc.Ean13BarcodeWidget(dir.pk + 460000000000,
                                       humanReadable=0,
                                       barHeight=17)
    bounds = barcode.getBounds()
    width = bounds[2] - bounds[0]
    height = bounds[3] - bounds[1]
    d = Drawing(width, height)
    d.add(barcode)
    paddingx = 15
    ac = dir.is_all_confirm()
    canc = dir.cancel
    visit = dir.visit_date is not None
    if ac or canc or visit:
        c.saveState()
        c.setFillColorRGB(0, 0, 0, 0.2)
        c.rotate(45)
        if xn == 0 and yn == 1:
            ox = w / 2 + 40 * mm
            oy = h / 2 - 30 * mm
        elif xn == 0 and yn == 0:
            ox = w / 2 - 65 * mm
            oy = 13.5 * mm
        elif xn == 1 and yn == 0:
            ox = w - 95.75 * mm
            oy = 13.5 * mm - h / 4
        else:
            ox = w + 9.25 * mm
            oy = h / 2 - 30 * mm - h / 4
        c.setFont('OpenSansBold', 50)
        s = 'ОТМЕНЕНО'
        if ac:
            s = 'ИСПОЛНЕНО'
        elif visit:
            s = 'ПОСЕЩЕНО'
        c.drawString(ox, oy, s)
        c.restoreState()

    c.setFont('OpenSans', 10)
    c.drawCentredString(w / 2 - w / 4 + (w / 2 * xn),
                        (h / 2 - height - 5) + (h / 2) * yn,
                        dir.hospital_short_title)

    c.setFont('OpenSans', 8)
    c.drawCentredString(
        w / 2 - w / 4 + (w / 2 * xn), (h / 2 - height - 15) + (h / 2) * yn,
        "(%s. %s)" % (dir.hospital_address, dir.hospital_phones))

    c.setFont('OpenSans', 14)
    c.drawCentredString(
        w / 2 - w / 4 + (w / 2 * xn), (h / 2 - height - 30) + (h / 2) * yn,
        "Направление" + ("" if not dir.imported_from_rmis else " из РМИС"))

    renderPDF.draw(d, c, w / 2 - width + (w / 2 * xn) - paddingx / 3 - 5 * mm,
                   (h / 2 - height - 57) + (h / 2) * yn)

    c.setFont('OpenSans', 20)
    c.drawString(paddingx + (w / 2 * xn), (h / 2 - height) + (h / 2) * yn - 57,
                 "№ " + str(dir.pk))  # Номер направления

    c.setFont('OpenSans', 9)
    c.drawString(
        paddingx + (w / 2 * xn), (h / 2 - height - 70) + (h / 2) * yn,
        "Создано: " + strdate(dir.data_sozdaniya) + " " +
        strtime(dir.data_sozdaniya)[:5])
    history_num = dir.history_num
    additional_num = dir.additional_num
    if history_num and len(history_num) > 0:
        c.drawRightString(w / 2 * (xn + 1) - paddingx,
                          (h / 2 - height - 70) + (h / 2) * yn,
                          "№ истории: " + history_num)
    elif additional_num and len(additional_num) > 0:
        c.drawRightString(w / 2 * (xn + 1) - paddingx,
                          (h / 2 - height - 70) + (h / 2) * yn,
                          f"({str(additional_num).strip()})")
    elif dir.client.number_poliklinika and len(
            dir.client.number_poliklinika) > 0:
        c.drawRightString(w / 2 * (xn + 1) - paddingx,
                          (h / 2 - height - 70) + (h / 2) * yn,
                          f"({str(dir.client.number_poliklinika).strip()})")

    if dir.history_num and len(dir.history_num) > 0:
        c.drawRightString(w / 2 * (xn + 1) - paddingx,
                          (h / 2 - height - 70) + (h / 2) * yn,
                          "№ истории: " + dir.history_num)

    c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 80) + (h / 2) * yn,
                 "ФИО: " + dir.client.individual.fio())

    c.drawRightString(w / 2 * (xn + 1) - paddingx,
                      (h / 2 - height - 80) + (h / 2) * yn,
                      "Пол: " + dir.client.individual.sex)

    c.drawRightString(
        w / 2 * (xn + 1) - paddingx, (h / 2 - height - 90) + (h / 2) * yn,
        "Д/р: {} ({})".format(dir.client.individual.bd(),
                              dir.client.individual.age_s(direction=dir)))

    c.drawString(
        paddingx + (w / 2 * xn), (h / 2 - height - 90) + (h / 2) * yn,
        "{}: {}".format("ID" if dir.client.base.is_rmis else "Номер карты",
                        dir.client.number_with_type()))
    diagnosis = dir.diagnos.strip()[:35]
    if not dir.imported_from_rmis:
        if diagnosis != "":
            c.drawString(
                paddingx + (w / 2 * xn),
                (h / 2 - height - 100) + (h / 2) * yn,
                ("" if dir.vich_code == "" else
                 ("Код: " + dir.vich_code + "  ")) + "Диагноз (МКБ 10): " +
                ("не указан" if diagnosis == "-" else diagnosis),
            )
        elif dir.vich_code != "":
            c.drawString(paddingx + (w / 2 * xn),
                         (h / 2 - height - 100) + (h / 2) * yn,
                         "Код: " + dir.vich_code)
        if dir.istochnik_f:
            c.drawString(
                paddingx + (w / 2 * xn), (h / 2 - height - 110) + (h / 2) * yn,
                "Источник финансирования: " + dir.client.base.title + " - " +
                dir.istochnik_f.title)
        else:
            c.drawString(paddingx + (w / 2 * xn),
                         (h / 2 - height - 110) + (h / 2) * yn,
                         "Источник финансирования: ")
    else:
        nds = 0
        if diagnosis != "":
            c.drawString(paddingx + (w / 2 * xn),
                         (h / 2 - height - 100) + (h / 2) * yn,
                         "Диагноз (МКБ 10): " + diagnosis)
            nds = 5
        if dir.imported_org:
            c.drawString(paddingx + (w / 2 * xn),
                         (h / 2 - height - 105 - nds) + (h / 2) * yn,
                         "Организация: " + dir.imported_org.title)

    issledovaniya = dir.issledovaniya_set.all()

    vid = []
    has_descriptive = False
    has_doc_refferal = False
    need_qr_code = False
    for i in issledovaniya:
        rtp = i.research.reversed_type
        if rtp < -1:
            has_doc_refferal = True
            rt = {
                -2: 'Консультации',
                -3: 'Лечение',
                -4: 'Стоматология',
                -5: 'Стационар',
                -6: 'Микробиология',
                -9998: 'Морфология',
                -9: 'Формы',
                -11: 'Заявления',
                -12: 'Мониторинги',
            }[rtp]
            # if rtp == -6:
            #     has_micro = True
        else:
            rt = i.research.podrazdeleniye.get_title()
        if rt not in vid:
            vid.append(rt)
            if i.research.podrazdeleniye and i.research.podrazdeleniye.p_type == Podrazdeleniya.PARACLINIC:
                has_descriptive = True
                if i.research.podrazdeleniye.can_has_pacs:
                    need_qr_code = True

    c.drawString(paddingx + (w / 2 * xn),
                 (h / 2 - height - 120) + (h / 2) * yn,
                 "Вид: " + ", ".join(vid))

    if dir.purpose:
        c.drawRightString(w / 2 * (xn + 1) - paddingx,
                          (h / 2 - height - 120) + (h / 2) * yn,
                          "Цель: " + dir.get_purpose_display())

    if dir.external_organization:
        c.drawRightString(w / 2 * (xn + 1) - paddingx,
                          (h / 2 - height - 134) + (h / 2) * yn,
                          dir.external_organization.title)

    if dir.parent and dir.parent.research.is_hospital:
        c.setFont('OpenSansBold', 8)
        c.drawRightString(w / 2 * (xn + 1) - paddingx,
                          (h / 2 - height - 129) + (h / 2) * yn,
                          ("Стационар-" + str(dir.parent.napravleniye_id)))
    c.setFont('OpenSans', 9)

    styleSheet = getSampleStyleSheet()

    all_iss = issledovaniya.count()
    max_f = 9
    min_f = 7
    max_res = 36

    max_off = max_f - min_f
    font_size = max_f - (max_off * (all_iss / max_res))

    styleSheet["BodyText"].leading = font_size + 0.5
    data = []

    values = []

    service_locations = {}

    n = 0
    for v in issledovaniya:
        n += 1
        service_location_title = "" if not v.service_location else v.service_location.title
        if service_location_title:
            if service_location_title not in service_locations:
                service_locations[service_location_title] = []
            service_locations[service_location_title].append(n)
        values.append({
            "title":
            v.research.get_title(),
            "full_title":
            v.research.title,
            "sw":
            v.research.sort_weight,
            "count":
            v.how_many,
            "comment":
            v.localization.title if v.localization else v.comment,
            "n":
            n,
            "g":
            -1 if not v.research.fractions_set.exists() else
            v.research.fractions_set.first().relation_id,
            "info":
            v.research.paraclinic_info,
            "hospital_department_replaced_title":
            v.hospital_department_replaced_title,
        })

    one_sl = len(service_locations) <= 1

    tw = w / 2 - paddingx * 2
    m = 0
    ns = {}
    if has_descriptive or has_doc_refferal:
        tmp = [
            Paragraph(
                '<font face="OpenSansBold" size="8">%s</font>' %
                ("Исследование" if not has_doc_refferal else "Назначение"),
                styleSheet["BodyText"]),
            Paragraph('<font face="OpenSansBold" size="8">Информация</font>',
                      styleSheet["BodyText"]),
        ]
        data.append(tmp)
        colWidths = [int(tw * 0.5), int(tw * 0.5)]
        values.sort(key=lambda l: l["full_title"])

        for v in values:
            ns[v["n"]] = v["n"]
            tmp = [
                Paragraph(
                    '<font face="OpenSans" size="8">' +
                    ("" if one_sl else "№{}: ".format(v["n"])) +
                    xh.fix(v["full_title"]) +
                    ("" if not v["comment"] else
                     " <font face=\"OpenSans\" size=\"" +
                     str(font_size * 0.8) +
                     "\">[{}]</font>".format(v["comment"])) +
                    ("" if not v["hospital_department_replaced_title"] else
                     f"<br/>Направлен в: {v['hospital_department_replaced_title']}"
                     ) + "</font>",
                    styleSheet["BodyText"],
                ),
                Paragraph(
                    '<font face="OpenSans" size="8">' + xh.fix(v["info"]) +
                    "</font>", styleSheet["BodyText"]),
            ]
            data.append(tmp)
        m = 8
    else:
        colWidths = [int(tw / 2), int(tw / 2)]
        c.drawString(paddingx + (w / 2 * xn),
                     (h / 2 - height - 134) + (h / 2) * yn, "Назначения: ")
        c.setStrokeColorRGB(0, 0, 0)
        c.setLineWidth(1)
        values.sort(key=lambda l: (l["g"], l["sw"]))

        n_rows = int(len(values) / 2)

        normvars = []
        c_cnt = nc_cnt = 0
        for i in range(0, len(values) + 1):
            if (i + 1) % 2 == 0:
                nc_cnt += 1
                if nc_cnt + n_rows < len(values):
                    normvars.append(values[nc_cnt + n_rows])
            else:
                normvars.append(values[c_cnt])
                c_cnt += 1

        p = Paginator(normvars, 2)
        n = 1
        for pg_num in p.page_range:
            pg = p.page(pg_num)
            tmp = []
            for obj in pg.object_list:
                ns[obj["n"]] = n
                tmp.append(
                    Paragraph(
                        '<font face="OpenSans" size="' + str(font_size) +
                        '">' + ("" if one_sl else "№{}: ".format(n)) +
                        obj["title"] +
                        ("" if not obj["count"] or obj["count"] == 1 else
                         " ({}шт.)".format(str(obj["count"]))) +
                        ("" if not obj["comment"] else
                         " <font face=\"OpenSans\" size=\"" +
                         str(font_size * 0.8) +
                         "\">[{}]</font>".format(obj["comment"])) + "</font>",
                        styleSheet["BodyText"],
                    ))
                n += 1
            if len(pg.object_list) < 2:
                tmp.append(
                    Paragraph(
                        '<font face="OpenSans" size="' + str(font_size) +
                        '"></font>', styleSheet["BodyText"]))
            data.append(tmp)

    t = Table(data, colWidths=colWidths)
    t.setStyle(
        TableStyle([
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('TEXTCOLOR', (0, -1), (-1, -1), colors.black),
            ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
            ('BOX', (0, 0), (-1, -1), 0.25, colors.black),
            ('LEFTPADDING', (0, 0), (-1, -1), 4),
            ('TOPPADDING', (0, 0), (-1, -1), 0.5),
            ('RIGHTPADDING', (0, 0), (-1, -1), 2),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 2),
        ]))
    t.canv = c
    wt, ht = t.wrap(0, 0)
    t.drawOn(c, paddingx + (w / 2 * xn),
             ((h / 2 - height - 138 + m) + (h / 2) * yn - ht))

    c.setFont('OpenSans', 8)
    if not has_descriptive and not has_doc_refferal:
        c.drawString(paddingx + (w / 2 * xn),
                     (h / 2 - height - 138 + m) + (h / 2) * yn - ht - 10,
                     "Всего назначено: " + str(len(issledovaniya)))

    if service_locations:
        n = 0 if has_descriptive or has_doc_refferal else 1
        if one_sl:
            c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 138 + m) +
                         (h / 2) * yn - ht - 14 - n * 10,
                         "Место: " + list(service_locations)[0])
        else:
            c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 138 + m) +
                         (h / 2) * yn - ht - 14 - n * 10,
                         "Места оказания услуг:")
            for title in service_locations:
                n += 1
                c.drawString(
                    paddingx + (w / 2 * xn),
                    (h / 2 - height - 138 + m) + (h / 2) * yn - ht - 14 -
                    n * 10,
                    title + " – услуги " + ', '.join(
                        map(lambda x: "№{}".format(ns[x]),
                            service_locations[title])),
                )

    if need_qr_code:
        qr_value = translit(dir.client.individual.fio(), 'ru', reversed=True)
        qr_code = qr.QrCodeWidget(qr_value)
        qr_code.barWidth = 70
        qr_code.barHeight = 70
        qr_code.qrVersion = 1
        d = Drawing()
        d.add(qr_code)
        renderPDF.draw(d, c, paddingx + (w / 2 * xn) + 200, 32 + (h / 2) * yn)

    nn = 0
    if not dir.imported_from_rmis:
        if dir.doc_who_create and dir.doc_who_create != dir.doc:
            nn = 9
            c.drawString(
                paddingx + (w / 2 * xn), 13 + (h / 2) * yn,
                Truncator("Выписал: %s, %s" %
                          (dir.doc_who_create.get_fio(),
                           dir.doc_who_create.podrazdeleniye.title)).chars(63))

        if dir.doc:
            c.drawString(
                paddingx + (w / 2 * xn), 22 + (h / 2) * yn + nn,
                "Отделение: " +
                Truncator(dir.get_doc_podrazdeleniye_title()).chars(50))
            c.drawString(paddingx + (w / 2 * xn), 13 + (h / 2) * yn + nn,
                         "Л/врач: " + dir.doc.get_fio())
    else:
        c.drawString(paddingx + (w / 2 * xn), 31 + (h / 2) * yn + nn,
                     "РМИС#" + dir.rmis_number)
        c.drawString(paddingx + (w / 2 * xn), 22 + (h / 2) * yn + nn,
                     "Создал направление: " + dir.doc_who_create.get_fio())
        c.drawString(paddingx + (w / 2 * xn), 13 + (h / 2) * yn + nn,
                     dir.doc_who_create.podrazdeleniye.title)

    c.setFont('OpenSans', 7)
    c.setLineWidth(0.25)
    c.translate(0, -leading)
    c.drawString(0, 0, text.next())

c.translate(0, -20*mm)
c.drawString(-100*mm, 0, "Canvas.drawCentredString")
c.translate(0, -leading)
for i in range(2):
    c.translate(0, -leading)
    c.drawCentredString(0, 0, text.next())

c.translate(0, -20*mm)
c.drawString(-100*mm, 0, "Canvas.drawRightString")
c.translate(0, -leading)
for i in range(2):
    c.translate(0, -leading)
    c.drawRightString(0, 0, text.next())

c.translate(0, -20*mm)
c.drawString(-100*mm, 0, "Canvas.beginText (Text object)")
c.translate(0, -leading*2)

# Text objects are more efficient for anything more than simple labels
textobject = c.beginText()
textobject.setTextOrigin(0, 0)
textobject.setFont("Times-Italic", 10)

# supply text one line at a time:
for i in range(6):
    textobject.textLine(text.next())
textobject.textLine()
Beispiel #17
0
can.setLineWidth(1)  # nouvelle épaisseur des lignes
can.ellipse(
    centreX - .5 * cm,
    centreY - .5 * cm,  # petit cercle indiquant la
    centreX + .5 * cm,
    centreY + .5 * cm)  # position du centre de la page

# Quelques textes, avec polices, orientation et alignement divers :
can.setFillColor("navy")  # couleur des textes
texteC = "Petite pluie abat grand vent."  # texte à centrer
can.setFont("Times-Bold", 18)
can.drawCentredString(centreX, centreY, texteC)
texteG = "Qui ne risque rien, n'a rien."  # texte à aligner à gauche
can.setFont("Helvetica", 18)
can.drawString(centreX, centreY - 1 * cm, texteG)
texteD = "La nuit porte conseil."  # texte à aligner à droite
can.setFont("Courier", 18)
can.drawRightString(centreX, centreY - 2 * cm, texteD)
texteV = "L'espoir fait  vivre."  # texte à disposer verticalement
can.rotate(90)
can.setFont("Times-Italic", 18)
can.drawString(centreY + 1 * cm, -centreX,
               texteV)  # ! inversion des coordonnées !
texteE = "L'exception confirme la règle"  # texte à afficher en blanc
can.rotate(-90)  # retour à l'orientation horiz.
can.setFont("Times-BoldItalic", 28)
can.setFillColor("white")  # nouvelle couleur des textes
can.drawCentredString(centreX, 7 * cm, texteE)

can.save()  # Sauvegarde du résultat
Beispiel #18
0
class InvoiceDocument:
    """This class represents a pdf invoice.
    All units are in mm
    pdffilePath is the output pdf file
    invoiceData = [invoiceHeader, lesson1List, ..., lessonNList]
    invoiceHeader = [invoice_date, invoice_to, invoice_for, invoice_ref, n, amount]
    lesson1List = [date, tuition_ref, hours, rate, amount, reason1, money1, ...,
                    reasonN, moneyN, "discount", money]
    """
    def __init__(self, pdffilePath, invoiceData):
        self.pageHeight = A4[1] / mm  # in mm, all units in mm
        self.pageWidth = A4[0] / mm
        self.lMargin = 20.0
        self.rMargin = 20.0
        self.tMargin = 30.0
        self.bMargin = 30.0
        #print("page size of A4 in mm: ", self.pageWidth, self.pageHeight)

        self.canvas = Canvas(pdffilePath, pagesize=A4)
        self.canvas.setTitle("Invoice for Maths tuition")
        self.title = "Invoice for Maths tuition"

        self.fontPathBase = "./fonts/%s.ttf"
        #print("Font: ", self.fontPathBase % "DejaVuSerif")
        pdfmetrics.registerFont(
            TTFont('DejaVu', self.fontPathBase % "DejaVuSerif"))
        pdfmetrics.registerFont(
            TTFont('DejaVu-Bold', self.fontPathBase % "DejaVuSerif-Bold"))
        pdfmetrics.registerFont(
            TTFont('DejaVu-Italics', self.fontPathBase % "DejaVuSerif-Italic"))

        self.tutorData = [
            "Hannes Buchholzer", "3 April Close, Horsham, RH12 2LL",
            "07516-100218", "*****@*****.**"
        ]
        self.invoiceHeader = invoiceData.pop(0)
        self.invoiceData = invoiceData

    # translate coordinates x,y in mm from top left
    # into pixels from bottom right
    def coord(self, x, y, fromRight=False, fromBottom=False):
        cx = (self.pageWidth - x) * mm if fromRight else x * mm
        cy = y * mm if fromBottom else (self.pageHeight - y) * mm
        return (cx, cy)

    # translate a mm value into pixels. Works also for a list of mm values
    def trans(self, x):
        if isinstance(x, list):
            cx = list(range(len(x)))
            for i in range(len(x)):
                cx[i] = float(x[i]) * mm
        else:
            cx = float(x) * mm

        return cx

    # convert Money to String
    # x should be a money amount as integer and float
    # the output is a string with £ sign
    def cM2S(self, x):
        x = float(x)
        if x < 0.0:
            pre = "-"
            x = -x
        else:
            pre = ""

        s = pre + "£{0:4.2f}".format(x)
        #print("convertMoney2String: ", x, " ", s)
        return s

    # convert date to String
    # x should be a list of 3 integers
    # day, month, year
    def cD2S(self, x):
        if x[2] < 100: x[2] += 2000
        s = "{0:>02n}/{1:>02n}/{2:4n}".format(*x)
        #print("convertDate2String: ", x, " ", s)
        return s

    # draw it centered y mm from top
    def draw_heading(self, y):
        # canvas.saveState()
        self.canvas.setFont('DejaVu', 20)
        (cx, cy) = self.coord(self.pageWidth / 2.0, y)
        self.canvas.drawCentredString(cx, cy, self.title)
        # canvas.restoreState()

    # draw the tutor's details; here x, y is the bottom left
    # corner of the first line in mm
    def draw_tutor(self, x, y):
        # canvas.saveState()
        cx, cy = self.coord(x, y)
        self.canvas.setFont('DejaVu-Bold', 13)
        self.canvas.drawString(cx, cy, self.tutorData[0])
        self.canvas.setFont('DejaVu', 10)
        cy -= 15
        self.canvas.drawString(cx, cy, "address:")
        self.canvas.drawString(cx + 19 * mm, cy, self.tutorData[1])
        cy -= 13
        self.canvas.drawString(cx, cy, "phone:")
        self.canvas.drawString(cx + 19 * mm, cy, self.tutorData[2])
        cy -= 13
        self.canvas.drawString(cx, cy, "email:")
        self.canvas.drawString(cx + 19 * mm, cy, self.tutorData[3])
        # canvas.restoreState()

    # draw the date; again x, y  are in mm
    # y is the distance from the top
    # x is the distance from the right
    def draw_invoice_date(self, x, y):
        # canvas.saveState()
        cx, cy = self.coord(x, y, fromRight=True)
        self.canvas.setFont('DejaVu-Bold', 10)
        self.canvas.drawRightString(cx, cy, "invoice date:")
        self.canvas.setFont('DejaVu', 10)
        cy -= 12  # go 12 pixels lower
        self.canvas.drawRightString(cx, cy, self.invoiceHeader[0])
        # canvas.restoreState()

    # draw the date; y  is in mm
    # y is the distance from the top
    def draw_invoice_data(self, y):
        middlex = 80
        # canvas.saveState()
        cx, cy = self.coord(self.lMargin, y)
        self.canvas.setFont('DejaVu-Bold', 11)
        self.canvas.drawString(cx, cy, "invoice to:")
        cx, cy = self.coord(middlex, y)
        self.canvas.drawString(cx, cy, "invoice for:")
        cx, cy = self.coord(self.pageWidth - 20, y)
        self.canvas.drawRightString(cx, cy, "invoice reference nr:")

        self.canvas.setFont('DejaVu', 10)
        cy -= 12  # go 12 pixels lower
        cx = self.lMargin * mm
        self.canvas.drawString(cx, cy, self.invoiceHeader[1])
        cx = middlex * mm
        self.canvas.drawString(cx, cy, self.invoiceHeader[2])
        cx = (self.pageWidth - 20) * mm
        self.canvas.drawRightString(cx, cy, self.invoiceHeader[3])
        # canvas.restoreState()

    # draw table
    # y is the distance in mm from top
    def draw_table(self, y):
        vspace = 4
        y += 8
        self.headStyle = TableStyle([('FONT', (0, 0), (-1, 0),
                                      'DejaVu-Bold', 10),
                                     ('GRID', (0, 0), (-1, 0), 2, black)])
        self.bodyStyle = TableStyle([('FONT', (0, 0), (-1, -1), 'DejaVu', 10),
                                     ('BOX', (0, 0), (-1, -1), 2, black),
                                     ('LINEBEFORE', (1, 0), (1, -1), 2, black),
                                     ('LINEBEFORE', (2, 0), (2, -1), 2, black),
                                     ('LINEBEFORE', (3, 0), (3, -1), 2, black),
                                     ('LINEBEFORE', (4, 0), (4, -1), 2, black),
                                     ('LINEBEFORE', (5, 0), (5, -1), 2, black),
                                     ('ALIGN', (3, 0), (5, -1), 'RIGHT')])
        self.footStyle = TableStyle([
            ('FONT', (0, 0), (-1, 0), 'DejaVu-Bold', 10),
            ('BOX', (0, 0), (-1, -1), 2, black),
            ('ALIGN', (0, 0), (0, 0), 'CENTER'),
            ('ALIGN', (1, 0), (1, 0), 'RIGHT'),
            ('LINEBEFORE', (1, 0), (1, -1), 2, black)
        ])

        dataBody = []
        num = 0
        for lesson in self.invoiceData:
            #print("Line: ", lesson)
            num += 1
            line = lesson[0:2]
            line.append("teaching")
            line.append("{0:3.2f}".format(lesson[2]))
            line.append(self.cM2S(lesson[3]))
            line.append(self.cM2S(lesson[4]))
            dataBody.append(line)

            lRest = lesson[5:]
            while lRest:
                num += 1
                extra_reason = lRest.pop(0)
                extra_cost = self.cM2S(lRest.pop(0))
                line2 = [None, None, extra_reason, None, None, extra_cost]
                dataBody.append(line2)

            self.bodyStyle.add('LINEABOVE', (0, num), (-1, num), 2, black)

        dataHead = [[
            "date", "tuition reference", "description", "hours", "rate",
            "amount"
        ]]
        dataFoot = [["total", self.cM2S(self.invoiceHeader[-1])]]

        colWiMMB = [25, 48, 42, 16, 18, 20]
        colWiMMF = [sum(colWiMMB[0:-1]), colWiMMB[-1]]
        colWidthB = self.trans(colWiMMB)
        colWidthF = self.trans(colWiMMF)
        #print(colWiMMB, colWiMMF)

        self.tableHead = Table(dataHead,
                               colWidths=colWidthB,
                               style=self.headStyle)
        self.tableBody = Table(dataBody,
                               colWidths=colWidthB,
                               style=self.bodyStyle,
                               repeatRows=0)
        self.tableFoot = Table(dataFoot,
                               colWidths=colWidthF,
                               style=self.footStyle)

        sw, sh = self.tableHead.wrapOn(self.canvas, *self.trans([180, 10]))
        tw, th = self.tableBody.wrapOn(self.canvas, *self.trans([180, 120]))
        uw, uh = self.tableFoot.wrapOn(self.canvas, *self.trans([180, 10]))

        xx, yy = self.coord(self.lMargin, y)
        ay = yy - sh
        by = ay - th - vspace
        cy = by - uh - vspace
        theight = (sh + th + uh + 2 * vspace) / mm
        self.tableHead.drawOn(self.canvas, xx, ay)
        self.tableBody.drawOn(self.canvas, xx, by)
        self.tableFoot.drawOn(self.canvas, xx, cy)

        return theight

    # draw the date; y  is in mm
    # y is the distance from the top
    def draw_invoice_foot(self, y):
        # canvas.saveState()
        cx, cy = self.coord(self.pageWidth / 2.0, y + 6)
        self.canvas.setFont('DejaVu', 10)
        # theight is becoming the total height of
        # the footer
        theight = 10

        self.canvas.drawCentredString(
            cx, cy,
            "Please pay by bank transfer to following account within 7 calendar days of invoice date:"
        )
        cy -= 13
        theight += 13
        self.canvas.drawCentredString(
            cx, cy,
            "Account Title: Hannes Buchholzer, Sort Code: 20-42-58, Account Number: 23821595."
        )
        cy -= 13
        theight += 13
        self.canvas.setFont('DejaVu-Italics', 10)
        self.canvas.drawCentredString(
            cx, cy,
            "Please set the reference as the invoice reference number :")
        cy -= 20
        theight += 20
        self.canvas.setFont('DejaVu', 12)
        cx = self.trans(self.pageWidth / 2.0)
        self.canvas.drawCentredString(cx, cy, self.invoiceHeader[3])
        cy -= 20
        theight += 20
        self.canvas.setFont('DejaVu', 10)
        self.canvas.drawCentredString(
            cx, cy, "Thank you for choosing me as your Tutor!")
        theight = theight / mm  # convert into mm
        return theight

    def compileInvoice(self):
        self.draw_heading(30)
        self.draw_tutor(20, 50)
        self.draw_invoice_date(20, 50)
        self.draw_invoice_data(90)
        height1 = self.draw_table(110)

        yfoot = 120 + height1 + 20
        if yfoot <= 250.0:
            height2 = self.draw_invoice_foot(yfoot)
        else:
            self.canvas.showPage()
            height2 = self.draw_invoice_foot(35)
        self.canvas.save()
Beispiel #19
0
class pdf:
    def __init__(self, path: str, name: str = 'generated'):
        """
        Create a pdf-file object\n
        :param path: path to create file
        :param name: name of file
        """
        self.file = Canvas(self._get_path(path, name))
        self.set_font(12)
        self.page = 1

    def _get_path(self, path: str, name: str = 'generated') -> str:
        """
        This function cleans path\n
        :param path: path to create file
        :param name: name of file
        :return: clean path to file
        """
        path = ''.join(symbol for symbol in path.lower()
                       if symbol not in ' <>?"\*')
        while path.count(':') > 1:
            path = path[:path.rfind(':')] + path[path.rfind(':') + 1:]
        while path[len(path) - 1] == ' ':
            path = path[:len(path) - 1]
        if ".pdf" in path:
            path = path[0:path.rfind('/') + 1:1]
        if path[len(path) - 1] != '/':
            path += '/'
        if '.pdf' in name:
            name = name[:name.rfind('.')]
        return path + name + '.pdf'

    def _format_data(self, data: dict) -> list:
        """
        This function processing data and return list of data for create table\n
        :param data: dict of data
        :return: list of data
        """
        new_data = [[data['title']]]
        add_list = []
        value_list = []
        for column_elem in data['columns']:
            add_list.append(column_elem['name'])
            value_list.append(column_elem['value'])
        new_data.append(add_list.copy())
        add_list.clear()
        for row_elem in data['rows']:
            for value in value_list:
                add_list.append(row_elem[value])
            new_data.append(add_list.copy())
            add_list.clear()
        return new_data

    def _normal_color(self):
        self.file.setFillColor('black')
        self.file.setStrokeColor('black')

    def set_font(self, font_size: int):
        """
        This function set up font and his size in file\n
        :param font_size: size of font
        """
        self.font_size = font_size
        using_font = ttfonts.TTFont("Calibri", "Calibri.ttf")
        pdfmetrics.registerFont(using_font)
        self.file.setFont("Calibri", self.font_size)

    def write_text(self,
                   text: str,
                   position: str = "mid",
                   x: int = 297,
                   y: int = 815):
        """"
        This function write text on defined position\n
        size of page is 595,841\n
        :param text: string of text to writing
        :param position: left/mid/right position of string of text
        :param x, y: coordinates of string
        """
        self._normal_color()
        if position == "left":
            self.file.drawString(x, y, text)
        elif position == "mid":
            self.file.drawCentredString(x, y, text)
        elif position == "right":
            self.file.drawRightString(x, y, text)

    def random_drawing(self, fg_count: int):
        """
        This function draws random picture\n
        :param fg_count: count of figures, drawn on page
        """
        for figure in range(fg_count):
            methods = [
                self.file.bezier(randint(150, 495), randint(150, 741),
                                 randint(150, 495), randint(150, 741),
                                 randint(150, 495), randint(150, 741),
                                 randint(150, 495), randint(150, 741)),
                self.file.arc(randint(100, 495), randint(100, 741),
                              randint(100, 495), randint(100, 741)),
                self.file.rect(randint(100, 395),
                               randint(100, 641),
                               randint(1, 100),
                               randint(1, 100),
                               fill=randint(0, 1)),
                self.file.ellipse(randint(100, 495),
                                  randint(100, 741),
                                  randint(100, 495),
                                  randint(100, 741),
                                  fill=randint(0, 1)),
                self.file.circle(randint(100, 395),
                                 randint(100, 641),
                                 randint(1, 100),
                                 fill=randint(0, 1)),
                self.file.roundRect(randint(100, 395),
                                    randint(100, 641),
                                    randint(1, 100),
                                    randint(1, 100),
                                    randint(1, 100),
                                    fill=randint(0, 1))
            ]
            self.file.setFillColorRGB(uniform(0, 1),
                                      uniform(0, 1),
                                      uniform(0, 1),
                                      alpha=uniform(0, 1))
            self.file.setStrokeColorRGB(uniform(0, 1),
                                        uniform(0, 1),
                                        uniform(0, 1),
                                        alpha=uniform(0, 1))
            choice(methods)

    def draw_table(self, data: dict, x: int = 10, y: int = 10):
        """
        This function draws table from your dictionary of data\n
        size of page is 595.27,841.89\n
        :param data: dictionary with data, e.g.
        :param x, y: coordinates of left-bottom corner of table
        {
            'title': 'Table title',
            'columns': [
                {'name': 'Name', 'value': 'name'},
                {'name': 'Age', 'value': 'age'}
            ],
            'rows': [
                {'name': 'string1', 'age': 23},
                {'name': 'string2', 'age': 43}
            ]
        }
        """
        self._normal_color()
        data = self._format_data(data)
        table = Table(data=data,
                      style=[("GRID", (0, 1), (-1, -1), 1, "Black"),
                             ("FONT", (0, 0), (-1, -1), "Calibri",
                              self.font_size),
                             ("BOX", (0, 0), (-1, -1), 1, "Black")])
        table.wrapOn(self.file, 10, 10)
        table.drawOn(self.file, x, y)

    def insert_image(self,
                     path: str,
                     x: int = 100,
                     y: int = 200,
                     width: int = None,
                     height: int = None):
        """
        This function inserts image in pdf-file\n
        size of page is 595.27,841.89\n
        :param path: path to image
        :param x, y: coordinates of left-bottom corner of image
        :param width, height: sizes of image
        """
        image = Image(path, width, height)
        image.drawOn(self.file, x, y)

    def next_page(self):
        """
        This function turns the page\n
        """
        self._normal_color()
        self.file.drawString(565, 30, str(self.page))
        self.page += 1
        self.file.showPage()

    def save(self, author: str = 'pdf_gen', title: str = 'GENERATED'):
        """
        This function saves our file\n
        :param author: author of file
        :param title: title of file
        """
        self._normal_color()
        self.file.drawString(565, 30, str(self.page))
        self.file.setAuthor(author)
        self.file.setTitle(title)
        self.file.save()
Beispiel #20
0
    def _on_first_page(self, canvas: Canvas, doc):
        canvas.setCreator('NETWAYS')
        canvas.setTitle(
            pgettext('invoice',
                     'Invoice {num}').format(num=self.invoice.number))

        canvas.saveState()
        canvas.setFont('OpenSans', 8)
        canvas.drawRightString(self.pagesize[0] - 20 * mm, 10 * mm,
                               pgettext("invoice", "Page %d") % (doc.page, ))

        for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]):
            canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm,
                                     line.strip())

        # https://docs.pretix.eu/en/latest/api/resources/invoices.html
        # https://docs.pretix.eu/en/latest/api/resources/orders.html
        try:
            vatId = self.invoice.order.invoice_address.vat_id

            # NET specific for country vat IDs
            if vatId and vatId.startswith("NL"):
                vatIdFooterNL = "Reverse Charge: BTW Verlegd naar %s According to Art. 12. 3 WOB" % (
                    vatId)

                i += 1
                canvas.drawCentredString(self.pagesize[0] / 2,
                                         40 + (3.5 * i) * mm, vatIdFooterNL)
                # DEBUG
                #i += 1
                #canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, "DEBUG: %s" % (vatId));
        except AttributeError:
            pass

        # Left, Invoice From
        textobject = canvas.beginText(25 * mm, (297 - 15) * mm)
        textobject.setFont('OpenSansBd', 8)
        textobject.textLine(pgettext('invoice', 'Invoice from').upper())
        canvas.drawText(textobject)

        p = Paragraph(self.invoice.full_invoice_from.strip().replace(
            '\n', '<br />\n'),
                      style=self.stylesheet['Normal'])
        p.wrapOn(canvas, 70 * mm, 50 * mm)
        p_size = p.wrap(70 * mm, 50 * mm)
        p.drawOn(canvas, 25 * mm, (297 - 17) * mm - p_size[1])

        # Left, Invoice To
        textobject = canvas.beginText(25 * mm, (297 - 50) * mm)
        textobject.setFont('OpenSansBd', 8)
        textobject.textLine(pgettext('invoice', 'Invoice to').upper())
        canvas.drawText(textobject)

        p = Paragraph(self.invoice.invoice_to.strip().replace(
            '\n', '<br />\n'),
                      style=self.stylesheet['Normal'])
        p.wrapOn(canvas, 85 * mm, 50 * mm)
        p_size = p.wrap(85 * mm, 50 * mm)
        p.drawOn(canvas, 25 * mm, (297 - 52) * mm - p_size[1])

        rightX = 95 * mm

        # Right, Order code
        textobject = canvas.beginText(rightX, (297 - 38) * mm)
        textobject.setFont('OpenSansBd', 8)
        textobject.textLine(pgettext('invoice', 'Order code').upper())
        textobject.moveCursor(0, 5)
        textobject.setFont('OpenSans', 10)
        textobject.textLine(self.invoice.order.full_code)
        canvas.drawText(textobject)

        # Right, * number
        textobject = canvas.beginText(rightX, (297 - 50) * mm)
        textobject.setFont('OpenSansBd', 8)
        if self.invoice.is_cancellation:
            textobject.textLine(
                pgettext('invoice', 'Cancellation number').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(self.invoice.number)
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSansBd', 8)
            textobject.textLine(
                pgettext('invoice', 'Original invoice').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(self.invoice.refers.number)
        else:
            textobject.textLine(pgettext('invoice', 'Invoice number').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(self.invoice.number)
        textobject.moveCursor(0, 5)

        # Right, * date
        if self.invoice.is_cancellation:
            textobject.setFont('OpenSansBd', 8)
            textobject.textLine(
                pgettext('invoice', 'Cancellation date').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT"))
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSansBd', 8)
            textobject.textLine(
                pgettext('invoice', 'Original invoice date').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(
                date_format(self.invoice.refers.date, "DATE_FORMAT"))
            textobject.moveCursor(0, 5)
        else:
            textobject.setFont('OpenSansBd', 8)
            textobject.textLine(pgettext('invoice', 'Invoice date').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT"))
            textobject.moveCursor(0, 5)

        canvas.drawText(textobject)

        # Right, Invoice and Event Logo
        rightLogoX = 160 * mm

        if self.invoice.event.settings.logo_image:
            logo_file = self.invoice.event.settings.get('logo_image',
                                                        binary_file=True)
            canvas.drawImage(ImageReader(logo_file),
                             rightLogoX, (297 - 38) * mm,
                             width=25 * mm,
                             height=25 * mm,
                             preserveAspectRatio=True,
                             anchor='n',
                             mask='auto')

        if self.invoice.event.settings.invoice_logo_image:
            logo_file = self.invoice.event.settings.get('invoice_logo_image',
                                                        binary_file=True)
            canvas.drawImage(ImageReader(logo_file),
                             rightLogoX, (297 - 63) * mm,
                             width=25 * mm,
                             height=25 * mm,
                             preserveAspectRatio=True,
                             anchor='n',
                             mask='auto')

        # Right, Event
        if self.invoice.event.settings.show_date_to:
            p_str = (
                str(self.invoice.event.name) + '\n' +
                pgettext('invoice', '{from_date}\nuntil {to_date}').format(
                    from_date=self.invoice.event.get_date_from_display(),
                    to_date=self.invoice.event.get_date_to_display()))
        else:
            p_str = (str(self.invoice.event.name) + '\n' +
                     self.invoice.event.get_date_from_display())

        p = Paragraph(p_str.strip().replace('\n', '<br />\n'),
                      style=self.stylesheet['Normal'])
        p.wrapOn(canvas, 65 * mm, 50 * mm)
        p_size = p.wrap(65 * mm, 50 * mm)
        p.drawOn(canvas, 95 * mm, (297 - 17) * mm - p_size[1])

        textobject = canvas.beginText(rightX, (297 - 15) * mm)
        textobject.setFont('OpenSansBd', 8)
        textobject.textLine(pgettext('invoice', 'Event').upper())
        canvas.drawText(textobject)

        canvas.restoreState()
Beispiel #21
0
class BadgeGen():
    rowcount = 5
    colcount = 2

    def __init__(self, festival, output):
        self.canvas = Canvas(output, pagesize=A4)
        self.canvas.setLineWidth(0.25)

        self.pagemargin = 20*mm

        self.rowheight = (A4[1] - self.pagemargin*2.0)/BadgeGen.rowcount
        self.colwidth = (A4[0] - self.pagemargin*2.0)/BadgeGen.colcount

        self.index = 0
        self.bps = BadgeGen.rowcount * BadgeGen.colcount
        self.colour = None

        self.festival = festival

        self.logoimage = None
        if self.festival['logo']:
            self.logoimage = ImageReader(self.festival['logo'])
            (w, h) = self.logoimage.getSize()

            if w > h:
                # Wide image.
                self.logowidth = 20*mm
                self.logoheight = h*20*mm/w
            else:
                # Tall image.
                self.logoheight = 20*mm
                self.logowidth  = w*20*mm/h
        else:
            self.logoheight = self.logowidth = 0

        # Size the festival name to fit
        fontsize = 18
        availableWidth = self.colwidth - self.logowidth - 4*mm
        while (self.canvas.stringWidth(self.festival["name"], "Times-Roman", fontsize) > availableWidth):
            fontsize -= 1
        self.festname_fontsize = fontsize
        if self.logoimage:
            if self.canvas.stringWidth(self.festival["name"], "Times-Roman", fontsize) < (availableWidth - self.logowidth):
                # Centre text on whole badge
                self.festname_x = self.colwidth/2
            else:
                # Centre text between logo and RHS
                self.festname_x = self.colwidth/2 + self.logowidth/2
            self.festname_y = self.rowheight - self.logoheight/2 - fontsize/2
        else:
            self.festname_x = self.colwidth/2
            self.festname_y = self.rowheight - 3*mm - fontsize/2

    def _setup_page(self):
        # Draw cutting lines around edge of page.
        self.canvas.setLineWidth(0.25)
        for col in range(0, self.colcount + 1):
            x = self.pagemargin + col * self.colwidth
            self.canvas.line (x, 0, x, self.pagemargin * 0.9)
            self.canvas.line (x, A4[1], x, A4[1] - self.pagemargin * 0.9)

        for row in range(0, self.rowcount + 1):
            y = self.pagemargin + row * self.rowheight
            self.canvas.line (0, y, self.pagemargin * 0.9, y)
            self.canvas.line (A4[0], y, A4[0] - self.pagemargin * 0.9, y)

        # Output the colour if needed.
        if self.colour and ((self.index % self.bps) == 0):
            self.canvas.setFont("Times-Bold", 14)
            self.canvas.drawCentredString(A4[0]/2, A4[1] - self.pagemargin/2 - 7, "To be printed on %s paper" % self.colour)


    def Render(self, data, colour=None):
        if data['altname']:
            # Double sided badge - check we're in the right place.
            while self.index % self.colcount != 0:
                self.index += 1

        if self.index == 0:
            self._setup_page()
        elif (self.colour != colour) or (self.index % self.bps == 0):
            # Start a fresh page - either we finished the last one or these need a different colour.
            self.canvas.showPage()
            self.colour = colour
            self._setup_page()

        # Local copy of index within the page.
        index = self.index % self.bps

        # Work out the co-ordinates for this index
        left = (index % BadgeGen.colcount) * self.colwidth + self.pagemargin
        bottom = (BadgeGen.rowcount - 1 - ((index // BadgeGen.colcount) % BadgeGen.rowcount)) * self.rowheight + self.pagemargin
        width = self.colwidth
        height = self.rowheight

        # Draw a box around the whole badge
        #self.canvas.setLineWidth(0.25)
        #self.canvas.rect (left, bottom, width, height)

        # Draw the logo, 2mm in from the top left, in a box
        if self.logoimage:
            logobottom = bottom + height - self.logoheight - 2*mm
            self.canvas.drawImage(self.logoimage, left + 2*mm, logobottom, self.logowidth, self.logoheight, preserveAspectRatio=True, anchor='nw')

        # Add the festival name, to the right of the logo
        self.canvas.setFont("Times-Roman", self.festname_fontsize)
        self.canvas.drawCentredString(self.festname_x + left, self.festname_y + bottom, self.festival['name'])

        # Add the volunteer name, just below the middle of the badge.
        fontsize = 22
        volname = data['name']
        while (self.canvas.stringWidth(volname, "Times-Bold", fontsize) > (width - 4*mm)):
            fontsize -= 1
        self.canvas.setFont("Times-Bold", fontsize)
        self.canvas.drawCentredString(left + width/2, (bottom + height/2)-(fontsize/2)-2*mm, volname)

        # Add the job title, centred, 3mm in from the bottom.
        if data['job']:
            fontsize = 16
            jobname = data['job']
            while (self.canvas.stringWidth(jobname, "Times-Roman", fontsize) > (width - 40*mm)):
                fontsize -= 1
            self.canvas.setFont("Times-Roman", fontsize)
            self.canvas.drawCentredString(left + width/2, bottom+3*mm, jobname)

        if data['id']:
            self.canvas.setFont("Courier", 8)
            self.canvas.drawRightString(left + width - 1*mm, bottom+3*mm, data['id'])
            # Barcode
            code = code128.Code128(data['id'])
            code.drawOn(self.canvas, left - 3*mm, bottom+2*mm)

        self.index = index + 1

        if data['altname']:
            # Call ourselves to render the alternative badge on the other half.
            data['name'] = data['altname']
            data['altname'] = None
            self.Render (data, colour)

    def Save(self):
        # Fill the rest of the sheet with useful blanks.
        blank = {'name':'', 'job':'Volunteer', 'altname':None, 'id':None}
        while self.index % self.bps:
            self.Render (blank, self.colour)

        self.canvas.save()
Beispiel #22
0
can.setFillColorCMYK(.7,0,.5,0)                 # couleur de remplissage (CMJN)
can.ellipse(3*cm, 4*cm, 19*cm, 10*cm, fill=1)   # ellipse (! axes = 16 x 6 cm)
can.setLineWidth(1)                             # nouvelle épaisseur des lignes
can.ellipse(centreX -.5*cm, centreY -.5*cm,     # petit cercle indiquant la
            centreX +.5*cm, centreY +.5*cm)     # position du centre de la page

# Quelques textes, avec polices, orientation et alignement divers :
can.setFillColor("navy")                        # couleur des textes
texteC ="Petite pluie abat grand vent."         # texte à centrer
can.setFont("Times-Bold", 18)
can.drawCentredString(centreX, centreY, texteC)
texteG ="Qui ne risque rien, n'a rien."         # texte à aligner à gauche
can.setFont("Helvetica", 18)
can.drawString(centreX, centreY -1*cm, texteG)
texteD ="La nuit porte conseil."                # texte à aligner à droite
can.setFont("Courier", 18)
can.drawRightString(centreX, centreY -2*cm, texteD)
texteV ="L'espoir fait  vivre."                 # texte à disposer verticalement
can.rotate(90)
can.setFont("Times-Italic", 18)
can.drawString(centreY +1*cm, -centreX, texteV) # ! inversion des coordonnées !
texteE ="L'exception confirme la règle"         # texte à afficher en blanc
can.rotate(-90)                                 # retour à l'orientation horiz.
can.setFont("Times-BoldItalic", 28)
can.setFillColor("white")                       # nouvelle couleur des textes
can.drawCentredString(centreX, 7*cm, texteE)

can.save()                                      # Sauvegarde du résultat

Beispiel #23
0
    def _on_first_page(self, canvas: Canvas, doc):
        canvas.setCreator('pretix.eu')
        canvas.setTitle(pgettext('invoice', 'Invoice {num}').format(num=self.invoice.number))

        canvas.saveState()
        canvas.setFont('OpenSans', 8)
        canvas.drawRightString(self.pagesize[0] - 20 * mm, 10 * mm, pgettext("invoice", "Page %d") % (doc.page,))

        for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]):
            canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, line.strip())

        textobject = canvas.beginText(25 * mm, (297 - 15) * mm)
        textobject.setFont('OpenSansBd', 8)
        textobject.textLine(pgettext('invoice', 'Invoice from').upper())
        canvas.drawText(textobject)

        self._draw_invoice_from(canvas)

        textobject = canvas.beginText(25 * mm, (297 - 50) * mm)
        textobject.setFont('OpenSansBd', 8)
        textobject.textLine(pgettext('invoice', 'Invoice to').upper())
        canvas.drawText(textobject)

        self._draw_invoice_to(canvas)

        textobject = canvas.beginText(125 * mm, (297 - 38) * mm)
        textobject.setFont('OpenSansBd', 8)
        textobject.textLine(pgettext('invoice', 'Order code').upper())
        textobject.moveCursor(0, 5)
        textobject.setFont('OpenSans', 10)
        textobject.textLine(self.invoice.order.full_code)
        canvas.drawText(textobject)

        textobject = canvas.beginText(125 * mm, (297 - 50) * mm)
        textobject.setFont('OpenSansBd', 8)
        if self.invoice.is_cancellation:
            textobject.textLine(pgettext('invoice', 'Cancellation number').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(self.invoice.number)
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSansBd', 8)
            textobject.textLine(pgettext('invoice', 'Original invoice').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(self.invoice.refers.number)
        else:
            textobject.textLine(pgettext('invoice', 'Invoice number').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(self.invoice.number)
        textobject.moveCursor(0, 5)

        if self.invoice.is_cancellation:
            textobject.setFont('OpenSansBd', 8)
            textobject.textLine(pgettext('invoice', 'Cancellation date').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT"))
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSansBd', 8)
            textobject.textLine(pgettext('invoice', 'Original invoice date').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(date_format(self.invoice.refers.date, "DATE_FORMAT"))
            textobject.moveCursor(0, 5)
        else:
            textobject.setFont('OpenSansBd', 8)
            textobject.textLine(pgettext('invoice', 'Invoice date').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT"))
            textobject.moveCursor(0, 5)

        canvas.drawText(textobject)

        if self.invoice.event.settings.invoice_logo_image:
            logo_file = self.invoice.event.settings.get('invoice_logo_image', binary_file=True)
            ir = ThumbnailingImageReader(logo_file)
            try:
                ir.resize(25 * mm, 25 * mm, 300)
            except:
                logger.exception("Can not resize image")
                pass
            canvas.drawImage(ir,
                             95 * mm, (297 - 38) * mm,
                             width=25 * mm, height=25 * mm,
                             preserveAspectRatio=True, anchor='n',
                             mask='auto')

        def shorten(txt):
            txt = str(txt)
            p = Paragraph(txt.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal'])
            p_size = p.wrap(65 * mm, 50 * mm)

            while p_size[1] > 2 * self.stylesheet['Normal'].leading:
                txt = ' '.join(txt.replace('…', '').split()[:-1]) + '…'
                p = Paragraph(txt.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal'])
                p_size = p.wrap(65 * mm, 50 * mm)
            return txt

        if not self.invoice.event.has_subevents:
            if self.invoice.event.settings.show_date_to and self.invoice.event.date_to:
                p_str = (
                    shorten(self.invoice.event.name) + '\n' + pgettext('invoice', '{from_date}\nuntil {to_date}').format(
                        from_date=self.invoice.event.get_date_from_display(),
                        to_date=self.invoice.event.get_date_to_display())
                )
            else:
                p_str = (
                    shorten(self.invoice.event.name) + '\n' + self.invoice.event.get_date_from_display()
                )
        else:
            p_str = shorten(self.invoice.event.name)

        p = Paragraph(p_str.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal'])
        p.wrapOn(canvas, 65 * mm, 50 * mm)
        p_size = p.wrap(65 * mm, 50 * mm)
        p.drawOn(canvas, 125 * mm, (297 - 17) * mm - p_size[1])

        textobject = canvas.beginText(125 * mm, (297 - 15) * mm)
        textobject.setFont('OpenSansBd', 8)
        textobject.textLine(pgettext('invoice', 'Event').upper())
        canvas.drawText(textobject)

        canvas.restoreState()
Beispiel #24
0
    def _on_first_page(self, canvas: Canvas, doc):
        canvas.setCreator('pretix.eu')
        canvas.setTitle(
            pgettext('invoice',
                     'Invoice {num}').format(num=self.invoice.number))

        canvas.saveState()
        canvas.setFont('OpenSans', 8)
        canvas.drawRightString(self.pagesize[0] - 20 * mm, 10 * mm,
                               pgettext("invoice", "Page %d") % (doc.page, ))

        for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]):
            canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm,
                                     line.strip())

        textobject = canvas.beginText(25 * mm, (297 - 15) * mm)
        textobject.setFont('OpenSansBd', 8)
        textobject.textLine(pgettext('invoice', 'Invoice from').upper())
        canvas.drawText(textobject)

        p = Paragraph(self.invoice.invoice_from.strip().replace(
            '\n', '<br />\n'),
                      style=self.stylesheet['Normal'])
        p.wrapOn(canvas, 70 * mm, 50 * mm)
        p_size = p.wrap(70 * mm, 50 * mm)
        p.drawOn(canvas, 25 * mm, (297 - 17) * mm - p_size[1])

        textobject = canvas.beginText(25 * mm, (297 - 50) * mm)
        textobject.setFont('OpenSansBd', 8)
        textobject.textLine(pgettext('invoice', 'Invoice to').upper())
        canvas.drawText(textobject)

        p = Paragraph(self.invoice.invoice_to.strip().replace(
            '\n', '<br />\n'),
                      style=self.stylesheet['Normal'])
        p.wrapOn(canvas, 85 * mm, 50 * mm)
        p_size = p.wrap(85 * mm, 50 * mm)
        p.drawOn(canvas, 25 * mm, (297 - 52) * mm - p_size[1])

        textobject = canvas.beginText(125 * mm, (297 - 38) * mm)
        textobject.setFont('OpenSansBd', 8)
        textobject.textLine(pgettext('invoice', 'Order code').upper())
        textobject.moveCursor(0, 5)
        textobject.setFont('OpenSans', 10)
        textobject.textLine(self.invoice.order.full_code)
        canvas.drawText(textobject)

        textobject = canvas.beginText(125 * mm, (297 - 50) * mm)
        textobject.setFont('OpenSansBd', 8)
        if self.invoice.is_cancellation:
            textobject.textLine(
                pgettext('invoice', 'Cancellation number').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(self.invoice.number)
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSansBd', 8)
            textobject.textLine(
                pgettext('invoice', 'Original invoice').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(self.invoice.refers.number)
        else:
            textobject.textLine(pgettext('invoice', 'Invoice number').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(self.invoice.number)
        textobject.moveCursor(0, 5)

        if self.invoice.is_cancellation:
            textobject.setFont('OpenSansBd', 8)
            textobject.textLine(
                pgettext('invoice', 'Cancellation date').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT"))
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSansBd', 8)
            textobject.textLine(
                pgettext('invoice', 'Original invoice date').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(
                date_format(self.invoice.refers.date, "DATE_FORMAT"))
            textobject.moveCursor(0, 5)
        else:
            textobject.setFont('OpenSansBd', 8)
            textobject.textLine(pgettext('invoice', 'Invoice date').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont('OpenSans', 10)
            textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT"))
            textobject.moveCursor(0, 5)

        canvas.drawText(textobject)

        if self.invoice.event.settings.invoice_logo_image:
            logo_file = self.invoice.event.settings.get('invoice_logo_image',
                                                        binary_file=True)
            canvas.drawImage(ImageReader(logo_file),
                             95 * mm, (297 - 38) * mm,
                             width=25 * mm,
                             height=25 * mm,
                             preserveAspectRatio=True,
                             anchor='n',
                             mask='auto')

        if self.invoice.event.settings.show_date_to:
            p_str = (
                str(self.invoice.event.name) + '\n' +
                pgettext('invoice', '{from_date}\nuntil {to_date}').format(
                    from_date=self.invoice.event.get_date_from_display(),
                    to_date=self.invoice.event.get_date_to_display()))
        else:
            p_str = (str(self.invoice.event.name) + '\n' +
                     self.invoice.event.get_date_from_display())

        p = Paragraph(p_str.strip().replace('\n', '<br />\n'),
                      style=self.stylesheet['Normal'])
        p.wrapOn(canvas, 65 * mm, 50 * mm)
        p_size = p.wrap(65 * mm, 50 * mm)
        p.drawOn(canvas, 125 * mm, (297 - 17) * mm - p_size[1])

        textobject = canvas.beginText(125 * mm, (297 - 15) * mm)
        textobject.setFont('OpenSansBd', 8)
        textobject.textLine(pgettext('invoice', 'Event').upper())
        canvas.drawText(textobject)

        canvas.restoreState()
Beispiel #25
0
def impr_recibo(request, pk):
    mitad = 14.8 * cm
    mita = 14.8
    # Inicializo todos los comprobantes y valores
    recibo = Recibo.objects.get(pk=pk)
    a_cuenta = recibo.a_cuenta
    # Datos de comprobantes
    comprobantes = recibo.detalle_cobro_set.all()
    # a_cuenta = recibo.cobranza_a_cuenta_set.all()
    # credito_anterior = recibo.cobranza_credito_anterior_set.all()
    # Datos de valores
    valores = recibo.dinero_set.all()
    # transferencia = recibo.transferenciabancariaentrante_set.all()
    # efectivo = recibo.dinero_set.all()
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'filename="somefilename.pdf"'
    p = Canvas(response, pagesize=A4)
    # Numero de recibo
    p.setFont('Helvetica-Bold', 16)
    p.drawString(15.7 * cm, 13 * cm, recibo.numero_full)
    # Fecha
    p.setFont('Helvetica', 13)
    p.drawString(17 * cm, 12 * cm, str(recibo.fecha.day))
    p.drawString(18 * cm, 12 * cm, str(recibo.fecha.month))
    p.drawString(19 * cm, 12 * cm, str(recibo.fecha.year))
    # Datos del cliente
    p.setFont('Helvetica', 13)
    p.drawString(12 * cm, 11 * cm, recibo.cliente.razon_social)
    p.drawString(12 * cm, 10.3 * cm, recibo.cliente.get_cond_iva_display())
    p.drawString(12 * cm, 9.8 * cm, "CUIT: %s" % recibo.cliente.cuit)
    p.drawString(12 * cm, 9.3 * cm, recibo.cliente.direccion)
    p.drawString(12 * cm, 8.8 * cm, "%s - %s" % (recibo.cliente.localidad, recibo.cliente.get_provincia_display()))
    inicio_y = 6.2
    alto_item = 0.4
    i = 0
    p.setFont('Helvetica', 7)
    if a_cuenta and a_cuenta > 0:
        p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, "A cuenta")
        p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % a_cuenta)
        i += 1
    if recibo.credito_anterior and recibo.credito_anterior > 0:
        p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, "Credito anterior")
        p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, "-%.2f" % recibo.credito_anterior)
        i += 1
    for item in comprobantes:
        p.drawString(2 * cm, (inicio_y - i * alto_item) * cm, item.venta.tipo)
        p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, item.venta.num_comp_full())
        p.drawString(5.1 * cm, (inicio_y - i * alto_item) * cm, item.venta.fecha_dd_mm_aaaa())
        p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, item.monto_2d())
        i += 1
    # Cheques
    i = 0
    for item in valores:
        try:
            p.drawString(10 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.numero)
            p.drawString(11.7 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.cuit_titular)
            p.drawString(13.8 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.fecha_dd_mm_aaaa())
            p.drawString(15.4 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.banco.nombre[:20])
            p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto)
        except Dinero.DoesNotExist:
            try:
                item.transferenciabancariaentrante
                p.drawString(10 * cm, (inicio_y - i * alto_item) * cm, "Transferencia Bancaria")
                p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto)
            except Dinero.DoesNotExist:
                p.drawString(10 * cm, (inicio_y - i * alto_item) * cm,
                             "Efectivo" if item.monto >= 0 else "Efectivo - SU VUELTO")
                p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto)
        finally:
            i += 1
    # for item in transferencia:
    #    p.drawString(10*cm, (inicio_y-i*alto_item)*cm, "Transferencia Bancaria")
    #    p.drawRightString(20*cm, (inicio_y-i*alto_item)*cm, "%.2f" %item.monto)
    #    i+=1
    # for item in efectivo:
    #    p.drawString(10*cm, (inicio_y-i*alto_item)*cm, "Efectivo")
    #    p.drawRightString(20*cm, (inicio_y-i*alto_item)*cm, "%.2f" %item.monto)
    #    i+=1
    p.setFont('Helvetica-Bold', 12)
    p.drawString(7.5 * cm, 2.3 * cm, recibo.total_str)
    p.drawString(18 * cm, 2.3 * cm, recibo.total_str)
    try:
        letra = (to_word(int(recibo.total_str.split('.')[0].strip())) + "con " + to_word(
            int(recibo.total_str.split('.')[1].strip())) + "centavos").lower()
    except IndexError:
        letra = (to_word(int(recibo.total_str.split('.')[0].strip()))).lower()
    p.setFont('Helvetica', 9)
    p.drawString(2 * cm, 7.5 * cm, letra)
    ######################################################
    ##############RECIBO DUPLICADO########################
    ######################################################
    # Numero de recibo
    p.setFont('Helvetica-Bold', 16)
    p.drawString(15.7 * cm, mitad + 13 * cm, recibo.numero_full)
    # Fecha
    p.setFont('Helvetica', 13)
    p.drawString(17 * cm, mitad + 12 * cm, str(recibo.fecha.day))
    p.drawString(18 * cm, mitad + 12 * cm, str(recibo.fecha.month))
    p.drawString(19 * cm, mitad + 12 * cm, str(recibo.fecha.year))
    # Datos del cliente
    p.setFont('Helvetica', 13)
    p.drawString(12 * cm, mitad + 11 * cm, recibo.cliente.razon_social)
    p.drawString(12 * cm, mitad + 10.3 * cm, recibo.cliente.get_cond_iva_display())
    p.drawString(12 * cm, mitad + 9.8 * cm, "CUIT: %s" % recibo.cliente.cuit)
    p.drawString(12 * cm, mitad + 9.3 * cm, recibo.cliente.direccion)
    p.drawString(12 * cm, mitad + 8.8 * cm,
                 "%s - %s" % (recibo.cliente.localidad, recibo.cliente.get_provincia_display()))
    # Datos de comprobantes
    # comprobantes = recibo.detalle_cobro_set.all()
    inicio_y = mita + 6.2
    alto_item = 0.4
    i = 0
    p.setFont('Helvetica', 7)
    if a_cuenta and a_cuenta > 0:
        p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, "A cuenta")
        p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % a_cuenta)
        i += 1
    if recibo.credito_anterior and recibo.credito_anterior > 0:
        p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, "Credito anterior")
        p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, "-%.2f" % recibo.credito_anterior)
        i += 1
    for item in comprobantes:
        p.drawString(2 * cm, (inicio_y - i * alto_item) * cm, item.venta.tipo)
        p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, item.venta.num_comp_full())
        p.drawString(5.1 * cm, (inicio_y - i * alto_item) * cm, item.venta.fecha_dd_mm_aaaa())
        p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm, item.monto_2d())
        i += 1
    i = 0
    for item in valores:
        try:
            p.drawString(10 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.numero)
            p.drawString(11.7 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.cuit_titular)
            p.drawString(13.8 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.fecha_dd_mm_aaaa())
            p.drawString(15.4 * cm, (inicio_y - i * alto_item) * cm, item.chequetercero.banco.nombre[:20])
            p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto)
        except Dinero.DoesNotExist:
            try:
                item.transferenciabancariaentrante
                p.drawString(10 * cm, (inicio_y - i * alto_item) * cm, "Transferencia Bancaria")
                p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto)
            except Dinero.DoesNotExist:
                p.drawString(10 * cm, (inicio_y - i * alto_item) * cm,
                             "Efectivo" if item.monto >= 0 else "Efectivo - SU VUELTO")
                p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm, "%.2f" % item.monto)
        finally:
            i += 1
    p.setFont('Helvetica-Bold', 12)
    p.drawString(7.5 * cm, mitad + 2.3 * cm, recibo.total_str)
    p.drawString(18 * cm, mitad + 2.3 * cm, recibo.total_str)
    try:
        letra = (to_word(int(recibo.total_str.split('.')[0].strip())) + "con " + to_word(
            int(recibo.total_str.split('.')[1].strip())) + "centavos").lower()
    except IndexError:
        letra = (to_word(int(recibo.total_str.split('.')[0].strip()))).lower()
    p.setFont('Helvetica', 9)
    p.drawString(2 * cm, mitad + 7.5 * cm, letra)
    p.showPage()
    p.save()
    return response
Beispiel #26
0
class DancerPDF():
    def __init__(self):
        self.reporter = Reporter()

        ##################################################################
        # *Abs. means a coordinate position according to reportlab. These are
        # full-page, centred bottom left.
        # *Raw means a coordinate position on stock. This includes
        # margins (so the stock).
        # *Raw is centred top left stock, even though reportlab works from
        # bottom left.
        # *Raw can be converted to reportlab coordinates using the functions
        # rawToAbsX() and rawToAbsY()
        #

        ## Page size ##
        self.pageStock = A4

        ## reportlab canvas ##
        #! as instance?
        self.c = Canvas("test.pdf", pagesize=self.pageStock)

        ## Stock ##
        #! no, 'typeblock'

        self._pageHeight = self.pageStock[1]
        self._pageWidth = self.pageStock[0]
        self._centerPage = self._pageWidth / 2

        self.leftMargin = mm * 20
        self.rightMargin = mm * 20
        self.topMargin = mm * 20
        self.bottomMargin = mm * 40

        self.rightStockAbs = self._pageWidth - self.rightMargin
        self.leftStockAbs = self.leftMargin
        self.topStockAbs = self._pageHeight - self.topMargin
        self.bottomStockAbs = self.bottomMargin

        # passed to renderMoveBlock
        self.stockContext = [
            self._pageHeight, self._pageWidth, self.topStockAbs,
            self.rightStockAbs, self.leftStockAbs, self.bottomStockAbs,
            self.topMargin
        ]

        ###########################################################
        ## Page ##

        ## Title ##
        # carries space if necessary (when sections start)
        self.titleFontFamily = "Times-Roman"
        self.titleFontSize = 24
        self.titleTopSkip = 8

        # Internal
        # tracks the start height of the moves block
        # allowing space for main or section titles
        self._titleHeightRaw = 0
        # currently 114, should be 95

        ## Sections ##
        self.sectionFontFamily = "Times-Roman"
        self.sectionFontSize = 24
        self.sectionTopSkip = 8

        ## Credits ##
        # If used, credits are aligned under the title. However, they do not
        # contribute to the overall space above the
        # musicalDirections. This is to give maximum flexibility in overriding
        # (for example, they could be in a column to the right of musical
        # directions). To make space for them, increase musicalDirectionsTopSkip.
        self.creditsFontFamily = "Times-Roman"
        self.creditsFontSize = 14
        # above first credit
        self.creditsTopSkip = 0
        # above each credit
        self.creditLineTopSkip = 4

        ## Move block essentials ##
        # Declared early because musical directions need to be aligned with the
        # opening time signature.

        # fixed space to go before music.
        # This is inserted at the beginning of lines which
        # contain only music.
        # This needs to be something, or the first move will sit on the
        # first barline. About a quarter of the overall glue/note spacing
        # is ok.
        self.moveLineMusicOnlyLeftSkip = 14

        # Many music scores adopt an indent. Not often applicable here, so will
        # usually be zero. If you have any material starting a move line, use it.
        # This variable can not be calculated (font width of time signature,
        # and other material).
        # NOT IMPLEMENTED
        #moveblockFirstLineIndent = 0

        # Amount of glue for a barline (apears after the barline), by our
        # current calculation. Works best round 0.5.
        self.barlineGlue = 0.5

        # The last line in any block may not have the right number of bars.
        # The simplistic solution here, if the line is within this number of
        # bars then it will stretched to full width, otherwise the line is
        # rendered as stopping short. To always stretch, make this a relativly
        # large number e.g. 12. 0 will never stretch.
        self.lastMovelineGlueMax = 2

        ## MusicalDirections ##
        self.musicalDirectionFontFamily = "Times-Bold"
        self.musicalDirectionFontSize = 9
        self.musicalDirectionBottomSkip = 12

        self._musicalDirectionContext = [
            self.musicalDirectionFontFamily, self.musicalDirectionFontSize,
            self.musicalDirectionBottomSkip
        ]

        ####################################################################
        ## The move block ##
        # The move block is almost all automatic layout. This has it's
        # diadvantages, but we will see....

        # Space above the block.
        # Used to add space for the top line of tempo marks, clearing the
        # freely placed credits.
        self.movesBlockTopSkip = 24

        # gap between lines. Don't make too small.
        self.movesLineTopSkip = 96

        ####################################################################
        ## Time signature ##
        self.timeMarkFontFamily = "Times-Roman"
        self.timeMarkFontSize = 16

        # Reserve space for time signatures.
        # For marks at line starts and inline.
        # This variable can not be calculated (possible width of oversize font).
        # If the time signature font size is changed, alter by hand.
        # Should be, say, 3/2 of the width of the fonts as written as glyphs.
        self.timeMarkWidth = 24

        # How far down from the line to drop a time signature
        self.timeMarkSkipDown = 24

        # Fixed allocation for indenting a time mark.
        # The time mark sits at the beginning of it's allocation. this is
        # used to push from barlines (and other preceeding content?).
        # Should only be a handful of points.
        #! while this is necessary and good, more is needed. A pre-music
        # indent to go after time signatures and before lines without time
        # marks would be helpful.
        self.timeMarkLeftSkip = 4
        #timeMarkLeftSkip = 0

        self._timeMarkContext = [
            self.timeMarkFontFamily, self.timeMarkFontSize, self.timeMarkWidth,
            self.timeMarkSkipDown, self.timeMarkLeftSkip
        ]

        ## moveLines ##

        # Express an interest in how many bars to a line
        # In many circumstances, will not be honoured. But used for open
        # bar rendering, so will stretch bars to fit the page width.
        #! what about sheet width, etc.?
        self.barPerLineAim = 5

        # fixed width for barmarks to occupy
        self.barmarkWidth = 24

        # The minimum glue allowed before bars are spilled to the next line
        self.minMoveGlueWidth = 14

        self.moveLineContentFontFamily = "Times-Roman"
        self.moveLineContentFontSize = 12

        # space down from the moveline to the move marks
        self.moveLineContentSkipDown = 8

        self.moveLineContentContext = [
            self.moveLineContentFontFamily, self.moveLineContentFontSize,
            self.moveLineContentSkipDown, self.moveLineMusicOnlyLeftSkip
        ]

    def addInstruction(self, m):
        self.mbr.addInstruction(m)

    def save(self):
        self.c.save()

    #################################################################

    ###########################################################
    ## Coordinate functions ##
    # rawToAbsX() and rawToAbsY() convert *Raw positions to *Abs
    #

    #? unused
    def rawToAbsX(self, x):
        return self.leftMargin + x

    def rawToAbsY(self, y):
        return self.topStockAbs - y

    def title(self, title):
        self.c.setFont(self.titleFontFamily, self.titleFontSize)
        self.c.drawCentredString(self._centerPage,
                                 self.rawToAbsY(self.titleTopSkip), title)
        self._titleHeightRaw = self.titleTopSkip + self.titleFontSize

    #! TODO
    def section(self, title):
        # initialize
        self.c.showPage()
        self._titleHeightRaw = 0

        # render
        self.c.setFont(self.sectionFontFamily, self.sectionFontSize)
        self.c.drawCentredString(self._centerPage,
                                 self.rawToAbsY(self.sectionTopSkip), title)
        self._titleHeightRaw = self.sectionTopSkip + self.sectionFontSize

    def titleCredits(self, performers, transcribedBy):
        self.c.setFont(self.creditsFontFamily, self.creditsFontSize)
        #48
        self.c.drawRightString(
            self.rightStockAbs,
            self.rawToAbsY(self._titleHeightRaw + self.creditsTopSkip),
            performers)
        self._titleHeightRaw += self.creditsTopSkip + self.creditsFontSize
        #68
        self.c.drawRightString(
            self.rightStockAbs,
            self.rawToAbsY(self._titleHeightRaw + self.creditLineTopSkip),
            "Trns: " + transcribedBy)

    # Opens a movesblock
    def movesblock(self):
        self._titleHeightRaw += self.movesBlockTopSkip
        return MoveBlockRender(
            self.c,
            self.reporter,
            stockContext=self.stockContext,
            barsInLineAim=self.barPerLineAim,
            lineTopSkip=self.movesLineTopSkip,
            firstPageTopSkip=self._titleHeightRaw,
            #moveblockFirstLineIndent = moveblockFirstLineIndent,
            barlineGlue=self.barlineGlue,
            minMoveGlueWidth=self.minMoveGlueWidth,
            lastMovelineGlueMax=self.lastMovelineGlueMax,
            musicalDirectionContext=self._musicalDirectionContext,
            timeMarkContext=self._timeMarkContext,
            moveLineContentContext=self.moveLineContentContext)

    ## Utils ##
    #x deprecated, when we get times and tempo in the block class
    def moveLineYRaw(self, idx):
        # positioning for each line
        return self._titleHeightRaw + (self.movesLineTopSkip * idx)
Beispiel #27
0
def impr_recibo(request, pk):
    mitad = 14.8 * cm
    mita = 14.8
    # Inicializo todos los comprobantes y valores
    recibo = Recibo.objects.get(pk=pk)
    a_cuenta = recibo.a_cuenta
    # Datos de comprobantes
    comprobantes = recibo.detalle_cobro_set.all()
    # a_cuenta = recibo.cobranza_a_cuenta_set.all()
    # credito_anterior = recibo.cobranza_credito_anterior_set.all()
    # Datos de valores
    valores = recibo.dinero_set.all()
    # transferencia = recibo.transferenciabancariaentrante_set.all()
    # efectivo = recibo.dinero_set.all()
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'filename="somefilename.pdf"'
    p = Canvas(response, pagesize=A4)
    # Numero de recibo
    p.setFont('Helvetica-Bold', 16)
    p.drawString(15.7 * cm, 13 * cm, recibo.numero_full)
    # Fecha
    p.setFont('Helvetica', 13)
    p.drawString(17 * cm, 12 * cm, str(recibo.fecha.day))
    p.drawString(18 * cm, 12 * cm, str(recibo.fecha.month))
    p.drawString(19 * cm, 12 * cm, str(recibo.fecha.year))
    # Datos del cliente
    p.setFont('Helvetica', 13)
    p.drawString(12 * cm, 11 * cm, recibo.cliente.razon_social)
    p.drawString(12 * cm, 10.3 * cm, recibo.cliente.get_cond_iva_display())
    p.drawString(12 * cm, 9.8 * cm, "CUIT: %s" % recibo.cliente.cuit)
    p.drawString(12 * cm, 9.3 * cm, recibo.cliente.direccion)
    p.drawString(
        12 * cm, 8.8 * cm, "%s - %s" %
        (recibo.cliente.localidad, recibo.cliente.get_provincia_display()))
    inicio_y = 6.2
    alto_item = 0.4
    i = 0
    p.setFont('Helvetica', 7)
    if a_cuenta and a_cuenta > 0:
        p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, "A cuenta")
        p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm,
                          "%.2f" % a_cuenta)
        i += 1
    if recibo.credito_anterior and recibo.credito_anterior > 0:
        p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm,
                     "Credito anterior")
        p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm,
                          "-%.2f" % recibo.credito_anterior)
        i += 1
    for item in comprobantes:
        p.drawString(2 * cm, (inicio_y - i * alto_item) * cm, item.venta.tipo)
        p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm,
                     item.venta.num_comp_full())
        p.drawString(5.1 * cm, (inicio_y - i * alto_item) * cm,
                     item.venta.fecha_dd_mm_aaaa())
        p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm,
                          item.monto_2d())
        i += 1
    # Cheques
    i = 0
    for item in valores:
        try:
            p.drawString(10 * cm, (inicio_y - i * alto_item) * cm,
                         item.chequetercero.numero)
            p.drawString(11.7 * cm, (inicio_y - i * alto_item) * cm,
                         item.chequetercero.cuit_titular)
            p.drawString(13.8 * cm, (inicio_y - i * alto_item) * cm,
                         item.chequetercero.fecha_dd_mm_aaaa())
            p.drawString(15.4 * cm, (inicio_y - i * alto_item) * cm,
                         item.chequetercero.banco.nombre[:20])
            p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm,
                              "%.2f" % item.monto)
        except Dinero.DoesNotExist:
            try:
                item.transferenciabancariaentrante
                p.drawString(10 * cm, (inicio_y - i * alto_item) * cm,
                             "Transferencia Bancaria")
                p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm,
                                  "%.2f" % item.monto)
            except Dinero.DoesNotExist:
                p.drawString(
                    10 * cm, (inicio_y - i * alto_item) * cm,
                    "Efectivo" if item.monto >= 0 else "Efectivo - SU VUELTO")
                p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm,
                                  "%.2f" % item.monto)
        finally:
            i += 1
    # for item in transferencia:
    #    p.drawString(10*cm, (inicio_y-i*alto_item)*cm, "Transferencia Bancaria")
    #    p.drawRightString(20*cm, (inicio_y-i*alto_item)*cm, "%.2f" %item.monto)
    #    i+=1
    # for item in efectivo:
    #    p.drawString(10*cm, (inicio_y-i*alto_item)*cm, "Efectivo")
    #    p.drawRightString(20*cm, (inicio_y-i*alto_item)*cm, "%.2f" %item.monto)
    #    i+=1
    p.setFont('Helvetica-Bold', 12)
    p.drawString(7.5 * cm, 2.3 * cm, recibo.total_str)
    p.drawString(18 * cm, 2.3 * cm, recibo.total_str)
    try:
        letra = (to_word(int(recibo.total_str.split('.')[0].strip())) +
                 "con " +
                 to_word(int(recibo.total_str.split('.')[1].strip())) +
                 "centavos").lower()
    except IndexError:
        letra = (to_word(int(recibo.total_str.split('.')[0].strip()))).lower()
    p.setFont('Helvetica', 9)
    p.drawString(2 * cm, 7.5 * cm, letra)
    ######################################################
    ##############RECIBO DUPLICADO########################
    ######################################################
    # Numero de recibo
    p.setFont('Helvetica-Bold', 16)
    p.drawString(15.7 * cm, mitad + 13 * cm, recibo.numero_full)
    # Fecha
    p.setFont('Helvetica', 13)
    p.drawString(17 * cm, mitad + 12 * cm, str(recibo.fecha.day))
    p.drawString(18 * cm, mitad + 12 * cm, str(recibo.fecha.month))
    p.drawString(19 * cm, mitad + 12 * cm, str(recibo.fecha.year))
    # Datos del cliente
    p.setFont('Helvetica', 13)
    p.drawString(12 * cm, mitad + 11 * cm, recibo.cliente.razon_social)
    p.drawString(12 * cm, mitad + 10.3 * cm,
                 recibo.cliente.get_cond_iva_display())
    p.drawString(12 * cm, mitad + 9.8 * cm, "CUIT: %s" % recibo.cliente.cuit)
    p.drawString(12 * cm, mitad + 9.3 * cm, recibo.cliente.direccion)
    p.drawString(
        12 * cm, mitad + 8.8 * cm, "%s - %s" %
        (recibo.cliente.localidad, recibo.cliente.get_provincia_display()))
    # Datos de comprobantes
    # comprobantes = recibo.detalle_cobro_set.all()
    inicio_y = mita + 6.2
    alto_item = 0.4
    i = 0
    p.setFont('Helvetica', 7)
    if a_cuenta and a_cuenta > 0:
        p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm, "A cuenta")
        p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm,
                          "%.2f" % a_cuenta)
        i += 1
    if recibo.credito_anterior and recibo.credito_anterior > 0:
        p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm,
                     "Credito anterior")
        p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm,
                          "-%.2f" % recibo.credito_anterior)
        i += 1
    for item in comprobantes:
        p.drawString(2 * cm, (inicio_y - i * alto_item) * cm, item.venta.tipo)
        p.drawString(3.4 * cm, (inicio_y - i * alto_item) * cm,
                     item.venta.num_comp_full())
        p.drawString(5.1 * cm, (inicio_y - i * alto_item) * cm,
                     item.venta.fecha_dd_mm_aaaa())
        p.drawRightString(7.4 * cm, (inicio_y - i * alto_item) * cm,
                          item.monto_2d())
        i += 1
    i = 0
    for item in valores:
        try:
            p.drawString(10 * cm, (inicio_y - i * alto_item) * cm,
                         item.chequetercero.numero)
            p.drawString(11.7 * cm, (inicio_y - i * alto_item) * cm,
                         item.chequetercero.cuit_titular)
            p.drawString(13.8 * cm, (inicio_y - i * alto_item) * cm,
                         item.chequetercero.fecha_dd_mm_aaaa())
            p.drawString(15.4 * cm, (inicio_y - i * alto_item) * cm,
                         item.chequetercero.banco.nombre[:20])
            p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm,
                              "%.2f" % item.monto)
        except Dinero.DoesNotExist:
            try:
                item.transferenciabancariaentrante
                p.drawString(10 * cm, (inicio_y - i * alto_item) * cm,
                             "Transferencia Bancaria")
                p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm,
                                  "%.2f" % item.monto)
            except Dinero.DoesNotExist:
                p.drawString(
                    10 * cm, (inicio_y - i * alto_item) * cm,
                    "Efectivo" if item.monto >= 0 else "Efectivo - SU VUELTO")
                p.drawRightString(20 * cm, (inicio_y - i * alto_item) * cm,
                                  "%.2f" % item.monto)
        finally:
            i += 1
    p.setFont('Helvetica-Bold', 12)
    p.drawString(7.5 * cm, mitad + 2.3 * cm, recibo.total_str)
    p.drawString(18 * cm, mitad + 2.3 * cm, recibo.total_str)
    try:
        letra = (to_word(int(recibo.total_str.split('.')[0].strip())) +
                 "con " +
                 to_word(int(recibo.total_str.split('.')[1].strip())) +
                 "centavos").lower()
    except IndexError:
        letra = (to_word(int(recibo.total_str.split('.')[0].strip()))).lower()
    p.setFont('Helvetica', 9)
    p.drawString(2 * cm, mitad + 7.5 * cm, letra)
    p.showPage()
    p.save()
    return response
Beispiel #28
0
class Report(object):
    render = {'table': render.TableRender,
              'pie':   render.PieRender,
              'histo': render.HistoRender,
              'line':  render.LineRender,
              'gantt': render.GanttRender,
             }

    margin = 30
    big_title_height = 40
    title_height = 50
    frame_margin = 5
    frag_title_height = 20
    frag_margin = 9
    edenwall_height = 60

    def __init__(self, title, enterprise, interval, logo):
        self.title = title
        self.enterprise = enterprise
        self.interval = interval
        self.logo = logo
        self.width, self.height = A4
        self.buf = StringIO()
        self.canvas = Canvas(self.buf, pagesize=A4)

        self.page_title = ''
        self.page_rows = []
        self.page_frags = 0
        self.page_num = 1

        # Build story.
        self.canvas.saveState()
        self.canvas.setStrokeColor(colors.RED)
        self.canvas.setLineWidth(2)
        self.canvas.roundRect(self.margin, self.edenwall_height + self.margin, self.width, self.height, 20, stroke=1, fill=0)

        self.canvas.setFillColor(colors.GREEN2)
        self.canvas.setStrokeColor(colors.GREEN1)
        self.canvas.roundRect(- self.margin, - self.margin, self.width - self.margin, self.edenwall_height + self.margin,
                              20, stroke=1, fill=1)
        # TODO do not hardcode this values.
        img = Image('/var/lib/ufwi_rpcd/edenwall.png', 1209 / (300/(self.edenwall_height-self.margin/2)), self.edenwall_height-self.margin/2)
        img.drawOn(self.canvas, self.margin, self.margin/4)

        self.canvas.restoreState()

        if self.logo:
            img = Image(StringIO(self.logo))
            img._setup_inner()
            img.drawOn(self.canvas, (self.width - self.margin)/2 - img.drawWidth/2, 2*self.height/3)

        offset = 40

        self.canvas.setFillColor(black)
        self.canvas.setFont("Helvetica-Bold", self.big_title_height)
        self.canvas.drawCentredString((self.width-self.margin)/2, self.height/3, title)
        self.canvas.setFont("Helvetica-Bold", self.frag_title_height)
        self.canvas.drawString(offset, self.height - offset, enterprise)

    def __getstate__(self):
        d = self.__dict__.copy()
        del d['canvas']
        return d

    def __setstate__(self, d):
        self.__dict__ = d
        self.canvas = Canvas(self.buf, pagesize=A4)

    def build(self):
        self.canvas.showPage()
        self.canvas.save()
        return self.buf

    def addGraph(self, title, columns, table, render):
        frags = self.page_frags
        for row, cols in enumerate(self.page_rows):
            frags -= cols
            if frags < 0:
                break

        if frags >= 0:
            self.addPage(self.page_title, self.page_rows)
            col = 0
            row = 0
            cols = self.page_rows[0]
        else:
            col = - frags - 1

        # You can read that? Not me.
        x = self.margin + self.frame_margin + (col+1) * self.frag_margin + \
            col * (self.width - 2*self.margin - 2*self.frame_margin - (col+1)*self.frag_margin) / cols
        y = self.margin + self.frame_margin + (row+1) * self.frag_margin + \
            row * (self.height - 2*self.margin - 2*self.frame_margin - self.title_height - 2*self.frag_margin) / len(self.page_rows)
        width = (self.width - 2*self.margin - 2*self.frame_margin - 2*cols*self.frag_margin) / cols
        height = (self.height - 2*self.margin - 2*self.frame_margin - self.title_height - 2*len(self.page_rows)*self.frag_margin) / len(self.page_rows)

        self.canvas.setFillColor(colors.GREEN1)
        self.canvas.roundRect(x, y, width, height, 7, stroke=0, fill=1)
        self.canvas.setFillColor(white)
        x += 1
        y += 1
        width -= 2
        height -= 2

        self.canvas.roundRect(x, y, width, height - self.frag_title_height, 7, stroke=0, fill=1)

        self.canvas.setFillColor(white)
        self.canvas.setFont("Helvetica", 3*self.frag_title_height/4)
        self.canvas.drawCentredString(x + width/ 2, y + height - 3*self.frag_title_height/4, title)

        self.page_frags += 1

        if len(table) > 0:
            klass = self.render[render]
            obj = klass(width, height - self.frag_title_height - 2*self.frame_margin, columns, table)

            r = obj.render()
            if isinstance(r, Drawing):
                renderPDF.draw(obj.render(), self.canvas, x, y + self.frame_margin)
            elif isinstance(r, Flowable):
                r.drawOn(self.canvas, x, y + height - self.frag_title_height - obj.height - self.frame_margin)

        else:
            pass
            #self.append(Paragraph(title, h2))
            #self.append(Paragraph('No data', h2))

            #self.append(KeepTogether([Paragraph(title, h2),
            #                          Paragraph('No data', h2)]))

    def addPage(self, title, rows=[1]):
        self.canvas.showPage()
        self.canvas.saveState()
        self.canvas.setLineWidth(2)
        self.canvas.setStrokeColor(colors.RED)
        self.canvas.roundRect(self.margin, self.margin,
                              self.width - self.margin*2,
                              self.height - self.margin*2,
                              20, stroke=1, fill=0)
        self.canvas.restoreState()
        self.canvas.setFillColor(colors.GREEN1)
        self.canvas.setFont("Helvetica-Bold", self.title_height/3)
        self.canvas.drawString(self.margin*2, self.height - self.margin - 4*self.title_height/5, title)
        self.canvas.setFont("Helvetica-Bold", self.title_height/3)
        self.canvas.drawRightString(self.width - self.margin*2, self.height - self.margin - 4*self.title_height/5, self.interval)
        self.page_num += 1
        self.canvas.setFont("Helvetica-Bold", 12)
        self.canvas.drawCentredString(self.width/2, 0, "Page %d" % self.page_num)

        self.page_title = title
        self.page_rows = rows
        self.page_frags = 0
Beispiel #29
0
    def render(self, outfile, font_name, font_size):
        """
        Render the binary heat map as a PDF to the file-like object or filename
        ``outfile``.  All text will be typeset in the font named ``font_name``
        at size ``font_size``.
        """
        c = Canvas(outfile)
        c.setFont(font_name, font_size)
        leftlen = max(map(c.stringWidth, self.row_labels)) + LABEL_PAD * 2
        toplen = max(map(c.stringWidth, self.column_labels)) + LABEL_PAD * 2
        miny = self.rows * font_size * 1.2
        maxx = self.columns * font_size * 1.2
        c.setPageSize(
            (leftlen + maxx + PADDING * 2, miny + toplen + PADDING * 2))
        # Set coordinates so that LL corner has coord (-leftlen-PADDING,
        # -miny-PADDING) and the origin is at the point where the borders of the
        # row & column labels meet:
        c.translate(leftlen + PADDING, miny + PADDING)

        lineheight = font_size * 1.2
        radius = lineheight / 3

        c.setFillColorRGB(*COL_BG_COLOR)
        for i in range(0, self.columns, 2):
            c.rect(
                i * lineheight,
                -miny,
                lineheight,
                miny + toplen,
                stroke=0,
                fill=1,
            )

        c.setFillColorRGB(*ROW_BG_COLOR)
        for i in range(2, self.rows + 1, 2):
            # Yes, it starts at 2, so that the positive rectangle height will
            # make it fill row 1.
            c.rect(
                -leftlen,
                -i * lineheight,
                leftlen + maxx,
                lineheight,
                stroke=0,
                fill=1,
            )

        c.setFillColorRGB(0, 0, 0)
        c.line(0, toplen, 0, -miny)
        c.line(-leftlen, 0, maxx, 0)

        for i, label in enumerate(self.row_labels):
            c.drawRightString(
                -LABEL_PAD,
                -(i + 1) * lineheight + font_size / 3,
                label,
            )

        for i, label in enumerate(self.column_labels):
            c.saveState()
            c.translate((i + 1) * lineheight, 0)
            c.rotate(90)
            c.drawString(LABEL_PAD, font_size / 3, label)
            c.restoreState()

        for row, col in self.get_indexed_pairs():
            c.circle(
                (col + 0.5) * lineheight,
                -(row + 0.5) * lineheight,
                radius,
                stroke=0,
                fill=1,
            )

        c.showPage()
        c.save()
Beispiel #30
0
    def _on_first_page(self, canvas: Canvas, doc):
        canvas.setCreator('pretix.eu')
        canvas.setTitle(pgettext('invoice', 'Invoice {num}').format(num=self.invoice.number))

        canvas.saveState()
        canvas.setFont(self.font_regular, 8)

        if self.invoice.order.testmode:
            canvas.saveState()
            canvas.setFont('OpenSansBd', 30)
            canvas.setFillColorRGB(32, 0, 0)
            canvas.drawRightString(self.pagesize[0] - 20 * mm, (297 - 100) * mm, ugettext('TEST MODE'))
            canvas.restoreState()

        for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]):
            canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, line.strip())

        textobject = canvas.beginText(25 * mm, (297 - 15) * mm)
        textobject.setFont(self.font_bold, 8)
        textobject.textLine(pgettext('invoice', 'Invoice from').upper())
        canvas.drawText(textobject)

        self._draw_invoice_from(canvas)

        textobject = canvas.beginText(25 * mm, (297 - 50) * mm)
        textobject.setFont(self.font_bold, 8)
        textobject.textLine(pgettext('invoice', 'Invoice to').upper())
        canvas.drawText(textobject)

        self._draw_invoice_to(canvas)

        textobject = canvas.beginText(125 * mm, (297 - 38) * mm)
        textobject.setFont(self.font_bold, 8)
        textobject.textLine(pgettext('invoice', 'Order code').upper())
        textobject.moveCursor(0, 5)
        textobject.setFont(self.font_regular, 10)
        textobject.textLine(self.invoice.order.full_code)
        canvas.drawText(textobject)

        textobject = canvas.beginText(125 * mm, (297 - 50) * mm)
        textobject.setFont(self.font_bold, 8)
        if self.invoice.is_cancellation:
            textobject.textLine(pgettext('invoice', 'Cancellation number').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont(self.font_regular, 10)
            textobject.textLine(self.invoice.number)
            textobject.moveCursor(0, 5)
            textobject.setFont(self.font_bold, 8)
            textobject.textLine(pgettext('invoice', 'Original invoice').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont(self.font_regular, 10)
            textobject.textLine(self.invoice.refers.number)
        else:
            textobject.textLine(pgettext('invoice', 'Invoice number').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont(self.font_regular, 10)
            textobject.textLine(self.invoice.number)
        textobject.moveCursor(0, 5)

        if self.invoice.is_cancellation:
            textobject.setFont(self.font_bold, 8)
            textobject.textLine(pgettext('invoice', 'Cancellation date').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont(self.font_regular, 10)
            textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT"))
            textobject.moveCursor(0, 5)
            textobject.setFont(self.font_bold, 8)
            textobject.textLine(pgettext('invoice', 'Original invoice date').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont(self.font_regular, 10)
            textobject.textLine(date_format(self.invoice.refers.date, "DATE_FORMAT"))
            textobject.moveCursor(0, 5)
        else:
            textobject.setFont(self.font_bold, 8)
            textobject.textLine(pgettext('invoice', 'Invoice date').upper())
            textobject.moveCursor(0, 5)
            textobject.setFont(self.font_regular, 10)
            textobject.textLine(date_format(self.invoice.date, "DATE_FORMAT"))
            textobject.moveCursor(0, 5)

        canvas.drawText(textobject)

        if self.invoice.event.settings.invoice_logo_image:
            logo_file = self.invoice.event.settings.get('invoice_logo_image', binary_file=True)
            ir = ThumbnailingImageReader(logo_file)
            try:
                ir.resize(25 * mm, 25 * mm, 300)
            except:
                logger.exception("Can not resize image")
                pass
            canvas.drawImage(ir,
                             95 * mm, (297 - 38) * mm,
                             width=25 * mm, height=25 * mm,
                             preserveAspectRatio=True, anchor='n',
                             mask='auto')

        def shorten(txt):
            txt = str(txt)
            p = Paragraph(txt.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal'])
            p_size = p.wrap(65 * mm, 50 * mm)

            while p_size[1] > 2 * self.stylesheet['Normal'].leading:
                txt = ' '.join(txt.replace('…', '').split()[:-1]) + '…'
                p = Paragraph(txt.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal'])
                p_size = p.wrap(65 * mm, 50 * mm)
            return txt

        if not self.invoice.event.has_subevents:
            if self.invoice.event.settings.show_date_to and self.invoice.event.date_to:
                p_str = (
                    shorten(self.invoice.event.name) + '\n' + pgettext('invoice', '{from_date}\nuntil {to_date}').format(
                        from_date=self.invoice.event.get_date_from_display(),
                        to_date=self.invoice.event.get_date_to_display())
                )
            else:
                p_str = (
                    shorten(self.invoice.event.name) + '\n' + self.invoice.event.get_date_from_display()
                )
        else:
            p_str = shorten(self.invoice.event.name)

        p = Paragraph(p_str.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal'])
        p.wrapOn(canvas, 65 * mm, 50 * mm)
        p_size = p.wrap(65 * mm, 50 * mm)
        p.drawOn(canvas, 125 * mm, (297 - 17) * mm - p_size[1])

        textobject = canvas.beginText(125 * mm, (297 - 15) * mm)
        textobject.setFont(self.font_bold, 8)
        textobject.textLine(pgettext('invoice', 'Event').upper())
        canvas.drawText(textobject)

        canvas.restoreState()
Beispiel #31
0
    def render(self, outfile, font_name, font_size):
        """
        Render the binary heat map as a PDF to the file-like object or filename
        ``outfile``.  All text will be typeset in the font named ``font_name``
        at size ``font_size``.
        """
        c = Canvas(outfile)
        c.setFont(font_name, font_size)
        leftlen = max(map(c.stringWidth, self.row_labels)) + LABEL_PAD * 2
        toplen  = max(map(c.stringWidth, self.column_labels)) + LABEL_PAD * 2
        miny = self.rows * font_size * 1.2
        maxx = self.columns * font_size * 1.2
        c.setPageSize((leftlen + maxx + PADDING*2, miny + toplen + PADDING*2))
        # Set coordinates so that LL corner has coord (-leftlen-PADDING,
        # -miny-PADDING) and the origin is at the point where the borders of the
        # row & column labels meet:
        c.translate(leftlen+PADDING, miny+PADDING)

        lineheight = font_size * 1.2
        radius = lineheight / 3

        c.setFillColorRGB(*COL_BG_COLOR)
        for i in range(0, self.columns, 2):
            c.rect(
                i * lineheight,
                -miny,
                lineheight,
                miny + toplen,
                stroke=0,
                fill=1,
            )

        c.setFillColorRGB(*ROW_BG_COLOR)
        for i in range(2, self.rows+1, 2):
            # Yes, it starts at 2, so that the positive rectangle height will
            # make it fill row 1.
            c.rect(
                -leftlen,
                -i * lineheight,
                leftlen + maxx,
                lineheight,
                stroke=0,
                fill=1,
            )

        c.setFillColorRGB(0, 0, 0)
        c.line(0, toplen, 0, -miny)
        c.line(-leftlen, 0, maxx, 0)

        for i, label in enumerate(self.row_labels):
            c.drawRightString(
                -LABEL_PAD,
                -(i+1) * lineheight + font_size / 3,
                label,
            )

        for i, label in enumerate(self.column_labels):
            c.saveState()
            c.translate((i+1) * lineheight, 0)
            c.rotate(90)
            c.drawString(LABEL_PAD, font_size / 3, label)
            c.restoreState()

        for row, col in self.get_indexed_pairs():
            c.circle(
                (col+0.5) * lineheight,
                -(row+0.5) * lineheight,
                radius,
                stroke=0,
                fill=1,
            )

        c.showPage()
        c.save()
Beispiel #32
0
class Reporter(object):
    def __init__(self,vapp):
        self.dataApp = vapp
        path = self.dataApp.repoPath + self.dataApp.rdataName + '.pdf'
        self.canvas = Canvas(path)
        self.page = 1

    def header(self):
        self.canvas.setFont("Helvetica", 10)  
        self.canvas.drawCentredString(4.135*inch, 10.74*inch, 'Copyright@2015 : ycroft.net')  
        self.canvas.setFont("Helvetica", 11.5)
        self.canvas.line(1*inch, 10.69*inch, 7.27*inch, 10.69*inch) 

    def footer(self):
        self.canvas.setFont("Helvetica", 11.5)
        self.canvas.line(1*inch, 1*inch, 7.27*inch, 1*inch)
        self.canvas.setFont("Helvetica", 10)  
        self.canvas.drawCentredString(4.135*inch, 0.83*inch, '- '+str(self.page)+' -')

    def cover(self,coverInfo):
        dataName = coverInfo.get('dataName','no name')
        author = coverInfo.get('author','no name')
        version = coverInfo.get('version','unknown')
        self.header()
        self.footer()
        self.canvas.setFont("Helvetica-Bold", 40)
        self.canvas.drawCentredString(4.135*inch, 7.5*inch, 'Analysis Report')
        self.canvas.setFont("Helvetica", 20)
        self.canvas.drawCentredString(4.135*inch, 6.8*inch, 'for data \'' + dataName + '\'')

        self.canvas.setFont("Helvetica", 15)
        self.canvas.drawRightString(3.935*inch, 4.4*inch, 'author:')
        self.canvas.drawRightString(3.935*inch, 3.9*inch, 'date:')
        self.canvas.drawRightString(3.935*inch, 3.4*inch, 'version:')
        self.canvas.drawString(4.335*inch, 4.4*inch, author)
        self.canvas.drawString(4.335*inch, 3.9*inch, str(datetime.now().strftime('%a, %b %d %H:%M')))
        self.canvas.drawString(4.335*inch, 3.4*inch, version)
        self.canvas.showPage()
        self.page += 1

    def body(self):
        self.header()
        self.footer()
        sdataName = self.dataApp.sdataName
        rdataName = self.dataApp.rdataName
        imgPath = './spec_data/img/'
        self.canvas.setFont("Helvetica-Bold", 15)
        self.canvas.drawString(1.25*inch, 10*inch, 'I. Modulation Factors ')
        self.canvas.setFont("Helvetica", 12)
        self.canvas.drawString(1.5*inch, 9.7*inch, 'These factors are derived from the file \''+sdataName+'\'')
        self.canvas.drawInlineImage(imgPath + sdataName + '_cs0.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch)
        self.canvas.drawInlineImage(imgPath + sdataName + '_cs1.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch)
        self.canvas.showPage()
        self.page += 1
        self.header()
        self.footer()
        self.canvas.drawInlineImage(imgPath + sdataName + '_cs2.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch)
        self.canvas.drawInlineImage(imgPath + sdataName + '_cs3.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch)
        self.canvas.showPage()
        self.page += 1
        self.header()
        self.footer()
        self.canvas.setFont("Helvetica-Bold", 15)
        self.canvas.drawString(1.25*inch, 10*inch, 'II. Measured Data & FFT ')
        self.canvas.setFont("Helvetica", 12)
        self.canvas.drawString(1.5*inch, 9.7*inch, 'The data is derived from the file \''+rdataName+'\', and each fft channel has been filtered.')
        self.canvas.drawInlineImage(imgPath + rdataName + '_rd.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch)
        self.canvas.drawInlineImage(imgPath + rdataName + '_fft.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch)
        self.canvas.showPage()
        self.page += 1
        self.header()
        self.footer()
        self.canvas.setFont("Helvetica-Bold", 15)
        self.canvas.drawString(1.25*inch, 10*inch, 'III. Modulation Signals ')
        self.canvas.setFont("Helvetica", 12)
        self.canvas.drawString(1.5*inch, 9.7*inch, 'These signals are derived by ifft on the corresponding channel.')
        self.canvas.drawInlineImage(imgPath + rdataName + '_fa0.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch)
        self.canvas.drawInlineImage(imgPath + rdataName + '_fa1.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch)
        self.canvas.showPage()
        self.page += 1
        self.header()
        self.footer()
        self.canvas.drawInlineImage(imgPath + rdataName + '_fa2.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch)
        self.canvas.drawInlineImage(imgPath + rdataName + '_fa3.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch)
        self.canvas.showPage()
        self.page += 1
        self.header()
        self.footer()
        self.canvas.setFont("Helvetica-Bold", 15)
        self.canvas.drawString(1.25*inch, 10*inch, 'IV. Stokes Vectors ')
        self.canvas.setFont("Helvetica", 12)
        self.canvas.drawString(1.5*inch, 9.7*inch, 'This can be figured out using modulation signals and modulation factors.')
        self.canvas.drawInlineImage(imgPath + rdataName + '_s0.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch)
        self.canvas.drawInlineImage(imgPath + rdataName + '_s1.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch)
        self.canvas.showPage()
        self.page += 1
        self.header()
        self.footer()
        self.canvas.drawInlineImage(imgPath + rdataName + '_s2.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch)
        self.canvas.drawInlineImage(imgPath + rdataName + '_s3.jpg',1.25*inch,1.2*inch,5.77*inch,4.33*inch)
        self.canvas.showPage()
        self.page += 1
        self.header()
        self.footer()
        self.canvas.setFont("Helvetica-Bold", 15)
        self.canvas.drawString(1.25*inch, 10*inch, 'IV. Degree of Polarization ')
        self.canvas.setFont("Helvetica", 12)
        self.canvas.drawString(1.5*inch, 9.7*inch, 'This was figured out using four Stokes vectors.')
        self.canvas.drawInlineImage(imgPath + rdataName + '_dop.jpg',1.25*inch,5.3*inch,5.77*inch,4.33*inch)
        self.canvas.showPage()
        self.page += 1
        self.header()
        self.footer()
        windows = self.dataApp.windows
        self.canvas.setFont("Helvetica-Bold", 15)
        self.canvas.drawString(1.25*inch, 10*inch, 'V. Data Analysis ')
        self.canvas.setFont("Helvetica", 12)
        self.canvas.drawString(1.5*inch, 9.7*inch, 'This was automatically generated by program.')
        self.canvas.drawString(1.5*inch, 9.0*inch, '-The number of the peaks recognized in `FFT` datagram:')
        self.canvas.drawString(2.0*inch, 8.7*inch, str(len(windows)) + ' peaks')
        self.canvas.drawString(1.5*inch, 8.4*inch, '-The range of the peaks recognized in `FFT` datagram:')
        for i in range(0,len(windows)):
            self.canvas.drawString(2.0*inch, (8.1-i*0.3)*inch, '[' + str(i)+ ']   ' +str(windows[i][0]))
            self.canvas.drawString(3.9*inch, (8.1-i*0.3)*inch, '~   ' + str(windows[i][1]))
        self.canvas.showPage()
        self.page += 1


    def gen(self):
        self.cover({
            'dataName' : self.dataApp.rdataName + '`C spec',
            'author' : 'ycroft',
            'version' : 'v0.1'
        })
        self.body()
        self.canvas.save()
    def generate(self, output_path):
        if output_path == None:
            print("no output path specified")
            return

        canvas = Canvas(output_path, pagesize=A4)
        canvas.setFont("Helvetica", 7)

        page_width, page_height = A4

        top_margin = 1.3 * cm
        side_margin = 0.4 * cm
        label_width = 4.95 * cm
        label_height = 2.9 * cm
        vertical_pitch = 3 * cm
        horizontal_pitch = 5.05 * cm

        image_width = 0.7 * label_width
        image_height = (2 / 3) * label_height

        across = 4
        down = 9

        label_x_start = side_margin
        label_y_start = page_height - top_margin - label_height

        image_x_start = label_x_start + (label_width - image_width) / 2
        image_y_start = label_y_start + (label_height * 0.25)

        sku_x_start = label_x_start + label_width * 0.04
        sku_y_start = label_y_start + label_height * 0.04 + label_height * 0.12

        product_x_start = sku_x_start
        product_y_start = label_y_start + label_height * 0.04

        size_x_start = horizontal_pitch
        size_y_start = sku_y_start

        design_x_start = size_x_start
        design_y_start = product_y_start

        season_x_start = label_width / 2 + side_margin
        season_y_start = product_y_start

        sheets_needed = math.ceil(len(self.csv_data) / 36)

        while sheets_needed >= 1:
            canvas.setFont("Helvetica", 7)
            for i in range(down):
                for j in range(across):

                    if len(self.csv_data) < 1:
                        break

                    data = self.csv_data.pop(0)

                    adjust_x = j * horizontal_pitch
                    adjust_y = i * vertical_pitch

                    # border
                    #x = label_x_start + adjust_x
                    #y = label_y_start - adjust_y
                    #canvas.rect(x, y, label_width, label_height, stroke=1, fill=0)

                    image_x = image_x_start + adjust_x
                    image_y = image_y_start - adjust_y
                    canvas.drawImage(self.createBarcode(data['barcode']),
                                     image_x,
                                     image_y,
                                     width=image_width,
                                     height=image_height,
                                     mask='auto')
                    #canvas.draw(self.createBarcode(data['barcode']), image_x, image_y, width=image_width, height=image_height, mask='auto')

                    sku_x = sku_x_start + adjust_x
                    sku_y = sku_y_start - adjust_y
                    canvas.drawString(sku_x, sku_y, data['sku'])

                    product_x = product_x_start + adjust_x
                    product_y = product_y_start - adjust_y
                    canvas.drawString(product_x, product_y, data['product'])

                    size_x = size_x_start + adjust_x
                    size_y = size_y_start - adjust_y
                    canvas.drawRightString(size_x, size_y, data['size'])

                    design_x = design_x_start + adjust_x
                    design_y = design_y_start - adjust_y
                    canvas.drawRightString(
                        design_x, design_y, data['design'][:12]
                        if len(data['design']) > 12 else data['design'])

                    season_x = season_x_start + adjust_x
                    season_y = season_y_start - adjust_y
                    canvas.drawCentredString(season_x, season_y,
                                             data['season'])

            sheets_needed -= 1
            canvas.showPage()

        canvas.save()
        print(output_path + " saved")