wbs.jsf1.pdf.LottoReceiptBean.java Source code

Java tutorial

Introduction

Here is the source code for wbs.jsf1.pdf.LottoReceiptBean.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package wbs.jsf1.pdf;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.Stateless;

import com.itextpdf.io.font.FontConstants;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.color.Color;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.border.Border;
import com.itextpdf.layout.border.SolidBorder;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.HorizontalAlignment;
import com.itextpdf.layout.property.TextAlignment;
// import com.itextpdf.text.DocumentException;

import wbs.jsf1.business.KostenErmittelnLocal;
import wbs.jsf1.persistence.Adresse;
import wbs.jsf1.persistence.AdresseFacadeLocal;
import wbs.jsf1.persistence.Kunde;
import wbs.jsf1.persistence.KundeFacadeLocal;
import wbs.jsf1.persistence.Lottoschein;
import wbs.jsf1.persistence.LottoscheinFacadeLocal;
import wbs.jsf1.util.ByteLongConverter;
import wbs.jsf1.util.LottoUtil;

/**
 * Bean : Quittungserstellung als PDF
 * ==================================
 *
 * Beschreibung :
 * ==============
 *
 * Aufbau der Quittung:
 * 
 * berschrift   
 * Block mit Kundenanschrift.
 * Block mit Lottoscheinangaben.
 * Block mit Barcode 
 * Block mit Hinweisen.
 *
 */
@Stateless
public class LottoReceiptBean implements LottoReceiptBeanLocal {

    // Komponenten f. Zugriff auf Datenmodell bzw. BussinessFunktionen    
    @EJB
    private KundeFacadeLocal kundeFacade; // notw. f. Kundenanschrift 
    @EJB
    private AdresseFacadeLocal adresseFacadeLocal; // notw. f. Kundenanschrift
    @EJB
    LottoscheinFacadeLocal lottoscheinFacadeLocal; // notw. f. Infos aus Lottoschein
    @EJB
    KostenErmittelnLocal kostenErmittelnLocal; // notw. f. Ermittlung Zahlungsbetrag d. Quittung

    // Logger
    private static final Logger LOG = Logger.getLogger(LottoReceiptBean.class.getName());

    //Verzeichnisse in dem die Bilder der Quitung liegen
    private static String bildVerzeichniss = null;

    // notw. Datenobjekte f. alte Logik der Quittung
    private static final int annahmeschlussMittwoch = 18;
    private static final int annahmeschlussSamstag = 19;

    // TODO hier prfen, ob Konstanten in Konfigurationsdatei-/klasse auslagern.
    private static final String IMAGE_NAME = "lotto6aus49.png";
    // private static final String IMAGE_BACKGROUND = "BackgroundImage.png";
    private static final String IMAGE_BARCODE = "barcode.png";

    private static String imagePath;
    private static String backgroundImageimagePath;
    private static String datum = new SimpleDateFormat("ddMMyyyy").format(new Date());
    private Lottoschein lottoscheinForPdfGenerierung;

    @PostConstruct
    public void init() {

        // festlegen der Pfade zum laden der eingebundenen Bilder (Bilder 6aus49 + Hintergrundbild)
        imagePath = this.getClass().getResource(IMAGE_NAME).getPath(); // laden des Pfades fr das Lottobild
        // backgroundImageimagePath = this.getClass().getResource(IMAGE_BACKGROUND).getPath();     // laden des Pfades fr Hintergroundbild

        // imagePath = LottoReceiptBean.class.getResource(IMAGE_NAME).getPath();
        // imagePath = Thread.currentThread().getContextClassLoader().getResource(IMAGE_NAME).getPath();
    }

    /** ********************************************************************************************
     * 
     * Erstellung der Quittung als PDF
     * =============================== 
     * 
     * Aufbau der Quittung:
     * ====================
     *  
     * 1) Block f. berschrift   
     * 2) Block mit Kundenanschrift.
     * 3) Block mit Lottoscheinangaben.
     * 4) Block mit Barcode 
     * 5) Block mit Hinweisen.
     * 
     * wenn keine Quittung erstellt werden dann wird null zurckgeliefert.
     * 
     * *********************************************************************************************/

    public byte[] createPdfFrom(Lottoschein lottoschein) {

        // zuweisung auf den lottoschein, da die alte logik ber das objekt lottoscheinForPdfGenerierung Daten holt 
        this.lottoscheinForPdfGenerierung = lottoschein;

        /* ****************************************************************************
         * Datenbeschaffung f. Quittung
         * ****************************************************************************/

        // Datenbeschaffung f. Quittung bzgl. Ermittlung der Kosten (Rechnungsbetrag f. Quittung) TODO mgl. Problem Obj.
        int kostenLottoschein = this.ermittlungKosten(lottoschein);
        lottoschein.setKosten(Integer.valueOf(kostenLottoschein));

        // Datenbeschaffung f. Quittung bzgl. Kundenaddresse (notw. Bussinessobjekte)
        Kunde kunde = kundeFacade.find(lottoschein.getKundeId().getKundeId());
        Adresse adresse = null;
        if (kunde.getAdresseList().size() > 0) {
            adresse = kunde.getAdresseList().get(0);
        }

        // Datenbeschaffung f. InfoTexte (Hinweise auf dem Lottoschein)
        String aktDatum = FormatUtil.formatDatum(new Date(), FormatUtil.Formats.FORMAT_DATUM); // akt. Datum f. Andruck i. Infotexten   
        String[] anzudruckendeInfoTexte = { "Lotto das SuperDing.", "Abgegeben am <AbgabeDatum>",
                "Infos in ihrer Annahmestelle.", "Rckseite beachten." };
        anzudruckendeInfoTexte[1] = anzudruckendeInfoTexte[1].replace("<AbgabeDatum>", "" + aktDatum);

        /* ****************************************************************************
         * Erstellen der Quittung mit den ermittelten Daten (quittungsstruktur + Befllung)
         * ****************************************************************************/

        // Formularbefllung, je Block erfolgt ein Methodenaufruf zur Befllung des Blocks
        try {

            /*
             * Begrndung: Bedienen eines Pdf-Dokument-Editor mit ntzl. Operationen 
             * mit denen wir das Dokument erstellen und befllen formatieren.
             * -> siehe hierzu Aufgaben des PdfDocEditors. 
             */

            PdfDocEditor pdfDocEditor = new PdfDocEditor();

            /* ****************************************************************************
             * blockweise Erstellung d. Quittung v. oben nach unten
             * ****************************************************************************/

            // 1) Block f. berschrift   
            pdfDocEditor.writeUeberschrift("SPIELQUITTUNG");

            // 2) Block mit Kundenanschrift. -> Angaben zur Kundenanschrift (Vorname, Nachname, Strasse, Hausnummer, Ort)
            this.createKundenanschriftBlock(pdfDocEditor, kunde, adresse);
            pdfDocEditor.createTrennstrich();

            // 3) Block mit Lottoscheinangaben -> Angaben zur Ziehung (Gewinnzahlen, Superzahl, Losnummer, von, bis ..)
            this.createZiehungsblock(pdfDocEditor.getDocument(), pdfDocEditor.schriftsatzNormal,
                    pdfDocEditor.schriftsatzFett);
            pdfDocEditor.createTrennstrich();

            // 4) Block mit Barcode -> Angaben zum Barcode (Barcode, Barcodenummer)
            this.createBarcodeBlock(pdfDocEditor, lottoschein);
            pdfDocEditor.createTrennstrich();

            // 5) Block mit Hinweisen. -> Hinweistexte ( Werbung, Abgabdatum, weitere Hinweise )    
            this.createInfoBlock(pdfDocEditor, anzudruckendeInfoTexte);
            pdfDocEditor.createTrennstrich();

            /* ****************************************************************************
             * Erstellung des PdfDokumentes und Rckgabe
             * ****************************************************************************/

            // Konv. in ByteArray z.B. f. BLOB in DB oder File Speicherung + Logging
            byte[] docContent = pdfDocEditor.convertDokumentToByteArray();
            LOG.log(Level.INFO, "PDF succesfully created.");

            // Rckgabe aktuelles Document als byteArray
            return docContent;

        }

        // wenn keine Quittung erstellt werden konnte oder Fehler, dann null
        catch (IOException ex) {
            Logger.getLogger(LottoReceiptBean.class.getName()).log(Level.SEVERE, "pdf creation problem", ex);
        }
        return null;
    }

    /** ********************************************************************************************
     * Methode ermittelt aus den Teilnahme Informationen des Lotteoschein unter Nutzung 
     * der BussinessFunktion ermittleKosten (KostenermittlungLocal) den auf den Lottoschein
     * zu entrichtenden Gesamtrechnungsbetrag.
     * 
     * @param lottoschein      Lotteschein, in dem die kostenrelevanten Teilnahmen vermerkt sind.
     * 
     * @return Gesamtbetrag der Rechnung in cent. 
     * ********************************************************************************************
     */
    public int ermittlungKosten(Lottoschein lottoschein) {

        // Auslesen rel. Infos f. Aufr. BussinessFunktion (ermittle Kosten) aus Lottoschein
        Date datumKosten_1 = lottoschein.getAbgabeDatum();
        Boolean isMittwoch_1 = lottoschein.getIsMittwoch();
        Boolean isSamstag_1 = lottoschein.getIsSamstag();
        Boolean isSpiel77_1 = lottoschein.getIsSpiel77();
        Boolean isSuper6_1 = lottoschein.getIsSuper6();
        int laufzeit_1 = lottoschein.getLaufzeit();

        // Ermittlung Anzahl der Lottoscheintipps, da pro Tip eine Gebhr zu entrichten ist. 
        long[] result = ByteLongConverter.byteToLong(lottoschein.getTipps());
        int anzahlTips_1 = 0;
        ;
        if (result != null) {
            anzahlTips_1 = result.length;
        }

        // Aufruf der Bussinessfunktion f. die Kostenermittlung
        int kosten_1 = kostenErmittelnLocal.kostenErmitteln(datumKosten_1, isMittwoch_1, isSamstag_1, isSpiel77_1,
                isSuper6_1, laufzeit_1, anzahlTips_1);

        return kosten_1;
    }

    /**
     * Block f. Barcode
     * ======================== 
     * 
     * Style  : Schriftart: Normal Ausrichtung:zentriert
     * Format :       
     *             <BARCODE>
     *             <BARBILD>   
     * 
     * @param editor               -   Editor mit d. akt. Dokument bearb. wird, z.B. Quittung-Rechnung
     * @throws IOException 
     * @throws DocumentException 
     */
    private void createBarcodeBlock(PdfDocEditor editor, Lottoschein lottoschein) {

        // Style  : Schriftart: Normal Ausrichtung:zentriert
        int tabstop = 0;
        editor.setSchriftsatz(editor.SIZE_NORMAL);
        editor.setTextausrichtung(editor.AUSRICHTUNG_CENTER);

        // Andruck : Belegnummer.             
        editor.writelnText("" + lottoschein.getBelegnummer());
        try {
            // Andruck : Barcode_bild
            editor.printImage(LottoReceiptBean.IMAGE_BARCODE, 30, 80.0f);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * Block f. Kundenanschrift
     * ======================== 
     * 
     * Style  : Schriftart: Normal Ausrichtung:zentriert
     * Format :       
     *               <KUNDE.VORNAME> <KUNDE.NACHNAME>
     *               <ADRESSE.STRASSE> <ADRESSE.HAUSNUMMER>
     *               <ADRESSE.ORT>
     * 
     * @param editor               -   Editor mit dem das akt. Dokument editiert wird, z.B. Quittung-Rechnung
     * @param kunde                  -   BObj Kunde mit Vorname, Name
     * @param addresse               -   BObj Adresse mit Strasse, Hausnummer, Ort  
     * 
     * @throws MalformedURLException
     */
    private void createKundenanschriftBlock(PdfDocEditor editor, Kunde kunde, Adresse addresse)
            throws MalformedURLException {

        // Style  : Schriftart: Normal Ausrichtung:zentriert
        int tabstop = 0;
        editor.setSchriftsatz(editor.SIZE_NORMAL);
        editor.setTextausrichtung(editor.AUSRICHTUNG_CENTER);

        // Format :
        StringBuilder gesamttext = new StringBuilder();

        // hinzufgen Kundenname
        gesamttext.append("" + kunde.getVorname() + " " + kunde.getName() + "\n");

        // hinzufgen Kundenandresse             
        if (addresse != null) {
            gesamttext.append("" + addresse.getStrasse() + " " + addresse.getHausnummer() + "\n");
            gesamttext.append("" + addresse.getOrt() + "\n");
        }

        // Andruck : gesamte Kundenanschrift
        editor.writelnText("" + gesamttext.toString());

    }

    /**
     * Block f. Hinweistexte
     * ======================== 
     * 
     * Style  : Schriftart: Normal Ausrichtung:zentriert
     * Format :       
     *               <HINWEISTEXT_1>
     *               <HINWEISTEXT_2>
     *               ...
     * 
     * @param editor               -   Editor mit dem das akt. Dokument editiert wird, z.B. Quittung-Rechnung
     * @param kunde                  -   Bussinessobjekt Kunde mit Vorname, Name
     * @param addresse               -   Bussinessobjekt Adresse mit 
     * 
     * @throws MalformedURLException
     */
    private void createInfoBlock(PdfDocEditor editor, String[] infos) throws MalformedURLException {

        // Style  : Schriftart: Normal Ausrichtung:zentriert
        int tabstop = 0;
        editor.setSchriftsatz(editor.SIZE_NORMAL);
        editor.setTextausrichtung(editor.AUSRICHTUNG_CENTER);

        // Format :             
        for (String hinweis : infos) {
            editor.writelnText("" + hinweis);
        }

    }

    /**
     * Block f. Angaben zur Ziehungsteilnahme
     * ======================================= 
     * 
     * Style  : Schriftart: Normal Ausrichtung:zentriert
     * 
     * Format :       
     *   
     * 1) <Lottoschein.TIPS>
     * 2) <Superzahl>
     * 3) <Losnummer> <Super6 NEIN/JA> 
     * 4)             <Spiel77 NEIN/JA> 
     * 5)             <Spieltag> 
     * 6)             <Laufzeit>    <von>
     * 7)                         <bis>
     *               ...
     *               
     * @param document
     * @param font
     * @param bold
     * @throws MalformedURLException
     */
    private void createZiehungsblock(Document document, PdfFont font, PdfFont bold) throws MalformedURLException {

        document.add(getHeaderTable());

        // -- Lottozahlen auflisten --
        // 1) <Lottoschein.TIPS>
        // 2) <Superzahl>
        document.add(getZiehungsDatenTable(font, bold));

        // ---  Losnummern ---
        // 2) <Superzahl>
        // 3) <Losnummer> <Super6 NEIN/JA> 
        // 4)             <Spiel77 NEIN/JA> 
        document.add(getLosnummerTable(font, bold));

        // ---  Spieltage ---
        // 5)             <Spieltag> 
        document.add(getSpieltageTable(font, bold));

        // ---  Laufzeit --- 
        // 6)             <Laufzeit>    <von>
        // 7)                          <bis>
        document.add(getLaufzeitTable(font, bold));

        // --- Rechnungsbetrage d. Quittung ---
        document.add(getBetragTable(font, bold));

    }

    // Ziehuungsblock : Header
    private Table getHeaderTable() throws MalformedURLException {
        Table table = new Table(new float[] { 1 }) {
        };
        table.setWidthPercent(100);
        getHeaderImage(table);
        table.addCell(new Cell().add("").setBorder(Border.NO_BORDER));

        return table;
    }

    // Ziehuungsblock : Einfgen des LottoBildes
    private void getHeaderImage(Table table) {
        Image headerLogo;

        try {
            headerLogo = new Image(ImageDataFactory.create(imagePath)).setAutoScale(true)
                    .setBorder(Border.NO_BORDER);
            table.addCell(new Cell().add(headerLogo).setBorder(Border.NO_BORDER));
        } catch (Exception e) {
            LOG.log(Level.WARNING, "cannot find the image file for the pdf");
            table.addCell(new Cell().setBorder(Border.NO_BORDER));
        }

    }

    // Ziehuungsblock : Einfgen der abgegebenen Tips auf dem Lottoschein
    private Table getZiehungsDatenTable(PdfFont font, PdfFont bold) {
        Table table = new Table(new float[] { 1, 1, 1, 1, 1, 1, 1 }) {
        };
        table.setWidthPercent(100);

        int lineCnt = 0;
        long[] result = ByteLongConverter.byteToLong(lottoscheinForPdfGenerierung.getTipps());

        for (long l : result) {
            table.addCell(new Cell().add(new Paragraph(String.valueOf(++lineCnt) + ".").setFont(font))
                    .setBorder(Border.NO_BORDER).setWidthPercent(20));
            List<Integer> lz = LottoUtil.tippAsArrayList(l);

            for (Integer i : lz) {
                table.addCell(new Cell().add(new Paragraph(String.valueOf(i)).setFont(font))
                        .setBorder(Border.NO_BORDER).setWidthPercent(13));
            }

        }
        return table;
    }

    // Ziehuungsblock : Angabe der Lsonummer, Teilnahme an den Spielen super6/Spiel77  
    private Table getLosnummerTable(PdfFont font, PdfFont bold) {
        Table table = new Table(new float[] { 1, 1, 1 }) {
        };
        table.setWidthPercent(100);

        table.addCell(new Cell().add("").setBorder(Border.NO_BORDER));
        table.addCell(new Cell().add("").setBorder(Border.NO_BORDER));
        table.addCell(new Cell().add("").setBorder(Border.NO_BORDER));

        table.addCell(new Cell().add(new Paragraph("Superzahl").setFont(font)).setBorder(Border.NO_BORDER)
                .setWidthPercent(55));
        table.addCell(
                new Cell().add(new Paragraph("").setFont(font)).setBorder(Border.NO_BORDER).setWordSpacing(35));
        String superzahl = String.valueOf(lottoscheinForPdfGenerierung.getLosnummer());
        table.addCell(new Cell().add(new Paragraph(superzahl.substring(superzahl.length() - 1)).setFont(font))
                .setBorder(Border.NO_BORDER).setWordSpacing(10).setHorizontalAlignment(HorizontalAlignment.RIGHT));

        table.addCell(new Cell().add(new Paragraph("Losnummer").setFont(font)).setBorder(Border.NO_BORDER)
                .setWidthPercent(55));
        table.addCell(new Cell().add(new Paragraph("Super6").setFont(font)).setBorder(Border.NO_BORDER)
                .setWordSpacing(35));
        table.addCell(
                new Cell().add(new Paragraph(isGame(lottoscheinForPdfGenerierung.getIsSuper6())).setFont(font))
                        .setBorder(Border.NO_BORDER).setWordSpacing(10));

        table.addCell(new Cell()
                .add(new Paragraph(String.valueOf(lottoscheinForPdfGenerierung.getLosnummer())).setFont(font))
                .setBorder(Border.NO_BORDER).setWidthPercent(55));
        table.addCell(new Cell().add(new Paragraph("Spiel77").setFont(font)).setBorder(Border.NO_BORDER)
                .setWordSpacing(35));
        table.addCell(
                new Cell().add(new Paragraph(isGame(lottoscheinForPdfGenerierung.getIsSpiel77())).setFont(font))
                        .setBorder(Border.NO_BORDER).setWordSpacing(10));

        return table;
    }

    // Ziehuungsblock : Angabe zur Teilnahme an den Ziehungstagen (Mittwoch/Sonnabenziehung)
    private Table getSpieltageTable(PdfFont font, PdfFont bold) {
        Table table = new Table(new float[] { 1 }) {
        };
        table.addCell(new Cell().add("").setBorder(Border.NO_BORDER));
        table.addCell(new Cell()
                .add(new Paragraph(getSpieltageText(lottoscheinForPdfGenerierung.getIsMittwoch(),
                        lottoscheinForPdfGenerierung.getIsSamstag()).toString()).setFont(font))
                .setBorder(Border.NO_BORDER).setWidthPercent(55));
        return table;
    }

    // Ziehungsblock : Angabe zur Loaufzeit (Anzahl der Wochen an denen teilgenommen wird)
    private Table getLaufzeitTable(PdfFont font, PdfFont bold) {
        Table table = new Table(new float[] { 1, 1 }) {
        };
        table.addCell(new Cell().add("").setBorder(Border.NO_BORDER));
        table.addCell(new Cell().add("").setBorder(Border.NO_BORDER));

        table.addCell(new Cell().add(
                new Paragraph(getLaufzeitText(lottoscheinForPdfGenerierung.getLaufzeit()).toString()).setFont(font))
                .setBorder(Border.NO_BORDER).setWidthPercent(55));
        table.addCell(new Cell().add(
                new Paragraph("vom " + FormatUtil.formatDatum(getEndDatum(), FormatUtil.Formats.FORMAT_DATUM_YEAR))
                        .setFont(font))
                .setBorder(Border.NO_BORDER).setWidthPercent(45));

        table.addCell(
                new Cell().add(new Paragraph("").setFont(font)).setBorder(Border.NO_BORDER).setWidthPercent(55));
        table.addCell(new Cell().add(
                new Paragraph("bis " + FormatUtil.formatDatum(getEndDatum(), FormatUtil.Formats.FORMAT_DATUM_YEAR))
                        .setFont(font))
                .setBorder(Border.NO_BORDER).setWidthPercent(45));
        return table;
    }

    // Rechnungsblock : Gesamtbetrag der Rechnung, siehe Fkt. ermittlungKosten(Lottoschein)
    private Table getBetragTable(PdfFont font, PdfFont bold) {
        Table table = new Table(new float[] { 1, 1 }) {
        };
        table.addCell(new Cell().add("").setBorder(Border.NO_BORDER));
        table.addCell(new Cell().add("").setBorder(Border.NO_BORDER));

        table.addCell(new Cell().add("Betrag: ").setBorder(Border.NO_BORDER).setWidthPercent(80));

        String formatedBetrag = FormatUtil.formatBetrag(lottoscheinForPdfGenerierung.getKosten(),
                FormatUtil.Formats.FORMAT_BETRAG, FormatUtil.Formats.PATTERN_BETRAG);

        table.addCell(new Cell().add("" + formatedBetrag).setBorder(Border.NO_BORDER).setWidthPercent(20)
                .setHorizontalAlignment(HorizontalAlignment.RIGHT));
        return table;
    }

    /**
     * TODO Zuerst prfen, ob diese Function nach LottoDatumUtil verlagern kann!
     * 
     * @return
     */
    // TODO: Schlauer machen
    /*
     * Ermittelt das letzte Spieldatum. Problematik: Um den tatschlich letzten
     * Ziehungstag zu errechnen, kann man nicht einfach 2 Wochen zum Abgabedatum
     * dazu rechnen. Reiche ich beispielsweise am Dienstag 20.03. den Lottoschein
     * ein und gebe 2 Wochen Laufzeit an, spiele aber nur Mittwochslotto, dann wrde
     * bei einer Aufrechnung von 2 Wochen der letzte Samstag mit eingeschlossen und
     * somit angezeigt werden, obwohl ich nur Mittwochslotto spiel. Daher muss
     * geprft werden, welche Tage (Mi oder Sa) gespielt werden, um diese dann von
     * meinen Zhlern abzuziehen. Wenn 0 erreicht wurde, muss die Schleife beendet
     * werden. Das dann ermittelte Datum ist der letzte tatschlich Ziehungstag, an
     * dem man teilnimmt.
     */
    private Date getEndDatum() {
        int wochenlaufzeit = lottoscheinForPdfGenerierung.getLaufzeit();
        int tage = wochenlaufzeit * 7;
        Date datumStart = lottoscheinForPdfGenerierung.getAbgabeDatum();

        int m = wochenlaufzeit;
        int s = wochenlaufzeit;

        Calendar curr = Calendar.getInstance();
        curr.get(Calendar.HOUR_OF_DAY);

        Calendar cal = Calendar.getInstance();
        cal.setTime(datumStart);

        if (cal.get(Calendar.DAY_OF_WEEK) == 4 & curr.get(Calendar.HOUR_OF_DAY) > annahmeschlussMittwoch) {
            cal.add(Calendar.DATE, 1);
        }

        if (cal.get(Calendar.DAY_OF_WEEK) == 7 & curr.get(Calendar.HOUR_OF_DAY) > annahmeschlussSamstag) {
            cal.add(Calendar.DATE, 1);
        }

        for (int i = 0; i < tage; i++) {
            cal.add(Calendar.DATE, 1);
            if (cal.get(Calendar.DAY_OF_WEEK) == 4) {
                m--;
            }
            if (cal.get(Calendar.DAY_OF_WEEK) == 7) {
                s--;
            }
            if (lottoscheinForPdfGenerierung.getIsMittwoch() & lottoscheinForPdfGenerierung.getIsSamstag()) {
                if (m == 0 & s == 0) {
                    break;
                }
            } else {
                if (lottoscheinForPdfGenerierung.getIsMittwoch()) {
                    if (m == 0) {
                        break;
                    }
                }
                if (lottoscheinForPdfGenerierung.getIsSamstag()) {
                    if (s == 0) {
                        break;
                    }
                }
            }
        }

        return cal.getTime();
    }

    private StringBuilder getLaufzeitText(int wochen) {
        StringBuilder laufzeit = new StringBuilder();
        laufzeit.append("Laufzeit: " + wochen + " Woche");
        if (wochen > 1) {
            laufzeit.append("n");
        }
        return laufzeit;
    }

    private StringBuilder getSpieltageText(boolean isM, boolean isS) {
        StringBuilder spieltage = new StringBuilder();
        spieltage.append("Spieltag");
        if (isM & isS) {
            spieltage.append("e");
        }
        if (isM) {
            spieltage.append(" Mittwoch ");
        }
        if (isM & isS) {
            spieltage.append("und");
        }
        if (isS) {
            spieltage.append(" Samstag");
        }
        return spieltage;
    }

    private String isGame(boolean check) {
        return check ? "JA" : "NEIN";
    }

    /*********************************************************************************************
     * 
     * PdfDocEditor
     * ============
     * 
     * Aufgabe d. PdfDocEditor ist die Bearbeitung eines Pdf-Dokumentes mittels vordefinierter
     * ntzlich Manipulationsoperationen zur Erstellung der Dokumentstruktur und der Dokumentbefllung.
     * 
     * Hintergrund :
     * --------------
     * 
     * Werden standardisiert gleichartige Dinge erzeugt, dann sollte man sich standardoperationen
     * definieren, um ein einheitliches Layout zu erzwingen.
     * 
     * Bei der nachfolgenden Quittung handelt es sich um Formular das aus Seiten/Blcken/Feldern
     * besteht, die stets in einer gleichen Art und Weise bearbeitet werden sollten. 
     * Um so etwas zu erzielen sollte man sich einen entsprechende Editor als Wrapper anlegen,
     * ber den die einzubindenden Editoren (z.B. PdfCancace fr die SeitenEdition usw. bedient werden)
     * 
     * bei dem nachfolgenden Entwicklungsstand wurden zunchst folgende Operationen erkannt:
     * 
     * 1) erzeugen eines Dokumentes 
     * 2) Trennstrich einfgen
     * 3) Text zentriert mit einem Font schreiben
     * 4) Bild einfgen.
     * 
     */
    public class PdfDocEditor {

        /* ******************************************************************************
         * Formatierungen/Schriftgren
         * =====================================
         *  Hier sind leider keine statischen Konstanten nutztbar, siehe OCA nestedKasses 
         *  -> Compilerfehler
         * ******************************************************************************/

        public String AUSRICHTUNG_CENTER = "AUSRICHTUNG_CENTER";
        public String AUSRICHTUNG_RIGHT = "AUSRICHTUNG_RIGHT";
        public String AUSRICHTUNG_LEFT = "AUSRICHTUNG_LEFT";

        public String SIZE_SMALL = "SIZE_SMALL";
        public String SIZE_NORMAL = "SIZE_NORMAL";
        public String SIZE_FETT = "SIZE_FETT";

        // Dokument + Bytestream
        ByteArrayOutputStream pdfStream = new ByteArrayOutputStream();
        PdfWriter writer = null;
        PdfDocument pdf = null;
        Document bearbeitungsDokument = null;

        // Auswahl der Schriftstze 
        PdfFont schriftsatzNormal = null;
        PdfFont schriftsatzFett = null;

        // 

        // Editierobjekte, die whrend des Prozesses der Dokumentbearbeitung bentigt werden
        Table table = null;
        int tabstop = 0;

        String textausrichtung = this.AUSRICHTUNG_LEFT;
        String schriftsatz = this.SIZE_NORMAL;

        // Anlegen eines Editor + leeres Dokument erzeugen
        public PdfDocEditor() throws IOException {
            this.initalizeFonts();
            this.createDocument();
        }

        /**
         * Initialisieren der Schriftstze. Z.B: berschriften und normaler Texte
         * @throws IOException
         */
        public void initalizeFonts() throws IOException {

            // Schriftstze initialisieren 
            this.schriftsatzNormal = PdfFontFactory.createFont(FontConstants.HELVETICA);
            this.schriftsatzFett = PdfFontFactory.createFont(FontConstants.HELVETICA_BOLD);

        }

        /**
         * Anlegen eines leeren PDF-Dokumentes
         * @throws MalformedURLException 
         */
        public void createDocument() throws MalformedURLException {

            // Notwendige Objekte i. Zshg mit einem Pdf Dokument
            this.pdfStream = new ByteArrayOutputStream();
            this.writer = new PdfWriter(pdfStream);
            this.pdf = new PdfDocument(writer);

            // Seitengre des Dokuments
            PageSize pageSize = new PageSize(PageSize.A6);

            // Dokumenteinrichten und Seitenabstnde festlegen
            bearbeitungsDokument = new Document(pdf, pageSize);

            // hinzufgen des Hintergrundbildes auf der ersten seite
            PdfCanvas canvas = new PdfCanvas(this.pdf.addNewPage());
            // Image bgImage = this.loadImage(LottoReceiptBean.IMAGE_BACKGROUND);
            // canvas.addImage(ImageDataFactory.create(IMAGE_BACKGROUND), pageSize, false);   

            // Seitenrnder
            bearbeitungsDokument.setMargins(20, 20, 40, 20);
            bearbeitungsDokument.setBorderLeft(new SolidBorder(Color.YELLOW, 36));
            bearbeitungsDokument.setBorderRight(new SolidBorder(Color.YELLOW, 36));

            // setzen des aktuellen Dokumentes zur Bearbeitung
            this.bearbeitungsDokument = bearbeitungsDokument;
        }

        /* *********************************************************************
         *  GET / SET - METHODEN
         * *********************************************************************/

        public Document getDocument() {
            return bearbeitungsDokument;
        }

        public void setDocument(Document document) {
            this.bearbeitungsDokument = document;
        }

        // setzen des Tabstops (Einrckung von Text als abstand vom linken Rand in prozent)
        public void setTabstop(int tab) {
            this.tabstop = tab;
        }

        public PdfFont getSchriftsatzNormal() {
            return schriftsatzNormal;
        }

        public void setSchriftsatzNormal(PdfFont schriftsatzNormal) {
            this.schriftsatzNormal = schriftsatzNormal;
        }

        public PdfFont getSchriftsatzFett() {
            return schriftsatzFett;
        }

        public void setSchriftsatzFett(PdfFont schriftsatzFett) {
            this.schriftsatzFett = schriftsatzFett;
        }

        /* *********************************************************************
         *  Edit - METHODEN
         * *********************************************************************/

        // setzen der aktuellen textausrichtung [z.B. AUSRICHTUNG_CENTER]
        public void setTextausrichtung(String textausrichtung) {
            this.textausrichtung = textausrichtung;
        }

        // setzen der Schriftart [z.B. SIZE_SMALL]
        public void setSchriftsatz(String schriftsatz) {
            this.schriftsatz = schriftsatz;
        }

        // Editieroperation (Anlegen von Ausgabetabellen): z.B. fr Textzelle, da alle Textausgabe ber Tabellenzellern erfolgen. 
        public void createTable(int rows, int columns, boolean isBorder) {

            // Anzahl der Zellen einer zeile in der Tabelle, (wichtig fr Formatierung) 
            float[] array = new float[columns];
            for (int i = 0; i < columns; i++) {
                array[i] = 1;
            }

            // 
            table = new Table(array);
            table.setWidthPercent(100);

            if (isBorder) {
                table.setBorderRight(new SolidBorder(Color.RED, 10));
            }
        }

        // Editieroperation ( anl. Trennstrich zum Trennen zwischen Blcken ): ----- 
        public void createTrennstrich() {

            int columns = 1;
            float[] array = new float[columns];
            for (int i = 0; i < columns; i++) {
                array[i] = 1;
            }
            table = new Table(array);
            table.setWidthPercent(100);

            table.setBorderBottom(new SolidBorder(Color.BLACK, 5));
            this.addTableToDokument();
        }

        /* *********************************************************************
         *  Mehtoden zum Bearbeiten des Dokumentes
         * *********************************************************************/

        public void printImage(String path, int zellaufteilung, float verticalScale) throws MalformedURLException {

            // tabelle mit drei zellen anlegen
            this.createTable(1, 3, false);

            // die erste zellen ist horizontalScale % derseitenbreite lang
            table.addCell(new Cell().add(new Paragraph("").setFont(this.schriftsatzNormal))
                    .setBorder(Border.NO_BORDER).setWidthPercent(zellaufteilung));

            Image image = this.loadImage(path);
            image = image.scale(verticalScale, verticalScale);

            // mittlere zelle hat 100-2*horizontalScale % breit
            Cell cell = new Cell().add(image);
            cell.setWidthPercent(100 - 2 * zellaufteilung);
            table.addCell(cell);

            // die letzte zelle ist horizontalScale % derseitenbreite lang
            table.addCell(new Cell().add(new Paragraph("").setFont(this.schriftsatzNormal))
                    .setBorder(Border.NO_BORDER).setWidthPercent(zellaufteilung));
            this.addTableToDokument();
        }

        // Methode zum laden eines Bildes
        public Image loadImage(String path) throws MalformedURLException {
            String imagePath = this.getClass().getResource(path).getPath();
            Image image = new Image(ImageDataFactory.create(imagePath)).setAutoScale(true)
                    .setBorder(Border.NO_BORDER);
            return image;
        }

        // Editieroperation (formatierten Textausgabe mit schriftsatz und ausrichtung ): 
        public void writeFormatedTextToCell(int width, String text, String font, String ausrichtung) {
            if (text != null) {
                Cell cell = new Cell().add(text);
                cell.setFont(this.schriftsatzNormal);
                this.formatCell(cell, width, font, ausrichtung);
                table.addCell(cell);
            }
        }

        // Editieroperation (Tabellenzelle): 
        public void formatCell(Cell cell, int width, String font, String ausrichtung) {

            cell.setBorder(Border.NO_BORDER).setWidthPercent(width);

            // Zelle entsprechend ausrichtung formatieren
            switch (ausrichtung) {
            case "AUSRICHTUNG_CENTER":
                cell.setTextAlignment(TextAlignment.CENTER).setBorder(Border.NO_BORDER);
                break;
            case "AUSRICHTUNG_RIGHT":
                cell.setTextAlignment(TextAlignment.RIGHT).setBorder(Border.NO_BORDER);
                break;
            case "AUSRICHTUNG_LEFT":
                cell.setTextAlignment(TextAlignment.LEFT).setBorder(Border.NO_BORDER);
                break;
            }

            // Zelle entsprechend Font formatieren, hier sind im moment die Schriftgren Hardcoded
            switch (font) {
            case "SIZE_SMALL":
                cell.setFont(this.schriftsatzNormal);
                cell.setFontSize(5.0f);
                break;
            case "SIZE_NORMAL":
                cell.setFont(this.schriftsatzNormal);
                cell.setFontSize(10.0f);
                break;
            case "SIZE_FETT":
                cell.setFont(this.schriftsatzFett);
                cell.setFontSize(20.0f);
                break;
            }

        }

        // Editieroperation (Ausgabe einer berschrift): Nutzung z.B. immer vor neuen Blcken als Kapitelberschrift
        public void writeUeberschrift(String ueberschrift) throws MalformedURLException {
            this.writelnText(ueberschrift, this.SIZE_FETT, this.AUSRICHTUNG_CENTER);
        }

        // Editieroperation (Ausgabe einer Textzeile): mit rechter Balkenmarkierung 
        public void writelnText(String text, boolean border) {

            // anlegen von zwei zellen
            createTable(1, 2, border);

            // erste zelle ist fr "zeilenvorschub" also Einrckung
            table.addCell(new Cell().add(new Paragraph("").setFont(this.schriftsatzNormal))
                    .setBorder(Border.NO_BORDER).setWidthPercent(this.tabstop));

            // in die zweite Zelle schreiben wir den Text
            this.writeFormatedTextToCell(100 - this.tabstop, text, this.schriftsatz, this.textausrichtung);

            // tabelle abschlieen
            addTableToDokument();
        }

        // Editieroperation (Ausgabe einer Textzeile):       
        public void writelnText(String text) {
            this.writelnText(text, false);
        }

        // Editieroperation (Ausgabe einer Textzeile): unter Angabe der Schriftart (Fett/Normal) und der Ausrichtung(Zentriert, rechts,links)
        public void writelnText(String text, String font, String ausrichtung) {

            // anlegen von zwei zellen
            createTable(1, 2, false);

            // erste zelle ist fr "zeilenvorschub" also Einrckung
            table.addCell(new Cell().add(new Paragraph("").setFont(this.schriftsatzNormal))
                    .setBorder(Border.NO_BORDER).setWidthPercent(this.tabstop));

            // in die zweite Zelle schreiben wir den Text
            this.writeFormatedTextToCell(100 - this.tabstop, text, font, ausrichtung);

            // tabelle abschlieen
            addTableToDokument();
        }

        // die editierte Tabelle wird zum Dokument hinzugefgt
        public void addTableToDokument() {
            // TODO type. FontProvider and FontSet are empty. Cannot resolve font with string value.
            if (table != null) {
                this.bearbeitungsDokument.add(table);
            }
        }

        // Konvertierung des Dokumentes in ein ByteArray
        public byte[] convertDokumentToByteArray() {
            this.bearbeitungsDokument.close();
            return pdfStream.toByteArray();
        }

    }

}

/*
 * ANHANG
 * =======
 * 
 * 
 * 
 * Literatur:
 * ===========
 * 
 * [A. Miller,1998] "about the art of programming"
 * 
 */