de.katho.kBorrow.controller.NewLendingController.java Source code

Java tutorial

Introduction

Here is the source code for de.katho.kBorrow.controller.NewLendingController.java

Source

/*
 * Copyright (C) 2015  Pascal Knig
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package de.katho.kBorrow.controller;

import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

import de.katho.kBorrow.Settings;
import de.katho.kBorrow.Util;
import de.katho.kBorrow.data.KArticleModel;
import de.katho.kBorrow.data.KLenderModel;
import de.katho.kBorrow.data.KLendingModel;
import de.katho.kBorrow.data.KUserModel;
import de.katho.kBorrow.data.objects.KArticle;
import de.katho.kBorrow.data.objects.KLender;
import de.katho.kBorrow.data.objects.KLending;
import de.katho.kBorrow.data.objects.KUser;
import de.katho.kBorrow.interfaces.DbConnector;
import de.katho.kBorrow.interfaces.KDataModel;

/**
 * NewLendingController fhrt smtliche Datenbankoperationen aus, die von {@link de.katho.kBorrow.gui.NewLendingPanel} angestoen werden.
 */
public class NewLendingController {

    /** Referenz auf die Datenbank */
    private DbConnector dbCon;

    /** Referenz auf KUserModel, wird bentigt um Tabellen und Listen zu aktualisieren. */
    private KUserModel kUserModel;

    /** Referenz auf KLenderModel, wird bentigt um Tabellen und Listen zu aktualisieren. */
    private KLenderModel kLenderModel;

    /** Referenz auf KArticleModel, wird bentigt um Tabellen und Listen zu aktualisieren. */
    private KArticleModel kArticleModel;

    /** Referenz auf KLendingModel, wird bentigt um Tabellen und Listen zu aktualisieren. */
    private KLendingModel kLendingModel;

    /** Referenz auf die Settings, wird bentigt, um Zugriff auf das Programmverzeichnis im Benutzerprofil zu haben. */
    private Settings settings;

    /**
     * Erzeugt eine neue Instanz des NewLendingController und setzt alle bentigten Referenzen.
     * 
     * @param pDbCon      Referenz auf die Datenbank.
     * @param models      HashMap mit den KDataModels.
     * @param pSettings      Referenz auf die Settings.
     */
    public NewLendingController(DbConnector pDbCon, HashMap<String, KDataModel> models, final Settings pSettings) {
        dbCon = pDbCon;
        kUserModel = (KUserModel) models.get("kusermodel");
        kLenderModel = (KLenderModel) models.get("klendermodel");
        kArticleModel = (KArticleModel) models.get("karticlemodel");
        kLendingModel = (KLendingModel) models.get("klendingmodel");
        settings = pSettings;
    }

    /**
     * Erzeugt eine neue Ausleihe.
     * 
     * <p>Gibt je nach Bearbeitungsergebnis einen anderen Statuscode aus:</p>
     * 
     * <ul>
     * <li>0: Erfolgreich gespeichert</li>
     * <li>1: SQL-Fehler</li>
     * <li>2: Notwendige Daten sind leer (Art-ID, Start-Date, Est. End Date)</li>
     * <li>3: Das Rckgabedatum ist frher oder gleich dem Ausleihdatum</li>
     * <li>4: Die gegebene Kombination aus Lender-Name, -Surname und -Studentnumer existiert mehrmals in der Datenbank. Das darf nicht sein und wird daher einen Fehler!</li>
     * <li>5: Matrikelnummer muss eine Zahl sein!</li>
     * </ul>
     * 
     * @param pArtId      Artikel-ID des Artikels, der verliehen wird (darf nicht -1 sein).
     * @param pLName      Vorname des Ausleihers (darf nicht leer sein).
     * @param pLSurname      Nachname des Ausleihers (darf nicht leer sein).
     * @param pLSN         Matrikelnummer des Ausleihers (muss numerisch sein).
     * @param pStartDate   Startdatum der Ausleihe (darf nicht leer sein).
     * @param pEstEndDate   Voraussichtliches Rckgabedatum (darf weder 'null' sein, noch in der Vergagenheit liegen).
     * @param pUsername      Username des Ausleihenden.
     * 
     * @return Statuscode als Int.
     * @throws Exception   ???
     */
    public int newLending(int pArtId, String pLName, String pLSurname, String pLSN, String pStartDate,
            Date pEstEndDate, String pUsername) throws Exception {
        if (pArtId == -1 || pStartDate.isEmpty() || pEstEndDate == null || pLName.isEmpty() || pLSurname.isEmpty()
                || pUsername.isEmpty())
            return 2;
        if (pEstEndDate.before(new Date()))
            return 3;
        if (!pLSN.matches("[0-9]+"))
            return 5;

        ArrayList<KLender> lenders = kLenderModel.getLenders(pLName, pLSurname, pLSN);
        if (lenders.size() == 0) {
            int result = dbCon.createNewLender(pLName, pLSurname, pLSN);

            if (result == 0) {
                kLenderModel.updateModel();

                return newLending(pArtId, pLName, pLSurname, pLSN, pStartDate, pEstEndDate, pUsername);
            } else
                return result;
        } else if (lenders.size() == 1) {
            KLender lender = lenders.get(0);
            int uId = kUserModel.getIdByFullname(pUsername);
            DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");

            int[] result = dbCon.createNewLending(pArtId, uId, lender.getId(), pStartDate,
                    dateFormat.format(pEstEndDate));

            if (result[0] == 0) {
                kArticleModel.updateModel();
                kLendingModel.updateModel();
                createPdfFile(result[1]);

                return result[0];
            } else
                return result[0];
        }
        return 4;
    }

    /**
     * Erzeugt ein PDF-File mit allen relevanten Daten zur als Parameter bergebenen Lending-ID.
     * 
     * @param pLendingId   ID der Ausleihe, fr die ein PDF erzeugt werden soll.
     * @throws Exception   Wenn Probleme beim Erstellen der Datei auftreten.
     */
    private void createPdfFile(int pLendingId) throws Exception {
        KLending lending = kLendingModel.getElement(pLendingId);
        KArticle article = kArticleModel.getElement(lending.getArticleId());
        KUser user = kUserModel.getElement(lending.getUserId());
        KLender lender = kLenderModel.getElement(lending.getLenderId());

        PDDocument doc = new PDDocument();
        PDPage page = new PDPage(PDPage.PAGE_SIZE_A4);
        PDRectangle rect = page.getMediaBox();
        doc.addPage(page);

        PDFont fontNormal = PDType1Font.HELVETICA;
        PDFont fontBold = PDType1Font.HELVETICA_BOLD;

        String[] text = { "Artikel: ", "Verliehen von: ", "Ausgeliehen an: ", "Start der Ausleihe: ",
                "Voraussichtliche Rckgabe: " };
        String[] vars = { article.getName(), user.getName() + " " + user.getSurname(),
                lender.getName() + " " + lender.getSurname() + " (" + lender.getStudentnumber() + ")",
                lending.getStartDate(), lending.getExpectedEndDate() };
        try {
            File file = createRandomPdf();

            PDPageContentStream cos = new PDPageContentStream(doc, page);

            cos.beginText();
            cos.moveTextPositionByAmount(100, rect.getHeight() - 100);
            cos.setFont(fontBold, 16);
            cos.drawString("Ausleihe #" + lending.getId());
            cos.endText();

            int i = 0;

            while (i < text.length) {
                cos.beginText();
                cos.moveTextPositionByAmount(100, rect.getHeight() - 25 * (i + 2) - 100);
                cos.setFont(fontBold, 12);
                cos.drawString(text[i]);
                cos.moveTextPositionByAmount(rect.getWidth() / 2 - 100, 0);
                cos.setFont(fontNormal, 12);
                cos.drawString(vars[i]);
                cos.endText();
                i++;
            }

            i = i + 2;
            cos.setLineWidth(1);
            cos.addLine(100, rect.getHeight() - 25 * (i + 2) - 100, 300, rect.getHeight() - 25 * (i + 2) - 100);
            cos.closeAndStroke();

            i++;

            cos.beginText();
            cos.moveTextPositionByAmount(100, rect.getHeight() - 25 * (i + 2) - 100);
            cos.setFont(fontNormal, 12);
            cos.drawString("Unterschrift " + lender.getName() + " " + lender.getSurname());
            cos.endText();

            cos.close();
            doc.save(file);
            doc.close();

            if (Desktop.isDesktopSupported()) {
                Desktop desktop = Desktop.getDesktop();
                if (desktop.isSupported(Desktop.Action.OPEN)) {
                    desktop.open(file);
                }
            }
        } catch (IOException | COSVisitorException e) {
            throw new Exception("Problem bei der Erstellung der PDF-Datei.", e);
        }
    }

    /**
     * Erzeugt ein PDF-File mit zuflligem Dateinamen.
     * 
     * @return   Gibt eine Referenz auf ein File-Objekt zurck.
     * @throws IOException   Wenn Probleme bei der Erstellung der Datei auftreten.
     */
    private File createRandomPdf() throws IOException {
        File dir = new File(settings.getSettingsDir() + "/tmp");
        File file = new File(settings.getSettingsDir() + "/tmp/" + Util.generateRandomString(8) + ".pdf");
        if (!dir.isDirectory())
            dir.mkdir();
        if (!file.isFile())
            file.createNewFile();
        else {
            file.delete();
            file.createNewFile();
        }

        return file;
    }
}