Archiv für den Monat: Februar 2024

Massenentlassungsanzeige: Anlage „Angaben für die Arbeitsvermittlung“ schnell ausgefüllt

Immer mal wieder unterstütze ich Unternehmen im Rahmen der anwaltlichen Beratung bei der Erstellung einer Massenentlassungsanzeige. Geht hier etwas schief, droht Schiffbruch, wenn der Fehler im Rahmen eines Kündigungsschutzverfahrens auffliegt.

Meistens bekomme ich die Arbeitnehmerdaten für die Beratung ohnehin elektronisch angeliefert. Dann wäre es selbst mittels „Copy & Paste“ lästig, das Vorhandene händisch in das Formular der Arbeitsagentur (dok_ba036740.pdf) zu übertragen.

Ab und an blicke ich über den Tellerrand und „code“ ein wenig. Meine Lösungen versuchen mit dem auszukommen, was das Betriebssystem bietet. Ergebnis ist deshalb ein bash-Skript. Es bevölkert das Formular der Arbeitsagentur mit den Daten aus einer Tabelle im csv-Format. Gängige Tabellenkalkulationsprogramme ermöglichen den Export der Daten in dieses Format. Eine csv-Datei mit Testdaten ist hier hinterlegt.

Ein paar Wimpernschläge weiter sind die Daten aus der csv-Datei im Formular. Übertragungs- und Eingabefehler werden vermieden.

Hinweis: Wer nicht weiß, was ein bash-Skript ist, wird mit dem Tool vermutlich nicht glücklich werden. Und wer einen „bug“ findet, der darf ihn behalten 😉 , wobei ich natürlich für jeden sachdienlichen Hinweis dankbar bin.

#!/bin/bash
#
# This script fills in the form dok_ba036740.pdf
# published by the german labour office
# with data sets from a csv-file (delimiter ";",
# encoded "Westeuropäisch ISO-8859-1", 10
# columns, max. 66 rows including one header-
# row).
#
# dependencies:
# pdftk
#
# usage: 
# pdf-filler-ba036740.sh <csv-file> <pdf-form-file> <output-pdf-file>
#
# Copyright (C) 2024 Dominique Maier 
# licensed under GPL-3.0-or-later
#
# 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
# 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 <https://www.gnu.org/licenses/>.
#
# ######################################################################

# help and tests
usage=$(echo "Usage: `basename $0` <csv-file> <pdf-form-file> <output-pdf-file>")
if [ "$1" == "-h" ]; then
  echo $usage 
  exit 0
fi
if [ "${1##*.}" != "csv" -o "${2##*.}" != "pdf" -o "${3##*.}" != "pdf" ]; then
  echo "Error! At least one file missing or wrong file type or wrong file order."
  echo $usage
  exit 0
fi
dependencies="pdftk"
if [ -z `which pdftk` ] ; then
  echo "Error! Dependency-check failed."
  echo "Necessary dependencies to be installed: "$dependencies
  exit 0
fi

# (f)pdf files 
input_data="input.fdf"
src_pdf="$2"
target_pdf="$3"

# csv-file
csv_src="$1"
csv_col_tot="10"

# form structure
frm_rs_pg_1="2"           # no of record sets on first page
frm_rs_follw_pg="7"       # no of record sets on following pages
frm_pg_1_fst_row="5"      # position of first row on first page
frm_follw_pg_fst_row="3"  # position of first row on following pages
frm_fst_col="2"           # position of first column
frm_col_max="6"           # no of columns
frm_max_rs="65"           # max no of record sets
# fpdf header and footer
fpdf_header="%FDF-1.2\n1 0 obj\n<< /FDF \n<< /Fields[\n"
fpdf_footer="] >> >>\nendobj\ntrailer\n<</Root 1 0 R>>\n%%EOF"

# initial values
frm_pg_rs_count="1"                    # record set on one page
csv_rs_count="1"                       # record set of csv
cur_frm_pg="1"                         # current form page
cur_frm_row=$(echo $frm_pg_1_fst_row)  # current form row
cur_frm_col=$(echo $frm_fst_col)       # current form column

# let's do it!
while IFS=";" read -r $(eval echo "rec_col{1..$csv_col_tot}")
do
  if [ $csv_rs_count -gt $frm_max_rs ] ; then
    echo "Error! The form only has a capacity for 65 record sets."
    echo "The csv-file contains more than 65 record sets."
    echo "I stop the script."
    exit 0
  fi
  #echo "csv-row: "$csv_rs_count" frm-page: "$cur_frm_pg # for testing purpose
  for (( csv_col=1; csv_col<=$csv_col_tot;csv_col++)); do
    cur_frm_val=$(eval echo "${rec_col$csv_col}")
    # echo "frm-row: "$cur_frm_row"frm-col: "$cur_frm_col          # for testing purpose
    # echo "value  : "$(eval echo "${rec_col$csv_col}")           # for testing purpose
    fpdf_file_data=$fpdf_file_data"\n<< /T (topmostSubform[0].Page${cur_frm_pg}[0].txtf_Tabelle_Seite"
    fpdf_file_data=$fpdf_file_data"${cur_frm_pg}_Zeile${cur_frm_row}_Spalte${cur_frm_col}[0]) "
    fpdf_file_data=$fpdf_file_data"/V (${cur_frm_val}) >>"
    if [ $cur_frm_col -eq $frm_col_max ] ; then # use again the first col of the form
      cur_frm_col=$(echo $frm_fst_col)
      cur_frm_row=$(expr $cur_frm_row + 1)
    else                                        # continue col counting
      cur_frm_col=$(expr $cur_frm_col + 1)
    fi
  done
  if [ $cur_frm_pg -eq 1 -a $frm_pg_rs_count -eq $frm_rs_pg_1 ] ; then # use again the first row of the next page
    cur_frm_row=$(echo $frm_follw_pg_fst_row)
    cur_frm_pg=$(expr $cur_frm_pg + 1)
    frm_pg_rs_count="0"
  fi
  if [ $cur_frm_pg -ne 1 -a $frm_pg_rs_count -eq $frm_rs_follw_pg ] ; then # use again the first fow of the next page
    cur_frm_row=$(echo $frm_follw_pg_fst_row)
    cur_frm_pg=$(expr $cur_frm_pg + 1)
    frm_pg_rs_count="0"
  fi
  frm_pg_rs_count=$(expr $frm_pg_rs_count + 1)  
  csv_rs_count=$(expr $csv_rs_count + 1)
  # if [ $csv_rs_count -eq 10 ] ; then break ; fi # for testing purpose

done < <(tail -n +2 $csv_src)
echo -e "$fpdf_header""$fpdf_file_data""$fpdf_footer" > $input_data
pdftk $src_pdf fill_form $input_data output $target_pdf

# clean up
rm -rf $input_data

exit 0