fi.riista.feature.permit.invoice.pdf.PermitHarvestInvoicePdfBuilder.java Source code

Java tutorial

Introduction

Here is the source code for fi.riista.feature.permit.invoice.pdf.PermitHarvestInvoicePdfBuilder.java

Source

package fi.riista.feature.permit.invoice.pdf;

import com.google.common.base.Joiner;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDTextField;
import org.springframework.core.io.ClassPathResource;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;

class PermitHarvestInvoicePdfBuilder {
    private static final ClassPathResource PDF_TEMPLATE = new ClassPathResource("tilisiirtolomake-bottom.pdf");

    static byte[] getPdf(final PermitHarvestInvoicePdfModel model) throws IOException {
        try (final InputStream is = PDF_TEMPLATE.getInputStream();
                final PDDocument pdfTemplate = PDDocument.load(is)) {

            return new PermitHarvestInvoicePdfBuilder(pdfTemplate, model).build();
        }
    }

    private final PDDocument pdfDocument;
    private final PDPage pdfPage;
    private final PDAcroForm acroForm;
    private final PermitHarvestInvoicePdfModel model;

    private PermitHarvestInvoicePdfBuilder(final PDDocument pdfDocument, final PermitHarvestInvoicePdfModel model) {
        this.pdfDocument = Objects.requireNonNull(pdfDocument);
        this.pdfPage = Objects.requireNonNull(pdfDocument.getPage(0));
        this.acroForm = Objects.requireNonNull(pdfDocument.getDocumentCatalog().getAcroForm());
        this.model = Objects.requireNonNull(model);
    }

    private String i18n(final String finnish, final String swedish) {
        return model.getLocalisedString(finnish, swedish);
    }

    private void textField(final String fieldName, final String value) throws IOException {
        final PDField field = acroForm.getField(fieldName);

        if (field instanceof PDTextField) {
            final PDTextField textField = (PDTextField) field;
            textField.setValue(value);
            textField.setReadOnly(true);
        } else {
            throw new IllegalArgumentException("No such field " + fieldName);
        }
    }

    private void addInvoiceSender(final InvoicePdfWriter writer) throws IOException {
        writer.topOffsetMm(13).marginLeftMm(20).italicFont().writeLine("Lhettj / Avsndare").normalFont();

        for (final String line : model.getInvoiceRecipient().formatAsLines()) {
            writer.writeLine(line);
        }
    }

    private void addInvoiceReceiver(final InvoicePdfWriter writer) throws IOException {
        writer.topOffsetMm(40).marginLeftMm(20).italicFont().writeLine("Vastaanottaja / Mottagare").boldFont()
                .writeLine(i18n("Suomen riistakeskus, lupahallintokirjaamo",
                        "Finlands Viltcentral /Tillstndsfrvaltningens registratur"))
                .writeLine(i18n("Kuralankatu 2 ", "Kuralagatan 2")).writeLine(i18n("20540 Turku", "205040 bo"));
    }

    private void addInvoiceHeader(final InvoicePdfWriter writer) throws IOException {
        writer.topOffsetMm(13).marginLeftRelative(65).normalFont().writeLine(i18n("LASKU", "FAKTURA"))
                .writeEmptyLine().writeLine(model.getInvoiceDateString());

        writer.topOffsetMm(45).marginLeftRelative(65).normalFont()
                .writeLine(i18n("Ptsnumero", "Beslutnummer")).writeLine(i18n("Asiakasnumero", "Kundnummer"));

        writer.topOffsetMm(45).marginLeftRelative(80).normalFont().writeLine(model.getPermitNumber())
                .writeLine(model.getInvoiceRecipient().getCustomerNumber());
    }

    private void addInvoiceText(final InvoicePdfWriter writer) throws IOException {

        writer.topOffsetMm(70).marginLeftMm(20).font(PDType1Font.HELVETICA_BOLD, 12)
                .writeLine(model.getInvoiceTitle()).addVerticalSpaceMm(2)

                .font(PDType1Font.HELVETICA_BOLD, 9.5f)
                .writeLine(i18n("Pyyntilupamaksu ja sen maksaminen", "Licensavgiften och dess betalning"))
                .addVerticalSpaceMm(2)

                .font(PDType1Font.HELVETICA, 9.5f)
                .writeParagraph(i18n(
                        "Riistanhoitomaksusta ja pyyntilupamaksusta annetun lain (616/1993) 4 :n mukaan: "
                                + "Metsstyslain 26 :ss tarkoitetusta hirvielimen pyyntiluvasta on suoritettava maksu "
                                + "(pyyntilupamaksu) valtiolle. Pyyntilupamaksu suoritetaan kultakin kaadetulta "
                                + "hirvielimelt. Luvan saajan on suoritettava pyyntilupamaksu viimeistn seitsemn "
                                + "pivn kuluttua hirvielimen metsstyskauden pttymisest sen mukaan kuin "
                                + "valtioneuvoston asetuksella sdetn.",
                        "Lag om viltvrdsavgift och licensavgift (616/1993) 4 : Fr i 26  i jaktlagen avsedd "
                                + "jaktlicens fr hjortdjur ska det betalas en avgift (jaktlicensavgift) till staten. "
                                + "Jaktlicensavgiften bestms enligt antalet fllda hjortdjur. Licenshavaren ska betala "
                                + "jaktlicensavgiften inom sju dagar efter det att jaktssongen fr hjortdjur r avslutad "
                                + "i enlighet med vad som freskrivs genom frordning av statsrdet."))
                .writeEmptyLine()
                .writeParagraph(i18n(
                        "Metsstysasetuksen (666/1993) 9 :n mukaan metsstyksen tuloksesta tehtvn "
                                + "ilmoitukseen on liitettv tosite pyyntilupamaksun suorittamisesta. Ilmoitus on tehtv "
                                + "seitsemn vuorokauden kuluessa pyyntiluvassa mainittujen elinten tultua pyydystetyiksi "
                                + "taikka, jos elimi on jnyt pyydystmtt, seitsemn vuorokauden kuluessa rauhoitusajan "
                                + "alkamisesta.",
                        "Enligt Jaktfrordningens (666/1993) 9  skall ett "
                                + "verifikat ver att jaktlicensavgiften betalats fogas till byteanmlan. Anmlan ska gras inom "
                                + "sju dygn efter det att de i jaktlicensen nmnda djuren fllts eller, om djur inte fllts, "
                                + "inom sju dygn efter det att fredningstiden har brjat."))
                .writeEmptyLine()

                .writeParagraph(i18n(
                        "Valtiolle on maksettava maksu kaadetuista hirvielimist oheisella tilisiirtolomakkeella"
                                + " (esim. pankissa tai nettipankissa).",
                        "Betalning till staten skall gras fr de fllda hjortdjuren med det bifogade bankgirot"
                                + " (tex i bank eller ntbank)"))
                .writeEmptyLine()

                .font(PDType1Font.HELVETICA_BOLD, 9.5f)
                .writeLine(i18n("Seuraamukset laiminlynneist", "Pfljd av frsummelse"))
                .addVerticalSpaceMm(2)

                .font(PDType1Font.HELVETICA, 9.5f)
                .writeParagraph(i18n(
                        "Metsstyslain (615/1993) 74 :n mukaan em. ilmoitusvelvollisuuden laiminlyj syyllistyy metsstysrikkomukseen.",
                        "Enligt jaktlagens (615/1993) 74  gr sig den som frsummar att gra den ovan nmnda bytesanmlan, sig skyldig till en jaktfrseelse."))
                .writeEmptyLine()
                .writeParagraph(i18n("Riistanhoitomaksusta ja pyyntilupamaksusta annetun lain 5 :n mukaan: Jos "
                        + "pyyntilupamaksua ei suoriteta mrajassa, Suomen riistakeskuksen on pantava se maksuun. "
                        + "Maksun suorasta ulosottokelpoisuudesta  ilman ulosottoperustetta sdetn verojen ja "
                        + "maksujen tytntnpanosta annetussa laissa (706/2007).",
                        "Enligt lagen om viltvrdsavgift och licensavgift  (616 /1993) 5 : Betalas en "
                                + "jaktlicensavgift inte inom freskriven tid ska Finlands viltcentral driva in avgiften. "
                                + "Bestmmelser om avgiftens direkta utskbarhet utan utskningsgrund finns i lagen om "
                                + "verkstllighet av skatter och avgifter (706/2007)."));
    }

    private void addPaymentTable(final InvoicePdfWriter writer) throws IOException {
        writer.font(PDType1Font.HELVETICA, 9.5f, 20f);

        final int baseTopOffset = 165;

        writer.topOffsetMm(baseTopOffset).marginLeftMm(25).writeLine(i18n("Saalis", "Byte"))
                .writeLine(i18n("Aikuiset", "Vuxna")).writeLine(i18n("Vasat", "Kalvar"));

        writer.topOffsetMm(baseTopOffset).marginLeftMm(43).writeLine(i18n("Uros", "Hane")).writeLine("______  +")
                .writeLine("______  +");

        writer.topOffsetMm(baseTopOffset).marginLeftMm(63).writeLine(i18n("Naaras", "Hona")).writeLine("______  =")
                .writeLine("______  =");

        writer.topOffsetMm(baseTopOffset).marginLeftMm(80).writeLine(i18n("yht/kpl", "tot/st"))
                .writeLine("_______  -").writeLine("_______  -");

        writer.topOffsetMm(baseTopOffset - 4.5f).marginLeftMm(100).writeLine(i18n("Vhenn ML", "Dra av"))
                .addVerticalSpaceMm(-2.5f).writeLine(i18n("28 :n myn.", "beviljade enl."))
                .writeLine(i18n("_________ kpl   =", "_________ st    ="))
                .writeLine(i18n("_________ kpl   =", "_________ st    ="));

        writer.topOffsetMm(baseTopOffset).marginLeftMm(130).writeLine(i18n("Maksettavat", "Skall betalas"))
                .writeLine(i18n("_________ kpl    x", "_________ st     x"))
                .writeLine(i18n("_________ kpl    x", "_________ st     x"));

        writer.topOffsetMm(baseTopOffset).marginLeftMm(162).writeLine(i18n("Euroa", "Euro"))
                .writeLine(String.format("%s  =  _________", model.getSpecimenPrice().formatAdultPrice()))
                .writeLine(String.format("%s  =  _________", model.getSpecimenPrice().formatYoungPrice()));
    }

    private void addFormFieldData() throws IOException {
        textField("iban", model.getInvoiceAccountDetails().getCombinedBankNameAndIbanString());
        textField("bic", model.getInvoiceAccountDetails().getBic().toString());
        textField("saaja", model.getPaymentRecipient());
        textField("maksaja", Joiner.on('\n').join(model.getInvoiceRecipient().formatAsLines()));
        textField("summa", model.getAmountText());
        textField("viitenumero", model.getInvoiceReferenceForHuman());
        textField("lisatiedot", model.getInvoiceAdditionalInfo());

        this.acroForm.setNeedAppearances(false);

        // Fix annotations
        for (PDPage page : this.pdfDocument.getPages()) {
            for (PDAnnotation annot : page.getAnnotations()) {
                annot.setPage(page);
            }
        }

        // Define font resources names used in PDF template
        final PDResources dr = new PDResources();
        dr.put(COSName.getPDFName("Helv"), PDType1Font.HELVETICA);
        dr.put(COSName.getPDFName("HeBo"), PDType1Font.HELVETICA_BOLD);
        this.acroForm.setDefaultResources(dr);

        // Convert form fields to text
        this.acroForm.flatten();
    }

    public byte[] build() throws IOException {
        try (final InvoicePdfWriter writer = new InvoicePdfWriter(pdfDocument, pdfPage)) {
            addInvoiceHeader(writer);
            addInvoiceSender(writer);
            addInvoiceReceiver(writer);
            addInvoiceText(writer);
            addPaymentTable(writer);
            writer.barCode(model.createBarCodeMessage(null));
            writer.riistaLogo(10, 180, 20);
        }

        addFormFieldData();

        final ByteArrayOutputStream bos = new ByteArrayOutputStream();
        pdfDocument.save(bos);
        pdfDocument.close();
        return bos.toByteArray();
    }

}