"""
 * @author Xiaobo Sun
 * created  on 23.06.2018
 * @copyright (C) 2018 Sogood International GmbH - all rights reserved
 * @licence
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
"""

import datetime
import json
import locale

from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, Table, TableStyle, Flowable
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch, cm
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.enums import TA_RIGHT, TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.pdfgen import canvas
from reportlab.lib.units import mm
from reportlab.graphics.barcode import createBarcodeDrawing
from reportlab.graphics.shapes import Drawing
from reportlab.graphics.barcode import eanbc, qr, usps


pdfmetrics.registerFont(TTFont('DejaVuSans', 'fonts/DejaVuSans.ttf'))

locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')

class SampleFlowable(Flowable):
    """
    Sample Flowable Usage
    Usage : elements.append(SampleFlowable())
    """

    def __init__(self):
        Flowable.__init__(self)
        self.width = 50
        self.height = 50

    def draw(self) -> None:
        """
        Draw a line
        """
        self.canv.line(0, self.height, self.width, self.height)


class NumberedCanvas(canvas.Canvas):
    """
    Page Number - Canvas Sample
    """

    def __init__(self, *args, **kwargs):
        canvas.Canvas.__init__(self, *args, **kwargs)
        self._saved_page_states = []

    def showPage(self) -> None:
        """
        Show page
        """
        self._saved_page_states.append(dict(self.__dict__))
        self._startPage()

    def save(self) -> None:
        """
        Add page info to each page (page x of y)
        """
        num_pages = len(self._saved_page_states)
        for state in self._saved_page_states:
            self.__dict__.update(state)
            self.draw_page_number(num_pages)
            canvas.Canvas.showPage(self)
        canvas.Canvas.save(self)

    def draw_page_number(self, page_count) -> None:
        """
        Draw page number
        :param page_count: page number
        """
        # Change the position of this to wherever you want the page number to be
        self.setFontSize(6)
        self.drawCentredString(100 * mm, 10 * mm,
                             "%d von %d" % (self._pageNumber, page_count))


class SogoodPrintable:
    """
    Main Class
    A4 is 210mm x 297mm, 8.27 x 11.69 inches. 1 inch is 72 points (not pixel)
    dimension 592 x 842 points
    """

    def __init__(self, buffer,
        is_sogood,
        platform_id,
        order_date,
        type,
        tax,
        customerCompany,
        customerTitle,
        customerSurname,
        customerFirstname,
        customerStreet,
        customerPostcode,
        customerCity,
        customerCountry,
        customerMail,
        customerTelephone,
        customerShippingCompany,
        customerShippingSurname,
        customerShippingFirstname,
        customerShippingStreet,
        customerShippingPostcode,
        customerShippingCity,
        customerShippingCountry,
        paymentMethod,
        paymentDetails,
        paidSum,
        paidTax,
        shippingMethod,
        shippingDatails,
        soldItems,
        comment,
        memo_ab,
        docNo,
        shippingDate,
        docDate,
        show_customer_name_in_doc,
        vat_nr,
        arbeitsort,
        customerShippingTelephone,
        dealWith):
        """
        :param buffer:
        :param is_sogood: False
        :param platform_id(new): 9876543210 : if afterbuy-id available, else goodone-order id
        :param order_date(new): "25.06.2018 09:30:00" - new
        :param type(new): 0 Angebot, 1 Auftragsbestätigung, 2 Lieferschein, 3 Rechnung
        :param tax(new): 19
        :param customerCompany: "Muster International GmbH"
        :param customerTitle(new): "Herr"
        :param customerSurname: "Müller"
        :param customerFirstname: "Thomas"
        :param customerStreet: "Hans-Kohl-Str. 27"
        :param customerPostcode: "64646"
        :param customerCity: "Heppenheim"
        :param customerCountry: "Deutschland"
        :param customerMail: "thomas.müller@muster.de"
        :param customerTelephone: "+49 151 00000000"
        :param customerShippingCompany: "Muster International GmbH"
        :param customerShippingSurname: "Müller"
        :param customerShippingFirstname: "Thomas"
        :param customerShippingStreet: "Hans-Kohl-Str. 27"
        :param customerShippingPostcode: "64646"
        :param customerShippingCity: "Heppenheim"
        :param customerShippingCountry: "Deutschland"
        :param paymentMethod: "Paypal"
        :param paymentDetails: "http://url_to_qrcode"
        :param paidSum: "289.00"
        :param paidTax(new): "50.00"
        :param shippingMethod: "DHL/DPD/EkremTranksport"
        :param shippingDatails: "28.06.2018"
        :param soldItems:
             {"items":
              [
                {
                  "ean": "4250755330211",
                  "quantity": "1",
                  "price": "310.99",
                  "comment": "ECHT GLAS DUSCHE DUSCHABTRENNUNG DUSCHKABINE AUS SICHERHEITSGLAS RAVENNA17-2",
                  "tax": "19"
                 },
                {
                  "ean": "4250755304137",
                  "quantity": "3",
                  "price": "60.99",
                  "comment": "WC SITZ TOILETTENDECKEL KLODECKEL KLOBRILLE TOILETTENSITZ SOFTCLOSE WCD376",
                  "tax": "19"
                },
                {
                  "ean": "4250755323091",
                  "quantity": "1",
                  "price": "260.99",
                  "comment": "140x200 cm Design Walk-In Duschabtrennung Bremen1 in grauem Glas mit 4-eckigem Stabilisator BRAM2 <br/>
                             Breite (cm): 140 cm <br/>
                             Stabilisator: 4 - eckig (BRAM2)",
                  "tax": "19"
                },
                {
                  "ean": "4250755323091",
                  "quantity": "2",
                  "price": "520.99",
                  "comment": "LUXUS DUSCHE DUSCHWAND DUSCHABTRENNUNG AUS ECHTGLAS VARIABEL 80-120CM BREMEN 1s",
                  "tax": "19"
                },
                {
                  "ean": "4251242935322",
                  "quantity": "1",
                  "price": "109.99",
                  "comment": "ABLAUFGARNITUR SIPHON DUSCHTASSE Ø90MM <br/> ABLAUFLOCH GERUCHVERSCHLUSS AL02",
                  "tax": "19"
                },
                {
                  "ean": "4251242935322",
                  "quantity": "1",
                  "price": "29.95",
                  "comment": "Nano-M für Duschwand Wachbecken WC & <br/> Bildet SOGOOD",
                  "tax": "19"},
                {
                  "ean": "4251242935322",
                  "quantity": "1",
                  "price": "29.95",
                  "comment": "Nano-M für Duschwand Wachbecken WC & <br/> Bildet SOGOOD",
                  "tax": "19"
                 },
                {
                  "ean": "4251242935322",
                  "quantity": "1",
                  "price": "29.95",
                  "comment": "Nano-M für Duschwand Wachbecken WC & <br/> Bildet SOGOOD",
                  "tax": "19"
                },
                {
                  "ean": "4250755323527",
                  "quantity": "1",
                  "price": "329.95",
                  "comment": "Bremen2ms 90x200 cm 10 mm (BR10703MS 90)",
                  "tax": "19"
                },
                {
                  "ean": "4250755323091",
                  "quantity": "1",
                  "price": "260.99",
                  "comment": "140x200 cm Design Walk-In Duschabtrennung Bremen1 in grauem Glas mit 4-eckigem Stabilisator BRAM2 <br/>
                            Breite (cm): 140 cm <br/>
                            Stabilisator: 4 - eckig (BRAM2)",
                  "tax": "19"
                },
                {
                  "ean": "",
                  "quantity": "1",
                  "price": "-260.99",
                  "comment": "4% Rabatt auf Ihre Bestellung",
                  "tax": "19"
                },
                {
                  "ean": "",
                  "quantity": "1",
                  "price": "-300.99",
                  "comment": "5% Rabatt auf Ihre Bestellung",
                  "tax": "19"
                }
              ]
            }
        :param comment: "testing memo..."
        """
        self._buffer = buffer
        self._type = type
        self._is_sogood = is_sogood
        self._platform_id = platform_id
        self._order_date = order_date
        self._tax = tax
        self._customer_company = customerCompany
        self._customer_title = customerTitle
        self._customer_surname = customerSurname
        self._customer_firstname = customerFirstname
        self._customer_street = customerStreet
        self._customer_postcode = customerPostcode
        self._customer_city = customerCity
        self._customer_country = customerCountry
        self._customer_mail = customerMail
        self._customer_Telephone = customerTelephone
        self._customer_shipping_company = customerShippingCompany
        self._customer_shipping_surname = customerShippingSurname
        self._customer_shipping_firstname = customerShippingFirstname
        self._customer_shipping_street = customerShippingStreet
        self._customer_shipping_postcode = customerShippingPostcode
        self._customer_shipping_city = customerShippingCity
        self._customer_shipping_country = customerShippingCountry
        self._payment_method = paymentMethod
        self._payment_details = paymentDetails
        self._payment_sum = paidSum
        self._payment_tax = paidTax
        self._shipping_method = shippingMethod
        self._shiping_details = shippingDatails
        self._sold_items = soldItems
        self._comment = comment
        self._memo_ab = memo_ab
        self._docNo = docNo
        self._shippingDate = shippingDate
        self._docDate = docDate
        self._show_customer_name_in_doc = show_customer_name_in_doc
        self._vat_nr = vat_nr
        self._arbeitsort = arbeitsort
        self._customer_shipping_Telephone = customerShippingTelephone
        self._deal_with = dealWith

    def header(self, c, doc, is_first_page) -> None:
        """
        Header on each page
        :param c: Canvas
        :param doc: SimpleDocTemplate
        """

        styles = getSampleStyleSheet()
        styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY))
        styles.add(ParagraphStyle(name='Right', alignment=TA_RIGHT))

        # FIXME: check self._is_sogood
        logo = "images/maimai.png"
        if(self._is_sogood):
            logo = "images/logo_pdf.png"
        im = Image(logo, 2.4 * inch, 0.859 * inch)
        w, h = im.wrap(doc.width, doc.bottomMargin)
        if is_first_page:
            im.drawOn(c, doc.leftMargin + 2 * mm, doc.height + doc.bottomMargin - 0.2 * inch)
        else:
            im.drawOn(c, doc.leftMargin + 2 * mm, doc.height + doc.bottomMargin)

        if is_first_page:

            # Style
            PaSt1 = ParagraphStyle(name='Normal', fontSize=9, leading=10)
            PaSt2 = ParagraphStyle(name='Normal', fontSize=9, leading=10, alignment=TA_RIGHT)

            # Val
            doc_nr_title = "Dokumenten-Nr."
            if self._type == "0":
                doc_nr_title = "Angebots-Nr.";
            elif self._type == "1":
                doc_nr_title = "Bestell-Nr.";
            elif self._type == "2":
                doc_nr_title = "Lieferschein-Nr.";
            elif self._type == "3":
                doc_nr_title = "Rechnungs-Nr.";
            
            # Vender addr in Line
            vendor_addr_inLine = """<font size="7">
            <u>Mai & Mai GmbH - Gutenbergring 1 - 63110 Rodgau</u>
            </font>
            """
            if(self._is_sogood):
                vendor_addr_inLine = """<font size="7">
                    <u>Sogood GmbH - Gutenbergring 1 - 63110 Rodgau</u>
                    </font>
                    """

            vendor_addr_inLine_p = Paragraph(vendor_addr_inLine, styles["Normal"]);
            # distance between two addrs
            empty_row_between_addrs_p = Paragraph("""<font size="9"> <br/></font>""", styles["Normal"]);
            if(len(self._customer_company) < 1):
                empty_row_between_addrs_p = Paragraph("""<font size="9"></font>""", styles["Normal"]);
            
            # address of customer
            if(self._show_customer_name_in_doc == 'Y'):
                if self._type == "2":
                    customer_addr = """<font>
                        <b>%s</b><br/>
                        %s %s<br/>
                        ( %s )<br/>
                        %s<br/>
                        %s %s<br/>
                        %s</font>
                        """ % (self._customer_shipping_company,
                            self._customer_shipping_firstname, self._customer_shipping_surname,
                            self._customer_shipping_Telephone,
                            self._customer_shipping_street,
                            self._customer_shipping_postcode, self._customer_shipping_city,
                            self._customer_shipping_country)
                else:
                    customer_addr = """<font>
                        <b>%s</b><br/>
                        %s %s<br/>
                        %s<br/>
                        %s %s<br/>
                        %s</font>
                        """ % (self._customer_company,
                            self._customer_firstname, self._customer_surname, self._customer_street,
                            self._customer_postcode, self._customer_city,
                            self._customer_country)
            else:
                if self._type == "2":
                    customer_addr = """<font>
                        <b>%s</b><br/>
                        ( %s )<br/>
                        %s<br/>
                        %s %s<br/>
                        %s</font>
                        """ % (self._customer_shipping_company,
                            self._customer_shipping_Telephone,
                            self._customer_shipping_street,
                            self._customer_shipping_postcode, self._customer_shipping_city,
                            self._customer_shipping_country)
                else:
                    customer_addr = """<font>
                        <b>%s</b><br/>
                        %s<br/>
                        %s %s<br/>
                        %s</font>
                        """ % (self._customer_company,
                            self._customer_street,
                            self._customer_postcode, self._customer_city,
                            self._customer_country)



            customer_addr_p = Paragraph(customer_addr, PaSt1)
            # FIXME: check self._is_sogood
            vendor_addr = """<font>
                          <b>Mai & Mai GmbH</b><br/>
                          Gutenbergring 1<br/>
                          63110 Rodgau<br/>
                          Tel.: +49 6106 6670592<br/>
                          www.doporro.com<br/>
                          <br/>
                          </font>
                          """
            if (self._arbeitsort == 'Showroom-Gelnhausen'):
                vendor_addr = """<font>
                          <b>Mai & Mai GmbH</b><br/>
                          Gutenbergring 1<br/>
                          63110 Rodgau<br/>
                          Tel.: +49 6106 667585<br/>
                          E-Mail: M.Oymak@doporro.de<br/>
                          www.doporro.com<br/>
                          <br/>
                          </font>
                          """

            if (self._arbeitsort == 'Showroom-Heusenstamm'):
                vendor_addr = """<font>
                          <b>Mai & Mai GmbH</b><br/>
                          Seligenstädter Grund 11<br/>
                          63150 Heusenstamm<br/>
                          Tel.: +49 6104 8023762<br/>
                          E-Mail: M.Oymak@doporro.de<br/>
                          www.doporro.com<br/>
                          <br/>
                          </font>
                          """

            if (self._arbeitsort == 'Showroom-Dietzenbach'):
                vendor_addr = """<font>
                    <b>Mai & Mai GmbH</b><br/>
                    Albert-Einstein-Str. 6<br/>
                    63128 Dietzenbach<br/>
                    Tel.: +49 6074 9146769<br/>
                    E-Mail: M.Oymak@doporro.de<br/>
                    www.doporro.com<br/>
                    <br/>
                    </font>
                    """

            if (self._deal_with == 'ersatzteil' and self._is_sogood):
                vendor_addr = """<font>
                    <b>Sogood international GmbH</b><br/>
                    Gutenbergring 1<br/>
                    63110 Rodgau<br/>
                    Tel.: +49 6106 6670592<br/>
                    www.sogood.de<br/>
                    <br/>
                    </font>
                    """


            vendor_addr_p = Paragraph(vendor_addr, PaSt2)

            if (self._vat_nr == ""):
                doc_info = """<font>
                <b>%s: </b>%s<br/>
                <b>Datum: </b>%s<br/>
                <b>Lieferdatum: </b>%s
                </font>""" % (doc_nr_title, self._docNo, self._docDate, self._shippingDate)
            else:
                doc_info = """<font>
                <b>%s: </b>%s<br/>
                <b>Datum: </b>%s<br/>
                <b>Lieferdatum: </b>%s<br/><br/>
                <b>MwSt-Nr.(VAT): </b>%s
                </font>""" % (doc_nr_title, self._docNo, self._docDate, self._shippingDate, self._vat_nr)

            doc_info_p = Paragraph(doc_info, PaSt2);

            data = [[[vendor_addr_inLine_p, empty_row_between_addrs_p, customer_addr_p], [vendor_addr_p, doc_info_p]]]
            table = Table(data, colWidths = 4 * inch, rowHeights = 100 * mm)

            style = TableStyle([
                ('FONT', (0, 0), (-1, -1), 'Helvetica'),
                ('LEFTPADDING', (0, 0), (-1, -1), 40),  # not clean solution, but works somehow
                ('RIGHTPADDING', (0, 0), (-1, -1), 40),  # not clean solution, but works somehow
                ('VALIGN', (0, 0), (-1, -1), 'TOP'),
                # TEST
                # ('GRID', (0, 0), (-1, -1), 0.5, colors.red)
            ])

            table.setStyle(style)
            w1, h1 = table.wrap(doc.width, doc.bottomMargin)
            table.drawOn(c, doc.width / 2 + doc.leftMargin - w1 / 2, doc.height + doc.bottomMargin - h - (85 * mm))

    def footer(self, c, doc) -> None:
        """
        Footer on each page
                Runs demo demonstrating usage of Spreadsheet Tables.
        :param c: Canvas
        :param doc: SimpleDocTemplate
        """

        # FIXME: check self._is_sogood
        data = [
            ["Mai & Mai GmbH", "Telefon: +49 6106 6670592", "Amtsgericht Offenbach", "Bankverbindung:", "IBAN: DE7250 040000"],
            ["Gutenbergring 1", "E-Mail: info@maimai24.de", "HRB 44229", "Commerzbank", "0413 0589 00"],
            ["63110 Rodgau", "", "Geschäftsführerin: Wei Tao".encode('utf-8'), "BLZ: 50040000", "BIC: COBADEFF004"],
            ["Deutschland", "", "", "Konto: 413058900", "USt-IdNr: DE265808049"]
        ]
        if(self._is_sogood):
            data = [
                ["Sogood International GmbH", "Telefon: +49 6106 6667585", "Amtsgericht Offenbach", "Bankverbindung:", "IBAN: DE3350 080000"],
                ["Gutenbergring 1", "E-Mail: info@sogood.de", "HRB 42229", "Commerzbank", "0635 2893 00"],
                ["63110 Rodgau", "", "Geschäftsführer: Shaoyan Huang".encode('utf-8'), "BLZ: 50080000", "BIC: DRESDEFFXXX"],
                ["Deutschland", "", "", "Konto: 635289300", "USt-IdNr: DE814341426"]
             ]

        style = TableStyle([
            ('FONT', (0, 0), (-1, -1), 'Helvetica'),
            ('FONTSIZE', (0, 0), (-1, -1), 6),
            ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
        ])

        # Configure style and word wrap
        # s = getSampleStyleSheet()
        # s = s["BodyText"]
        # s.wordWrap = 'CJK'
        # data2 = [[Paragraph(cell, s) for cell in row] for row in data]
        # t = Table(data2)
        table = Table(data, colWidths=[91.711, 116.654, 117.038, 86.339, 88.257], rowHeights=0.3 * cm)
        table.setStyle(style)

        w, h = table.wrap(doc.width, doc.bottomMargin)
        table.drawOn(c, doc.leftMargin, h)

    def header_footer_first_page(self, c, doc) -> None:
        """
        First Page
        :param c: Canvas
        :param doc: SimpleDocTemplate
        """
        # Save the state of our canvas so we can draw on it
        c.saveState()
        self.header(c, doc, True)
        self.footer(c, doc)
        # Release the canvas
        c.restoreState()

    def header_footer_later_pages(self, c, doc) -> None:
        """
        First Page
        :param c: Canvas
        :param doc: SimpleDocTemplate
        """
        # Save the state of our canvas so we can draw on it
        c.saveState()
        self.header(c, doc, False)
        self.footer(c, doc)
        # Release the canvas
        c.restoreState()

    def write_content(self, elements) -> None:
        """
        write first page content
        :param elements:
        """
        styles = getSampleStyleSheet()
        styles.add(ParagraphStyle(name='MY_Justify', alignment=TA_JUSTIFY, leading=16))
        styles.add(ParagraphStyle(name='MY_Right', alignment=TA_RIGHT))
        styles.add(ParagraphStyle(name='MY_Center', alignment=TA_CENTER))
        styles.add(ParagraphStyle(name='MY_Head', alignment=TA_CENTER, fontSize=24, fontName="Helvetica-Bold"))

        if(self._type == "2"):
            elements.append(Spacer(1, 120))
            ptext = '<font size=8>Auftrag %s am %s</font>' % (self._platform_id, self._order_date)
            elements.append(Paragraph(ptext, styles["Normal"]))
            elements.append(createBarcodeDrawing('Code128', value=self._platform_id,  height=40, width=120))

        # Val
        letter_greeting = "Sehr geehrte Damen und Herren"
        letter_text = ""
        if self._type == "0":
            letter_text = "herzlichen Dank für Ihre Anfrage.<br/>gerne unterbreiten wir Ihnen hiermit folgendes Angebot:"
        elif self._type == "1":
            letter_text = "vielen Dank für Ihre Bestellung. Wir freuen uns über Ihren Auftrag.<br/>Details entnehmen Sie bitte der folgenden Übersicht:"
        elif self._type == "2":
            letter_text = "wir bedanken uns für die gute Zusammenarbeit und liefern Ihnen wie vereinbart folgende Waren:"
        elif self._type == "3":
                letter_text = "vielen Dank für Ihre Bestellung und das uns entgegengebrachte Vertrauen.<br/>Wir berechnen Ihnen hiermit wie folgt:"

        # elements.append(Spacer(1, 60))
        # ptext = '<font size=8>Auftrag %s am %s</font>' % (self._platform_id, self._order_date)
        # elements.append(Paragraph(ptext, styles["Normal"]))
        # elements.append(createBarcodeDrawing('Code128', value='001234567890',  height=40))

        if(self._type == "2"):
            elements.append(Spacer(1, 20))
        else:
            elements.append(Spacer(1, 115))


        # FIXME: check self._type
        if self._type == '0':
            ptext = '<font size=20><b>Angebot</b></font>'
        elif self._type == '1':
            ptext = '<font size=20><b>Auftragsbestätigung</b></font>'
        elif self._type == '2':
            ptext = '<font size=20><b>Lieferschein</b></font>'
        else:
            ptext = '<font size=20><b>Rechnung</b></font>'

        elements.append(Paragraph(ptext, styles["Normal"]))

        elements.append(Spacer(1, 26))
        ptext = '<font size=10>%s,</font>' % (letter_greeting)
        elements.append(Paragraph(ptext, styles["Normal"]))

        elements.append(Spacer(1, 10))
        ptext = '<font size=10>%s</font>' % (letter_text)
        elements.append(Paragraph(ptext, styles["MY_Justify"]))

        elements.append(Spacer(1, 15))
        elements.append(self.table1())

        if(self._type != '2'):
            elements.append(Spacer(1, 20))
            elements.append(self.tableSumInfo())

        elements.append(Spacer(1, 30))
        elements.append(Paragraph("<font size=10><b>Zahlungsmethode:</b> %s</font>" % self._payment_method, styles["Normal"]))

        # Paypal QRCode Tip
        if self._payment_method == "Paypal" and self._type != '2':
            ptext = '<font size=10>Mit Paypal zahlen Sie mittels QR-Code schnell und sicher.<br/>Bitte scannen Sie den folgenden QR-Code:</font>'
            elements.append(Paragraph(ptext, styles["Normal"]))
            elements.append(Spacer(1, 10))
            # Paypal Logo
            i_p_logo = Image("images/logo_paypal.png", 2 * inch, 0.6 * inch)
            i_p_logo.hAlign = "LEFT"
            elements.append(i_p_logo)
            #elements.append(Spacer(1, 10))
            # QR-Code
            i_qr = qr.QrCodeWidget(self._payment_details)
            bounds = i_qr.getBounds()
            width = bounds[2] - bounds[0]
            height = bounds[3] - bounds[1]
            i_qr_d = Drawing(45, 120, transform=[135./width,0,0,135./height,0,0])
            i_qr_d.add(i_qr)
            elements.append(i_qr_d)
            # qr-code link
            # elements.append(Spacer(1, 5))
            # ptext = '<font size=10>Als Alternative zur Zahlung können Sie auch den folgenden Link im Computer besuchen:<br/>%s</font>' % (self._payment_details)
            # elements.append(Paragraph(ptext, styles["Normal"]))

        if self._type == '3':
            # Rechnungsbemerkung
            elements.append(Spacer(1, 20))
            ptext = '<font size=10>%s</font>' % (self._comment)
            elements.append(Paragraph(ptext, styles["Normal"]))
        elif self._type == '2':
            # Memo in Lieferschein
            elements.append(Spacer(1, 20))
            ptext = '<font size=10>%s</font>' % (self._memo_ab)
            elements.append(Paragraph(ptext, styles["Normal"]))

        elements.append(Spacer(1, 30))
        ptext = '<font size=10>Mit freundlichen Grüßen<br/>Ihr Doporro Team</font>'
        elements.append(Paragraph(ptext, styles["Normal"]))
        elements.append(Spacer(1, 10))

    @staticmethod
    def table():
        """
        Runs demo demonstrating usage of Spreadsheet Tables.
        :return: Table
        """
        pos = 0
        i = 1
        data = [
            ["Pos", "EAN", "Artikelbezeichnung", "Stammbezeichnung", "P", "A", "Preis"],
            ["%d" % (pos + i), "4251242935322", "ABLAUFGARNITUR SIPHON DUSCHTASSE Ø90MM", "ABLAUFGARNITUR AL02", "1", "1", "8,99"],
            ["%d" % (pos + 2), "4250755391915", "140x200 cm Design Walk-In Duschabtrennung Bremen1 in grauem Glas mit 4-eckigem Stabilisator BRAM2 \
                                    Breite (cm): 140 cm \
                                    Stabilisator: 4 - eckig (BRAM2)", "Bremen01VG 140 + MMBR2", "1", "1", "288,99"],
            ["%d" %(pos + 3), "", "4% Rabatt auf Ihre Bestellung", "", "1", "1", "-8,99"],
            ["%d" %(pos + 4), "", "5% Rabatt auf Ihre Bestellung", "", "1", "1", "-10,99"],
        ]


        # Configure style and word wrap
        # which overrides the table style regarding fontSize
        s = getSampleStyleSheet()
        s = s["BodyText"]
        s.wordWrap = 'CJK'
        s.fontSize = 8
        data_with_style = [[Paragraph(cell, s) for cell in row] for row in data]
        t = Table(data_with_style, colWidths=[30, 80, 160, 90, 20, 20, 50])      # whole width is 450
        style = TableStyle([
            ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black),
            ('BOX', (0, 0), (-1, -1), 0.25, colors.black),  # border of table
        ])
        t.setStyle(style)
        return t

    def table1(self):
        """
        Runs demo demonstrating usage of Spreadsheet Tables.
        :return: Table
        """
        # data = [
        #     ["Artikelbezeichnung", "Anzahl", "Preis"],
        #     ["ABLAUFGARNITUR SIPHON DUSCHTASSE Ø90MM",  "1", "8,99 Euro"],
        #     ["140x200 cm Design Walk-In Duschabtrennung Bremen1 in grauem Glas mit 4-eckigem Stabilisator BRAM2 <br/>\
        #                             Breite (cm): 140 cm <br/>\
        #                             Stabilisator: 4 - eckig (BRAM2)", "1", "288,99 Euro"],
        #     ["5% Rabatt auf Ihre Bestellung", "1", "-10,99 Euro"],
        #     ["", "", "Versandkosten: 0,00 Euro <br/> \
        #               Gesamtkosten ohne Mwst: 250,84 Euro <br/> \
        #               19% Mwst: 29,77 Euro <br/> \
        #               Gesamtkosten: 279 Euro\
        #              "],
        # ]

        data = []

        if self._type != '2':
            data.append(["Pos", "Artikelbezeichnung", "Einzelpreis", "Anzahl", "Gesamtpreis"])
        else:
            data.append(["Pos", "Artikelbezeichnung", "Anzahl"])
        
        loaded_json = json.loads(self._sold_items, strict=False)

        items_json = loaded_json["items"]
        pos_count = 1
        for x in items_json:
            row = []
            row.append(str(pos_count))
            row.append("<b>" + x["comment"] + "</b><br/>Artikelnummer: " + x["ean"].replace("42507553", "42512429"))
            #row.append(self.completeGermanPrice('{0:n}'.format(float(x["price"]))) + " EUR")
            
            if self._type != '2':
                row.append(self.formatPrice(float(x["price"])) + " EUR")
            
            row.append(x["quantity"])
            
            if self._type != '2':
                row.append(self.formatPrice(float(x["price"]) * float(x["quantity"])) + " EUR")
            
            data.append(row)
            pos_count += 1

        # FIXME: calculate the price
        # sum_1_val = "0,00"
        # sum_1 = ["", "", "<br/>Versandkosten : ", "", "<br/>" + self.completeGermanPrice(sum_1_val) + " EUR"]
        # data.append(sum_1)
        # sum_2_val = '{0:n}'.format(float(round((float(self._payment_sum)-float(self._payment_tax)), 2)))
        # sum_2 = ["", "", "Zwischensumme : ", "", self.completeGermanPrice(sum_2_val) + " EUR"]
        # data.append(sum_2)
        # sum_3_val = '{0:n}'.format(round(float(self._payment_tax),2))
        # sum_3 = ["", "", "MwSt. " + self._tax + "% : ", "", self.completeGermanPrice(sum_3_val) + " EUR"]
        # data.append(sum_3)
        # sum_4_val = '{0:n}'.format(round(float(self._payment_sum), 2))
        # sum_4 = ["", "", "Gesamtsumme : ", "", self.completeGermanPrice(sum_4_val) + " EUR"]
        # data.append(sum_4)


        # Configure style and word wrap
        # which overrides the table style regarding fontSize
        s = getSampleStyleSheet()
        s = s["BodyText"]
        s.wordWrap = 'CJK'
        s.fontSize = 8
        s.alignment = TA_LEFT
        s_right = getSampleStyleSheet()
        s_right = s_right["BodyText"]
        s_right.wordWrap = 'CJK'
        s_right.fontSize = 8
        s_right.alignment = TA_RIGHT
        s_center = getSampleStyleSheet()
        s_center = s_center["BodyText"]
        s_center.wordWrap = 'CJK'
        s_center.fontSize = 8
        s_center.alignment = TA_CENTER

        data_with_style = []
        for row in data:
            data_with_style_row = []
            for i in range(len(row)):
                if self._type != '2':
                    if i == 0:
                        data_with_style_row.append(Paragraph(row[i], s_center))
                    elif i == len(row) - 1:
                        data_with_style_row.append(Paragraph(row[i], s_right))
                    elif i == len(row) - 2:
                        data_with_style_row.append(Paragraph(row[i], s_center))
                    elif i == len(row) - 3:
                        data_with_style_row.append(Paragraph(row[i], s_right))
                    else:
                        data_with_style_row.append(Paragraph(row[i], s))
                else:
                    if i == 0 or i == 2:
                        data_with_style_row.append(Paragraph(row[i], s_center))
                    else:
                        data_with_style_row.append(Paragraph(row[i], s))

            data_with_style.append(data_with_style_row)

        if self._type != '2':
            t = Table(data_with_style, colWidths=[30, 260, 70, 60, 70])  # whole width is 500
            #t = Table(data_with_style, colWidths=[200, 50, 200])
        else:
            t = Table(data_with_style, colWidths=[50, 350, 100])
        
        style = TableStyle([
            ('VALIGN', (0, 0), (-1, -1), 'TOP'),
            # SUM SPAN
           # ('SPAN', (-3, -4), (-2, -4)),
           # ('SPAN', (-3, -3), (-2, -3)),
           # ('SPAN', (-3, -2), (-2, -2)),
           # ('SPAN', (-3, -1), (-2, -1)),
            # ALIGN
            #('ALIGN', (0, -4), (-1, -4), 'LEFT'),
            #('ALIGN', (0, -3), (-1, -3), 'LEFT'),
            #('ALIGN', (0, -2), (-1, -2), 'LEFT'),
            #('ALIGN', (0, -1), (-1, -1), 'LEFT'),
            # border bottom for positions
            ('LINEBELOW', (0, 0), (-1, -1), 0.25, colors.black),
            # border bottom for summery
           # ('LINEBELOW', (-3, -4), (-1, -2), 0.25, colors.black),
           # ('LINEBELOW', (-3, -1), (-1, -1), 1.0, colors.black),
        ])
        t.setStyle(style)
        return t

    def tableSumInfo(self):
        """
        This table show the sum info of the order
        :return: Table
        """

        data = []

        # FIXME: calculate the price
        sum_1_val = "0,00"
        sum_1 = ["", "", "Versandkosten : ", sum_1_val + " EUR"]
        data.append(sum_1)
        sum_2_val = float(self._payment_sum) - float(self._payment_tax)
        #sum_2 = ["", "", "Zwischensumme : ", self.completeGermanPrice(sum_2_val) + " EUR"]
        sum_2 = ["", "", "Zwischensumme : ", self.formatPrice(sum_2_val) + " EUR"]
        data.append(sum_2)
        #sum_3_val = '{0:n}'.format(self.roundedTo2Decimals(float(self._payment_tax)))
        #sum_3 = ["", "", "MwSt. " + self._tax + "% : ", self.completeGermanPrice(sum_3_val) + " EUR"]
        sum_3 = ["", "", "MwSt. " + self._tax + "% : ", self.formatPrice(self._payment_tax) + " EUR"]
        data.append(sum_3)
        #sum_4_val = '{0:n}'.format(self.roundedTo2Decimals(float(self._payment_sum)))
        #sum_4 = ["", "", "<b>Gesamtsumme : </b>", "<b>" + self.completeGermanPrice(sum_4_val) + " EUR</b>"]
        sum_4 = ["", "", "<b>Gesamtsumme : </b>", "<b>" + self.formatPrice(self._payment_sum) + " EUR</b>"]
        data.append(sum_4)

        # Configure style and word wrap
        # which overrides the table style regarding fontSize
        s = getSampleStyleSheet()
        s = s["BodyText"]
        s.wordWrap = 'CJK'
        s.fontSize = 8
        s.alignment = TA_LEFT
        s_right = getSampleStyleSheet()
        s_right = s_right["BodyText"]
        s_right.wordWrap = 'CJK'
        s_right.fontSize = 8
        s_right.alignment = TA_RIGHT
        s_center = getSampleStyleSheet()
        s_center = s_center["BodyText"]
        s_center.wordWrap = 'CJK'
        s_center.fontSize = 8
        s_center.alignment = TA_CENTER

        data_with_style = []
        for row in data:
            data_with_style_row = []
            for i in range(len(row)):
                if i == len(row) - 2:
                    data_with_style_row.append(Paragraph(row[i], s))
                else:
                    data_with_style_row.append(Paragraph(row[i], s_right))
            data_with_style.append(data_with_style_row)

        t = Table(data_with_style, colWidths=[150, 150, 100, 100]) # whole width is 500
        style = TableStyle([
            ('VALIGN', (0, 0), (-1, -1), 'TOP'),
            # border bottom for summery
            ('LINEBELOW', (-2, 0), (-1, -2), 0.25, colors.black),
            ('LINEBELOW', (-2, -1), (-1, -1), 1.0, colors.black),
        ])
        t.setStyle(style)
        return t

    def formatPrice(self, p):
        #return locale.currency(float(p), 'EUR')
        p_new = str('{:12,.2f}'.format(float(p)))
        p_new = p_new.replace(",", "#")
        p_new = p_new.replace(".", ",")
        p_new = p_new.replace("#", ".")
        return p_new

    def do(self):
        """
        Entry method of the class
        :rtype: BytesIO
        """
        doc = SimpleDocTemplate(self._buffer, pagesize=A4,
                                rightMargin=43, leftMargin=43,
                                topMargin=90, bottomMargin=90)
        elements = []
        self.write_content(elements)
        doc.build(elements, onFirstPage=self.header_footer_first_page, onLaterPages=self.header_footer_later_pages,
                  canvasmaker=NumberedCanvas)

        # Get the value of the BytesIO buffer and write it to the response.
        # comment the following lines if debug with __main__
        pdf = self._buffer.getvalue()
        self._buffer.close()
        return pdf
