
package de.ivu.elect.core.exchange.wahl;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;

import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;

import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

import org.apache.commons.lang3.time.DateUtils;

import de.ivu.elect.EmlExportMapper;
import de.ivu.elect.business.anschrift.entity.NlZipCodeProperty;
import de.ivu.elect.business.datei.entity.DateiConstants;
import de.ivu.elect.business.wahl.control.AbstractNlExportArtefaktNachSystemExportstatusExportContext;
import de.ivu.elect.business.wahl.entity.NlWahlParameterWerte;
import de.ivu.elect.business.wahl.entity.NlWahlart;
import de.ivu.elect.business.wahl.entity.Wahl;
import de.ivu.elect.jee.faces.FacesMessageUtil;
import de.ivu.elect.jee.presentation.dynamicform.AbstractSelectManyProperty;
import de.ivu.elect.jee.presentation.dynamicform.AbstractStringProperty;
import de.ivu.elect.jee.presentation.dynamicform.AbstractTemporalProperty;
import de.ivu.elect.jee.presentation.dynamicform.FormBuilder;
import de.ivu.elect.jee.presentation.dynamicform.LambdaDateProperty;
import de.ivu.elect.jee.presentation.dynamicform.LambdaStringProperty;
import de.ivu.elect.jee.presentation.dynamicform.LambdaStringSelectManyProperty;
import de.ivu.elect.jee.presentation.dynamicform.LambdaTimestampBetweenProperty;
import de.ivu.elect.jee.presentation.dynamicform.LambdaTimestampProperty;
import de.ivu.elect.jee.presentation.dynamicform.PropertyType;
import de.ivu.elect.presentation.ViewFormBuilder;
import de.ivu.elect.util.CaseAndDiacriticIgnoringComparator;

public class NlExportArtefaktNachSystemExportstatusExportFormBuilder extends ViewFormBuilder {

  private static final long serialVersionUID = 1L;

  private static final String PAST_DATE_VALIDATED_ATTRIBUTE_NAME_PREFIX = "NlExportArtefaktNachSystemExportstatusExportFormBuilder#PAST_DATE_VALIDATED_";

  private static final Predicate<Date> PAST_DATE_PREDICATE = value -> {
    Date now = new Date();

    return value != null && value.before(now) && !DateUtils.isSameDay(value, now);
  };

  public NlExportArtefaktNachSystemExportstatusExportFormBuilder() {
    super();
  }

  public void addProperties(FormBuilder formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext context, NlExportArtefaktNachSystemExportstatusExportMapper exportMapper) {
    addProperties(formBuilder, context, asList(exportMapper), false);
  }

  public void addProperties(FormBuilder formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext context,
      Collection< ? extends NlExportArtefaktNachSystemExportstatusExportMapper> exportMappers) {
    addProperties(formBuilder, context, exportMappers, false);

    int exportMappersCount = exportMappers.size();

    if (exportMappersCount > 0) {
      formBuilder.addSeparator(exportMappersCount > 1 ? DateiConstants.MESSAGE_KEY_ENTITY_MEHRZAHL : DateiConstants.MESSAGE_KEY_ENTITY_EINZAHL);

      List<String> targetFileNames = exportMappers.stream() //
          .flatMap(exportMapper -> exportMapper.describeTargetFiles(context).stream()) //
          .sorted(CaseAndDiacriticIgnoringComparator.DEFAULT_INSTANCE) //
          .collect(toList());

      formBuilder.addProperty(new LambdaStringSelectManyProperty(AbstractSelectManyProperty.CHECKBOX_MENU, "", false, ignored -> {
      }, () -> targetFileNames, emptyList())).readonly();
    }
  }

  private void addProperties(FormBuilder formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext context,
      Collection< ? extends NlExportArtefaktNachSystemExportstatusExportMapper> exportMappers, boolean readonly) {
    Layout layout = new Layout(context, exportMappers);

    updateContext(context);

    Predicate<NlWahlParameterWerte> requiredFct = NlWahlParameterWerte::isDefaultRequired;
    Predicate<NlWahlParameterWerte> readonlyFct = parameter -> readonly;

    addPropertiesTargetFileSigning(formBuilder, context, layout, requiredFct, readonlyFct); // ELECT-10450

    addPropertiesWahlbehoerdeWahlausschusssitzungGewaehltesGremium(formBuilder, context, layout, requiredFct, readonlyFct);

    addPropertiesWahlvorschlagEinreichung(formBuilder, context, layout, requiredFct, readonlyFct);

    addPropertiesWahlvorschlagPruefung(formBuilder, context, layout, requiredFct, readonlyFct);

    addPropertiesWahlvorschlagVeroeffentlichung(formBuilder, context, layout, requiredFct, readonlyFct);

    addPropertiesEinwohnerzahlVeroeffentlichung(formBuilder, context, layout, requiredFct, readonlyFct);
  }

  protected void addPropertiesWahlbehoerdeWahlausschusssitzungGewaehltesGremium(FormBuilder formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext context, Layout layout,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    // ELECT-10828, ELECT-13311, Reihenfolge/Pflichtfelder WAS-/WUS-spezifisch...
  }

  protected void addPropertiesTargetFileSigning(FormBuilder formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext context, Layout layout,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    boolean sectionTargetFileSigningRendered = layout.isSectionTargetFilesSigningRendered();

    if (sectionTargetFileSigningRendered) {
      new EmlExportMapper() {

        @Override
        public boolean isSignEml(Wahl wahl) {
          return sectionTargetFileSigningRendered;
        }
      }.addSignProperties(context.getWahl(), formBuilder, context, getMessages());
    }
  }

  protected void addPropertiesWahlbehoerde(FormBuilder formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext context, Layout layout, Predicate<NlWahlParameterWerte> requiredFct,
      Predicate<NlWahlParameterWerte> readonlyFct) {
    if (layout.isSectionWahlbehoerdeRendered()) {
      formBuilder.addSeparator(AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLBEHOERDE_SEPARATOR_MSG_KEY);

      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLBEHOERDE_WAHLLEITER_NAME, layout.isPropertyWahlbehoerdeWahlleiterNameRendered(),
          context::setWahlbehoerdeWahlleiterName, context::getWahlbehoerdeWahlleiterName, requiredFct, readonlyFct);

      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLBEHOERDE_ANSCHRIFT_STRASSE_HAUSNUMMER,
          layout.isPropertyWahlbehoerdeAnschriftStrasseHausnummerRendered(), context::setWahlbehoerdeAnschriftStrasseHausnummer, context::getWahlbehoerdeAnschriftStrasseHausnummer, requiredFct,
          readonlyFct);
      addPlzProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLBEHOERDE_ANSCHRIFT_PLZ, layout.isPropertyWahlbehoerdeAnschriftPlzRendered(),
          context::setWahlbehoerdeAnschriftPlz, context::getWahlbehoerdeAnschriftPlz, requiredFct, readonlyFct);
      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLBEHOERDE_ANSCHRIFT_ORT, layout.isPropertyWahlbehoerdeAnschriftOrtRendered(),
          context::setWahlbehoerdeAnschriftOrt, context::getWahlbehoerdeAnschriftOrt, requiredFct, readonlyFct);
    }
  }

  protected void addPropertiesWahlbehoerdeDokumentErstellt(FormBuilder formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext context, Layout layout,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    if (layout.isSectionWahlbehoerdeDokumentErstelltRendered()) {
      formBuilder.addSeparator(AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLBEHOERDE_DOKUMENT_ERSTELLT_SEPARATOR_MSG_KEY);

      // ELECT-11984
      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLBEHOERDE_DOKUMENT_ERSTELLT_ANSCHRIFT_STRASSE_HAUSNUMMER,
          layout.isPropertyWahlbehoerdeDokumentErstelltAnschriftStrasseHausnummerRendered(), context::setWahlbehoerdeDokumentErstelltAnschriftStrasseHausnummer,
          context::getWahlbehoerdeDokumentErstelltAnschriftStrasseHausnummer, requiredFct, readonlyFct);
      addPlzProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLBEHOERDE_DOKUMENT_ERSTELLT_ANSCHRIFT_PLZ,
          layout.isPropertyWahlbehoerdeDokumentErstelltAnschriftPlzRendered(), context::setWahlbehoerdeDokumentErstelltAnschriftPlz, context::getWahlbehoerdeDokumentErstelltAnschriftPlz, requiredFct,
          readonlyFct);
      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLBEHOERDE_DOKUMENT_ERSTELLT_ANSCHRIFT_ORT,
          layout.isPropertyWahlbehoerdeDokumentErstelltAnschriftOrtRendered(), context::setWahlbehoerdeDokumentErstelltAnschriftOrt, context::getWahlbehoerdeDokumentErstelltAnschriftOrt, requiredFct,
          readonlyFct);

      // ELECT-11849
      addDatePropertyExpectingNonPastValue(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLBEHOERDE_DOKUMENT_ERSTELLT_AM,
          layout.isPropertyWahlbehoerdeDokumentErstelltAmRendered(), context::setWahlbehoerdeDokumentErstelltAm, context::getWahlbehoerdeDokumentErstelltAm, requiredFct, readonlyFct);
    }
  }

  protected void addPropertiesGewaehltesGremium(FormBuilder formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext context, Layout layout,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    if (layout.isSectionGewaehltesGremiumRendered()) {
      formBuilder.addSeparator(AbstractNlExportArtefaktNachSystemExportstatusExportContext.GEWAEHLTES_GREMIUM_SEPARATOR_MSG_KEY);

      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.GEWAEHLTES_GREMIUM_DURCHFUEHRENDES_ORGAN,
          layout.isPropertyGewaehltesGremiumDurchfuehrendesOrganRendered(), context::setGewaehltesGremiumDurchfuehrendesOrgan, context::getGewaehltesGremiumDurchfuehrendesOrgan, requiredFct,
          readonlyFct);

      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.GEWAEHLTES_GREMIUM_ANSCHRIFT_STRASSE_HAUSNUMMER,
          layout.isPropertyGewaehltesGremiumAnschriftStrasseHausnummerRendered(), context::setGewaehltesGremiumAnschriftStrasseHausnummer, context::getGewaehltesGremiumAnschriftStrasseHausnummer,
          requiredFct, readonlyFct);
      addPlzProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.GEWAEHLTES_GREMIUM_ANSCHRIFT_PLZ, layout.isPropertyGewaehltesGremiumAnschriftPlzRendered(),
          context::setGewaehltesGremiumAnschriftPlz, context::getGewaehltesGremiumAnschriftPlz, requiredFct, readonlyFct);
      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.GEWAEHLTES_GREMIUM_ANSCHRIFT_ORT, layout.isPropertyGewaehltesGremiumAnschriftOrtRendered(),
          context::setGewaehltesGremiumAnschriftOrt, context::getGewaehltesGremiumAnschriftOrt, requiredFct, readonlyFct);
    }
  }

  protected void addPropertiesWahlausschusssitzung(FormBuilder formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext context, Layout layout,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    if (layout.isSectionWahlausschusssitzungRendered()) {
      formBuilder.addSeparator(AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLAUSSCHUSSSITZUNG_SEPARATOR_MSG_KEY);

      addTimestampPropertiesExpectingNonPastValue(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLAUSSCHUSSSITZUNG_BEGINN_ENDE_LABEL_MSG_KEY,
          AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLAUSSCHUSSSITZUNG_BEGINN, layout.isPropertyWahlausschusssitzungBeginnRendered(), context::setWahlausschusssitzungBeginn,
          context::getWahlausschusssitzungBeginn, requiredFct, readonlyFct, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLAUSSCHUSSSITZUNG_ENDE,
          layout.isPropertyWahlausschusssitzungEndeRendered(), context::setWahlausschusssitzungEnde, context::getWahlausschusssitzungEnde, requiredFct, readonlyFct);

      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLAUSSCHUSSSITZUNG_ANSCHRIFT_STRASSE_HAUSNUMMER,
          layout.isPropertyWahlausschusssitzungAnschriftStrasseHausnummerRendered(), context::setWahlausschusssitzungAnschriftStrasseHausnummer,
          context::getWahlausschusssitzungAnschriftStrasseHausnummer, requiredFct, readonlyFct);
      addPlzProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLAUSSCHUSSSITZUNG_ANSCHRIFT_PLZ, layout.isPropertyWahlausschusssitzungAnschriftPlzRendered(),
          context::setWahlausschusssitzungAnschriftPlz, context::getWahlausschusssitzungAnschriftPlz, requiredFct, readonlyFct);
      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLAUSSCHUSSSITZUNG_ANSCHRIFT_ORT, layout.isPropertyWahlausschusssitzungAnschriftOrtRendered(),
          context::setWahlausschusssitzungAnschriftOrt, context::getWahlausschusssitzungAnschriftOrt, requiredFct, readonlyFct);

      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLAUSSCHUSSSITZUNG_EINWAENDE, layout.isPropertyWahlausschusssitzungEinwaendeRendered(),
          context::setWahlausschusssitzungEinwaende, context::getWahlausschusssitzungEinwaende, requiredFct, readonlyFct);
      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLAUSSCHUSSSITZUNG_EINWAENDE_BEMERKUNGEN,
          layout.isPropertyWahlausschusssitzungEinwaendeBemerkungenRendered(), context::setWahlausschusssitzungEinwaendeBemerkungen, context::getWahlausschusssitzungEinwaendeBemerkungen, requiredFct,
          readonlyFct);
    }
  }

  protected void addPropertiesWahlvorschlagPruefung(FormBuilder formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext context, Layout layout,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    if (layout.isSectionWahlvorschlagPruefungFristZuletztGesetztRendered()) {
      formBuilder.addSeparator(AbstractNlExportArtefaktNachSystemExportstatusExportContext.FRIST_ZULETZT_GESETZT_SEPARATOR_MSG_KEY);

      addTimestampPropertiesExpectingNonPastValue(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.FRIST_ZULETZT_GESETZT_BEGINN_ENDE_LABEL_MSG_KEY,
          AbstractNlExportArtefaktNachSystemExportstatusExportContext.FRIST_ZULETZT_GESETZT_BEGINN, layout.isPropertyWahlvorschlagPruefungFristZuletztGesetztBeginnRendered(),
          context::setFristZuletztGesetztBeginn, context::getFristZuletztGesetztBeginn, requiredFct, readonlyFct,
          AbstractNlExportArtefaktNachSystemExportstatusExportContext.FRIST_ZULETZT_GESETZT_ENDE, layout.isPropertyWahlvorschlagPruefungFristZuletztGesetztEndeRendered(),
          context::setFristZuletztGesetztEnde, context::getFristZuletztGesetztEnde, requiredFct, readonlyFct);
    }

    if (layout.isSectionWahlvorschlagPruefungUnterzeichnerRendered()) {
      formBuilder.addSeparator(AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLAUSSCHUSSSITZUNG_UNTERZEICHNER_SEPARATOR_MSG_KEY);

      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLAUSSCHUSSSITZUNG_UNTERZEICHNER_1_NAME,
          layout.isPropertyWahlvorschlagPruefungUnterzeichner1NameRendered(), context::setWahlausschusssitzungUnterzeichner1Name, context::getWahlausschusssitzungUnterzeichner1Name, requiredFct,
          readonlyFct);
      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLAUSSCHUSSSITZUNG_UNTERZEICHNER_1_ROLLE,
          layout.isPropertyWahlvorschlagPruefungUnterzeichner1RolleRendered(), context::setWahlausschusssitzungUnterzeichner1Rolle, context::getWahlausschusssitzungUnterzeichner1Rolle, requiredFct,
          readonlyFct);
      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLAUSSCHUSSSITZUNG_UNTERZEICHNER_2_NAME,
          layout.isPropertyWahlvorschlagPruefungUnterzeichner2NameRendered(), context::setWahlausschusssitzungUnterzeichner2Name, context::getWahlausschusssitzungUnterzeichner2Name, requiredFct,
          readonlyFct);
      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLAUSSCHUSSSITZUNG_UNTERZEICHNER_2_ROLLE,
          layout.isPropertyWahlvorschlagPruefungUnterzeichner2RolleRendered(), context::setWahlausschusssitzungUnterzeichner2Rolle, context::getWahlausschusssitzungUnterzeichner2Rolle, requiredFct,
          readonlyFct);
    }
  }

  protected void addPropertiesWahlvorschlagEinreichung(FormBuilder formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext context, Layout layout,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    if (layout.isSectionWahlvorschlagEinreichungRendered()) {
      formBuilder.addSeparator(AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLVORSCHLAG_EINREICHUNG_SEPARATOR_MSG_KEY);

      addDatePropertyExpectingNonPastValue(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLVORSCHLAG_EINREICHUNG_ABGABEFRIST,
          layout.isPropertyWahlvorschlagEinreichungAbgabefristRendered(), context::setWahlvorschlagEinreichungAbgabefrist, context::getWahlvorschlagEinreichungAbgabefrist, requiredFct, readonlyFct);

      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLVORSCHLAG_EINREICHUNG_ANSCHRIFT_ORT,
          layout.isPropertyWahlvorschlagEinreichungAnschriftOrtRendered(), context::setWahlvorschlagEinreichungAnschriftOrt, context::getWahlvorschlagEinreichungAnschriftOrt, requiredFct,
          readonlyFct);
    }

    if (layout.isSectionWahlvorschlagEinreichungUnterzeichnerRendered()) {
      // formBuilder.addSeparator(AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLVORSCHLAG_EINREICHUNG_UNTERZEICHNER_SEPARATOR_MSG_KEY);

      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLVORSCHLAG_EINREICHUNG_UNTERZEICHNER_1_NAME,
          layout.isPropertyWahlvorschlagEinreichungUnterzeichner1NameRendered(), context::setWahlvorschlagEinreichungUnterzeichner1Name, context::getWahlvorschlagEinreichungUnterzeichner1Name,
          requiredFct, readonlyFct);
    }
  }

  protected void addPropertiesWahlvorschlagVeroeffentlichung(FormBuilder formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext context, Layout layout,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    if (layout.isSectionWahlvorschlagVeroeffentlichungRendered()) {
      formBuilder.addSeparator(AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLVORSCHLAG_VEROEFFENTLICHUNG_SEPARATOR_MSG_KEY);

      addDatePropertyExpectingNonPastValue(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLVORSCHLAG_VEROEFFENTLICHUNG_BEGINN,
          layout.isPropertyWahlvorschlagVeroeffentlichungBeginnRendered(), context::setWahlvorschlagVeroeffentlichungBeginn, context::getWahlvorschlagVeroeffentlichungBeginn, requiredFct,
          readonlyFct);

      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLVORSCHLAG_VEROEFFENTLICHUNG_ANSCHRIFT_ORT,
          layout.isPropertyWahlvorschlagVeroeffentlichungAnschriftOrtRendered(), context::setWahlvorschlagVeroeffentlichungAnschriftOrt, context::getWahlvorschlagVeroeffentlichungAnschriftOrt,
          requiredFct, readonlyFct);
    }

    if (layout.isSectionWahlvorschlagVeroeffentlichungUnterzeichnerRendered()) {
      // formBuilder.addSeparator(AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLVORSCHLAG_VEROEFFENTLICHUNG_UNTERZEICHNER_SEPARATOR_MSG_KEY);

      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.WAHLVORSCHLAG_VEROEFFENTLICHUNG_UNTERZEICHNER_1_NAME,
          layout.isPropertyWahlvorschlagVeroeffentlichungUnterzeichner1NameRendered(), context::setWahlvorschlagVeroeffentlichungUnterzeichner1Name,
          context::getWahlvorschlagVeroeffentlichungUnterzeichner1Name, requiredFct, readonlyFct);
    }
  }

  protected void addPropertiesEinwohnerzahlVeroeffentlichung(FormBuilder formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext context, Layout layout,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    if (layout.isSectionEinwohnerzahlVeroeffentlichungRendered()) {
      formBuilder.addSeparator(AbstractNlExportArtefaktNachSystemExportstatusExportContext.EINWOHNERZAHL_VEROEFFENTLICHUNG_SEPARATOR_MSG_KEY);

      addDateProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.EINWOHNERZAHL_VEROEFFENTLICHUNG_DATUM, layout.isPropertyEinwohnerzahlVeroeffentlichungDatumRendered(),
          context::setEinwohnerzahlVeroeffentlichungDatum, context::getEinwohnerzahlVeroeffentlichungDatum, requiredFct, readonlyFct);

      addStringProperty(formBuilder, AbstractNlExportArtefaktNachSystemExportstatusExportContext.EINWOHNERZAHL_VEROEFFENTLICHUNG_ID, layout.isPropertyEinwohnerzahlVeroeffentlichungIdRendered(),
          context::setEinwohnerzahlVeroeffentlichungId, context::getEinwohnerzahlVeroeffentlichungId, requiredFct, readonlyFct);
    }
  }

  private void addStringProperty(FormBuilder formBuilder, NlWahlParameterWerte parameter, boolean parameterRendered, Consumer<String> setter, Supplier<String> getter,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    if (parameterRendered) {
      formBuilder.addProperty(createStringProperty(parameter, setter, getter, requiredFct)).withReadonly(readonlyFct.test(parameter));

      if (parameter.getDefaultMaxLength() > NlWahlParameterWerte.MAX_LENGTH_DEFAULT_VALUE) {
        formBuilder.withType(PropertyType.INPUT_TEXTAREA);
      }
    }
  }

  private void addPlzProperty(FormBuilder formBuilder, NlWahlParameterWerte parameter, boolean parameterRendered, Consumer<String> setter, Supplier<String> getter,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    if (parameterRendered) {
      formBuilder.addProperty(new NlZipCodeProperty(createStringProperty(parameter, setter, getter, requiredFct))).withReadonly(readonlyFct.test(parameter));
    }
  }

  private AbstractStringProperty createStringProperty(NlWahlParameterWerte parameter, Consumer<String> setter, Supplier<String> getter, Predicate<NlWahlParameterWerte> requiredFct) {
    return new LambdaStringProperty(parameter.getDefaultLabel(getMessages()), requiredFct.test(parameter), setter, getter, parameter.getDefaultMinLength(), parameter.getDefaultMaxLength());
  }

  private void addTimestampPropertiesExpectingNonPastValue(FormBuilder formBuilder, String labelMsgKey, NlWahlParameterWerte parameterFrom, boolean parameterFromRendered, Consumer<Date> setterFrom,
      Supplier<Date> getterFrom, Predicate<NlWahlParameterWerte> parameterFromRequiredFct, Predicate<NlWahlParameterWerte> parameterFromReadonlyFct, NlWahlParameterWerte parameterTo,
      boolean parameterToRendered, Consumer<Date> setterTo, Supplier<Date> getterTo, Predicate<NlWahlParameterWerte> parameterToRequiredFct, Predicate<NlWahlParameterWerte> parameterToReadonlyFct) {
    if (parameterFromRendered && parameterToRendered) {
      formBuilder.addProperty(createTimestampBetweenProperty(labelMsgKey, parameterFrom, setterFrom, getterFrom, parameterFromRequiredFct, parameterTo, setterTo, getterTo, parameterToRequiredFct))
          .withReadonly(parameterFromReadonlyFct.test(parameterFrom) && parameterToReadonlyFct.test(parameterFrom));
    } else if (parameterFromRendered) {
      addTimestampPropertyExpectingNonPastValue(formBuilder, parameterFrom, parameterFromRendered, setterFrom, getterFrom, parameterFromRequiredFct, parameterFromReadonlyFct);
    } else if (parameterToRendered) {
      addTimestampPropertyExpectingNonPastValue(formBuilder, parameterTo, parameterToRendered, setterTo, getterTo, parameterToRequiredFct, parameterToReadonlyFct);
    }
  }

  private void addTimestampProperty(FormBuilder formBuilder, NlWahlParameterWerte parameter, boolean parameterRendered, Consumer<Date> setter, Supplier<Date> getter,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    if (parameterRendered) {
      formBuilder.addProperty(createTimestampProperty(parameter, setter, getter, requiredFct)).withReadonly(readonlyFct.test(parameter));
    }
  }

  private void addTimestampPropertyExpectingNonPastValue(FormBuilder formBuilder, NlWahlParameterWerte parameter, boolean parameterRendered, Consumer<Date> setter, Supplier<Date> getter,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    if (parameterRendered) {
      addTemporalPropertyExpectingNonPastValue(formBuilder, createTimestampProperty(parameter, setter, getter, requiredFct), readonlyFct.test(parameter));
    }
  }

  private void addDateProperty(FormBuilder formBuilder, NlWahlParameterWerte parameter, boolean parameterRendered, Consumer<Date> setter, Supplier<Date> getter,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    if (parameterRendered) {
      formBuilder.addProperty(createDateProperty(parameter, setter, getter, requiredFct)).withReadonly(readonlyFct.test(parameter));
    }
  }

  private void addDatePropertyExpectingNonPastValue(FormBuilder formBuilder, NlWahlParameterWerte parameter, boolean parameterRendered, Consumer<Date> setter, Supplier<Date> getter,
      Predicate<NlWahlParameterWerte> requiredFct, Predicate<NlWahlParameterWerte> readonlyFct) {
    if (parameterRendered) {
      addTemporalPropertyExpectingNonPastValue(formBuilder, createDateProperty(parameter, setter, getter, requiredFct), readonlyFct.test(parameter));
    }
  }

  private void addTemporalPropertyExpectingNonPastValue(FormBuilder formBuilder, AbstractTemporalProperty property, boolean readonly) {
    formBuilder.addProperty(property).withReadonly(readonly);

    if (!readonly) {
      Validator pastValueWarningValidator = (facesContext, component, value) -> {
        if (facesContext != null && component != null && value instanceof Date) {
          String pastDateValidatedAttributeName = PAST_DATE_VALIDATED_ATTRIBUTE_NAME_PREFIX + component.getClientId(); // ELECT-12773

          if (PAST_DATE_PREDICATE.test((Date) value) && !Objects.equals(value, component.getAttributes().get(pastDateValidatedAttributeName))) {
            component.getAttributes().put(pastDateValidatedAttributeName, value);

            String msgKey = "NlExportArtefaktNachSystemExportstatusExportFormBuilder.PAST_DATE.message";

            throw new ValidatorException(FacesMessageUtil.createWarnMessage(facesContext, msgKey, msgKey));
          }
        }
      };

      formBuilder.withValidator(pastValueWarningValidator); // ELECTVAPP-922
    }
  }

  private AbstractTemporalProperty createTimestampBetweenProperty(String labelMsgKey, NlWahlParameterWerte parameterFrom, Consumer<Date> setterFrom, Supplier<Date> getterFrom,
      Predicate<NlWahlParameterWerte> parameterFromRequiredFct, NlWahlParameterWerte parameterTo, Consumer<Date> setterTo, Supplier<Date> getterTo,
      Predicate<NlWahlParameterWerte> parameterToRequiredFct) {
    return new LambdaTimestampBetweenProperty(getMessage(labelMsgKey), parameterFromRequiredFct.test(parameterFrom), setterFrom, getterFrom, parameterToRequiredFct.test(parameterTo), setterTo,
        getterTo);
  }

  private AbstractTemporalProperty createTimestampProperty(NlWahlParameterWerte parameter, Consumer<Date> setter, Supplier<Date> getter, Predicate<NlWahlParameterWerte> requiredFct) {
    return new LambdaTimestampProperty(parameter.getDefaultLabel(getMessages()), requiredFct.test(parameter), setter, getter);
  }

  private AbstractTemporalProperty createDateProperty(NlWahlParameterWerte parameter, Consumer<Date> setter, Supplier<Date> getter, Predicate<NlWahlParameterWerte> requiredFct) {
    return new LambdaDateProperty(parameter.getDefaultLabel(getMessages()), requiredFct.test(parameter), setter, getter);
  }

  protected void updateContext(AbstractNlExportArtefaktNachSystemExportstatusExportContext context) {
    if (context.getWahlausschusssitzungBeginn() == null) {
      String wahlartName = context.getWahlartName(); // ELECTVAPP-1589, ELECTVAPP-1417

      Calendar calendar = Calendar.getInstance();
      calendar.set(Calendar.HOUR_OF_DAY, NlWahlart.EERSTE_KAMER.equalsWahlart(wahlartName) && NlWahlart.equalsWahlebene(wahlartName, NlWahlart.KUERZEL_WAHLEBENE_CSB) ? 9 : 10); // ELECT-9945
      calendar.set(Calendar.MINUTE, 0);
      calendar.set(Calendar.MILLISECOND, 0);

      context.setWahlausschusssitzungBeginn(calendar.getTime());
    }

    if (context.getWahlausschusssitzungEnde() == null) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(context.getWahlausschusssitzungBeginn());

      context.setWahlausschusssitzungEnde(calendar.getTime());
    }

    if (!context.getWahlausschusssitzungEnde().after(context.getWahlausschusssitzungBeginn())) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(context.getWahlausschusssitzungBeginn());
      calendar.add(Calendar.HOUR, 2);

      context.setWahlausschusssitzungEnde(calendar.getTime());
    }
  }

  static class Layout {

    private boolean sectionTargetFilesSigningRendered;

    private final boolean sectionWahlbehoerdeRendered;
    private boolean propertyWahlbehoerdeWahlleiterNameRendered;
    private boolean propertyWahlbehoerdeAnschriftStrasseHausnummerRendered;
    private boolean propertyWahlbehoerdeAnschriftOrtRendered;
    private boolean propertyWahlbehoerdeAnschriftPlzRendered;

    private final boolean sectionWahlbehoerdeDokumentErstelltRendered;
    private boolean propertyWahlbehoerdeDokumentErstelltAnschriftStrasseHausnummerRendered;
    private boolean propertyWahlbehoerdeDokumentErstelltAnschriftOrtRendered;
    private boolean propertyWahlbehoerdeDokumentErstelltAnschriftPlzRendered;
    private boolean propertyWahlbehoerdeDokumentErstelltAmRendered;

    private final boolean sectionGewaehltesGremiumRendered;
    private boolean propertyGewaehltesGremiumDurchfuehrendesOrganRendered;
    private boolean propertyGewaehltesGremiumAnschriftStrasseHausnummerRendered;
    private boolean propertyGewaehltesGremiumAnschriftOrtRendered;
    private boolean propertyGewaehltesGremiumAnschriftPlzRendered;

    private final boolean sectionWahlausschusssitzungRendered;
    private boolean propertyWahlausschusssitzungAnschriftStrasseHausnummerRendered;
    private boolean propertyWahlausschusssitzungAnschriftOrtRendered;
    private boolean propertyWahlausschusssitzungAnschriftPlzRendered;
    private boolean propertyWahlausschusssitzungBeginnRendered;
    private boolean propertyWahlausschusssitzungEndeRendered;
    private boolean propertyWahlausschusssitzungEinwaendeRendered;
    private boolean propertyWahlausschusssitzungEinwaendeBemerkungenRendered;

    private final boolean sectionWahlvorschlagPruefungUnterzeichnerRendered;
    private boolean propertyWahlvorschlagPruefungUnterzeichner1NameRendered;
    private boolean propertyWahlvorschlagPruefungUnterzeichner1RolleRendered;
    private boolean propertyWahlvorschlagPruefungUnterzeichner2NameRendered;
    private boolean propertyWahlvorschlagPruefungUnterzeichner2RolleRendered;

    private final boolean sectionWahlvorschlagPruefungFristZuletztGesetztRendered;
    private boolean propertyWahlvorschlagPruefungFristZuletztGesetztBeginnRendered;
    private boolean propertyWahlvorschlagPruefungFristZuletztGesetztEndeRendered;

    private final boolean sectionWahlvorschlagEinreichungRendered;
    private boolean propertyWahlvorschlagEinreichungAnschriftOrtRendered;
    private boolean propertyWahlvorschlagEinreichungAbgabefristRendered;

    private final boolean sectionWahlvorschlagEinreichungUnterzeichnerRendered;
    private boolean propertyWahlvorschlagEinreichungUnterzeichner1NameRendered;

    private final boolean sectionWahlvorschlagVeroeffentlichungRendered;
    private boolean propertyWahlvorschlagVeroeffentlichungAnschriftOrtRendered;
    private boolean propertyWahlvorschlagVeroeffentlichungBeginnRendered;

    private final boolean sectionWahlvorschlagVeroeffentlichungUnterzeichnerRendered;
    private boolean propertyWahlvorschlagVeroeffentlichungUnterzeichner1NameRendered;

    private final boolean sectionEinwohnerzahlVeroeffentlichungRendered;
    private boolean propertyEinwohnerzahlVeroeffentlichungIdRendered;
    private boolean propertyEinwohnerzahlVeroeffentlichungDatumRendered;

    public Layout(AbstractNlExportArtefaktNachSystemExportstatusExportContext context, Collection< ? extends NlExportArtefaktNachSystemExportstatusExportMapper> exportMappers) {
      super();

      this.propertyWahlbehoerdeWahlleiterNameRendered = false;

      this.propertyWahlbehoerdeAnschriftStrasseHausnummerRendered = false;
      this.propertyWahlbehoerdeAnschriftOrtRendered = false;
      this.propertyWahlbehoerdeAnschriftPlzRendered = false;

      this.propertyWahlbehoerdeDokumentErstelltAnschriftStrasseHausnummerRendered = false;
      this.propertyWahlbehoerdeDokumentErstelltAnschriftOrtRendered = false;
      this.propertyWahlbehoerdeDokumentErstelltAnschriftPlzRendered = false;
      this.propertyWahlbehoerdeDokumentErstelltAmRendered = false;

      this.propertyGewaehltesGremiumDurchfuehrendesOrganRendered = false;
      this.propertyGewaehltesGremiumAnschriftStrasseHausnummerRendered = false;
      this.propertyGewaehltesGremiumAnschriftOrtRendered = false;
      this.propertyGewaehltesGremiumAnschriftPlzRendered = false;

      this.propertyWahlausschusssitzungAnschriftStrasseHausnummerRendered = false;
      this.propertyWahlausschusssitzungAnschriftOrtRendered = false;
      this.propertyWahlausschusssitzungAnschriftPlzRendered = false;
      this.propertyWahlausschusssitzungBeginnRendered = false;
      this.propertyWahlausschusssitzungEndeRendered = false;
      this.propertyWahlausschusssitzungEinwaendeRendered = false;
      this.propertyWahlausschusssitzungEinwaendeBemerkungenRendered = false;

      this.propertyWahlvorschlagPruefungUnterzeichner1NameRendered = false;
      this.propertyWahlvorschlagPruefungUnterzeichner1RolleRendered = false;
      this.propertyWahlvorschlagPruefungUnterzeichner2NameRendered = false;
      this.propertyWahlvorschlagPruefungUnterzeichner2RolleRendered = false;

      this.propertyWahlvorschlagPruefungFristZuletztGesetztBeginnRendered = false;
      this.propertyWahlvorschlagPruefungFristZuletztGesetztEndeRendered = false;

      this.propertyWahlvorschlagEinreichungAnschriftOrtRendered = false;
      this.propertyWahlvorschlagEinreichungAbgabefristRendered = false;

      this.propertyWahlvorschlagEinreichungUnterzeichner1NameRendered = false;

      this.propertyWahlvorschlagVeroeffentlichungAnschriftOrtRendered = false;
      this.propertyWahlvorschlagVeroeffentlichungBeginnRendered = false;

      this.propertyWahlvorschlagVeroeffentlichungUnterzeichner1NameRendered = false;

      this.propertyEinwohnerzahlVeroeffentlichungIdRendered = false;
      this.propertyEinwohnerzahlVeroeffentlichungDatumRendered = false;

      for (NlExportArtefaktNachSystemExportstatusExportMapper exportMapper : exportMappers) {
        this.sectionTargetFilesSigningRendered |= exportMapper.supportsTargetFilesSigning(context);

        this.propertyWahlbehoerdeWahlleiterNameRendered |= exportMapper.requiresWahlbehoerdeWahlleiterName(context);

        this.propertyWahlbehoerdeAnschriftStrasseHausnummerRendered |= exportMapper.requiresWahlbehoerdeAnschriftStrasseHausnummer(context);
        this.propertyWahlbehoerdeAnschriftOrtRendered |= exportMapper.requiresWahlbehoerdeAnschriftOrt(context);
        this.propertyWahlbehoerdeAnschriftPlzRendered |= exportMapper.requiresWahlbehoerdeAnschriftPlz(context);

        this.propertyWahlbehoerdeDokumentErstelltAnschriftStrasseHausnummerRendered |= exportMapper.requiresWahlbehoerdeDokumentErstelltAnschriftStrasseHausnummer(context);
        this.propertyWahlbehoerdeDokumentErstelltAnschriftOrtRendered |= exportMapper.requiresWahlbehoerdeDokumentErstelltAnschriftOrt(context);
        this.propertyWahlbehoerdeDokumentErstelltAnschriftPlzRendered |= exportMapper.requiresWahlbehoerdeDokumentErstelltAnschriftPlz(context);
        this.propertyWahlbehoerdeDokumentErstelltAmRendered |= exportMapper.requiresWahlbehoerdeDokumentErstelltAm(context);

        this.propertyGewaehltesGremiumDurchfuehrendesOrganRendered |= exportMapper.requiresGewaehltesGremiumDurchfuehrendesOrgan(context);
        this.propertyGewaehltesGremiumAnschriftStrasseHausnummerRendered |= exportMapper.requiresGewaehltesGremiumAnschriftStrasseHausnummer(context);
        this.propertyGewaehltesGremiumAnschriftOrtRendered |= exportMapper.requiresGewaehltesGremiumAnschriftOrt(context);
        this.propertyGewaehltesGremiumAnschriftPlzRendered |= exportMapper.requiresGewaehltesGremiumAnschriftPlz(context);

        this.propertyWahlausschusssitzungAnschriftStrasseHausnummerRendered |= exportMapper.requiresWahlausschusssitzungAnschriftStrasseHausnummer(context);
        this.propertyWahlausschusssitzungAnschriftOrtRendered |= exportMapper.requiresWahlausschusssitzungAnschriftOrt(context);
        this.propertyWahlausschusssitzungAnschriftPlzRendered |= exportMapper.requiresWahlausschusssitzungAnschriftPlz(context);
        this.propertyWahlausschusssitzungBeginnRendered |= exportMapper.requiresWahlausschusssitzungBeginn(context);
        this.propertyWahlausschusssitzungEndeRendered |= exportMapper.requiresWahlausschusssitzungEnde(context);
        this.propertyWahlausschusssitzungEinwaendeRendered |= exportMapper.requiresWahlausschusssitzungEinwaende(context);
        this.propertyWahlausschusssitzungEinwaendeBemerkungenRendered |= exportMapper.requiresWahlausschusssitzungEinwaendeBemerkungen(context);

        this.propertyWahlvorschlagPruefungUnterzeichner1NameRendered |= exportMapper.requiresWahlausschusssitzungUnterzeichner1Name(context);
        this.propertyWahlvorschlagPruefungUnterzeichner1RolleRendered |= exportMapper.requiresWahlausschusssitzungUnterzeichner1Rolle(context);
        this.propertyWahlvorschlagPruefungUnterzeichner2NameRendered |= exportMapper.requiresWahlausschusssitzungUnterzeichner2Name(context);
        this.propertyWahlvorschlagPruefungUnterzeichner2RolleRendered |= exportMapper.requiresWahlausschusssitzungUnterzeichner2Rolle(context);

        this.propertyWahlvorschlagPruefungFristZuletztGesetztBeginnRendered |= exportMapper.requiresFristZuletztGesetztBeginn(context);
        this.propertyWahlvorschlagPruefungFristZuletztGesetztEndeRendered |= exportMapper.requiresFristZuletztGesetztEnde(context);

        this.propertyWahlvorschlagEinreichungAnschriftOrtRendered |= exportMapper.requiresWahlvorschlagEinreichungAnschriftOrt(context);
        this.propertyWahlvorschlagEinreichungAbgabefristRendered |= exportMapper.requiresWahlvorschlagEinreichungAbgabefrist(context);

        this.propertyWahlvorschlagEinreichungUnterzeichner1NameRendered |= exportMapper.requiresWahlvorschlagEinreichungUnterzeichner1Name(context);

        this.propertyWahlvorschlagVeroeffentlichungAnschriftOrtRendered |= exportMapper.requiresWahlvorschlagVeroeffentlichungAnschriftOrt(context);
        this.propertyWahlvorschlagVeroeffentlichungBeginnRendered |= exportMapper.requiresWahlvorschlagVeroeffentlichungBeginn(context);

        this.propertyWahlvorschlagVeroeffentlichungUnterzeichner1NameRendered |= exportMapper.requiresWahlvorschlagVeroeffentlichungUnterzeichner1Name(context);

        this.propertyEinwohnerzahlVeroeffentlichungIdRendered |= exportMapper.requiresEinwohnerzahlVeroeffentlichungId(context);
        this.propertyEinwohnerzahlVeroeffentlichungDatumRendered |= exportMapper.requiresEinwohnerzahlVeroeffentlichungDatum(context);
      }

      this.sectionWahlbehoerdeRendered = this.propertyWahlbehoerdeWahlleiterNameRendered || this.propertyWahlbehoerdeAnschriftStrasseHausnummerRendered || this.propertyWahlbehoerdeAnschriftOrtRendered
          || this.propertyWahlbehoerdeAnschriftPlzRendered;

      this.sectionWahlbehoerdeDokumentErstelltRendered = this.propertyWahlbehoerdeDokumentErstelltAnschriftStrasseHausnummerRendered || this.propertyWahlbehoerdeDokumentErstelltAnschriftOrtRendered
          || this.propertyWahlbehoerdeDokumentErstelltAnschriftPlzRendered || this.propertyWahlbehoerdeDokumentErstelltAmRendered;

      this.sectionGewaehltesGremiumRendered = this.propertyGewaehltesGremiumDurchfuehrendesOrganRendered || this.propertyGewaehltesGremiumAnschriftStrasseHausnummerRendered
          || this.propertyGewaehltesGremiumAnschriftOrtRendered || this.propertyGewaehltesGremiumAnschriftPlzRendered;

      this.sectionWahlausschusssitzungRendered = this.propertyWahlausschusssitzungAnschriftStrasseHausnummerRendered || this.propertyWahlausschusssitzungAnschriftOrtRendered
          || this.propertyWahlausschusssitzungAnschriftPlzRendered || this.propertyWahlausschusssitzungBeginnRendered || this.propertyWahlausschusssitzungEndeRendered
          || this.propertyWahlausschusssitzungEinwaendeRendered || this.propertyWahlausschusssitzungEinwaendeBemerkungenRendered;

      this.sectionWahlvorschlagPruefungUnterzeichnerRendered = this.propertyWahlvorschlagPruefungUnterzeichner1NameRendered || this.propertyWahlvorschlagPruefungUnterzeichner1RolleRendered
          || this.propertyWahlvorschlagPruefungUnterzeichner2NameRendered || this.propertyWahlvorschlagPruefungUnterzeichner2RolleRendered;

      this.sectionWahlvorschlagPruefungFristZuletztGesetztRendered = this.propertyWahlvorschlagPruefungFristZuletztGesetztBeginnRendered
          || this.propertyWahlvorschlagPruefungFristZuletztGesetztEndeRendered;

      this.sectionWahlvorschlagEinreichungRendered = this.propertyWahlvorschlagEinreichungAnschriftOrtRendered || this.propertyWahlvorschlagEinreichungAbgabefristRendered;

      this.sectionWahlvorschlagEinreichungUnterzeichnerRendered = this.propertyWahlvorschlagEinreichungUnterzeichner1NameRendered;

      this.sectionWahlvorschlagVeroeffentlichungRendered = this.propertyWahlvorschlagVeroeffentlichungAnschriftOrtRendered || this.propertyWahlvorschlagVeroeffentlichungBeginnRendered;

      this.sectionWahlvorschlagVeroeffentlichungUnterzeichnerRendered = this.propertyWahlvorschlagVeroeffentlichungUnterzeichner1NameRendered;

      this.sectionEinwohnerzahlVeroeffentlichungRendered = this.propertyEinwohnerzahlVeroeffentlichungIdRendered || this.propertyEinwohnerzahlVeroeffentlichungDatumRendered;
    }

    public boolean isSectionTargetFilesSigningRendered() {
      return sectionTargetFilesSigningRendered;
    }

    public boolean isSectionWahlbehoerdeRendered() {
      return sectionWahlbehoerdeRendered;
    }

    public boolean isPropertyWahlbehoerdeWahlleiterNameRendered() {
      return propertyWahlbehoerdeWahlleiterNameRendered;
    }

    public boolean isPropertyWahlbehoerdeAnschriftStrasseHausnummerRendered() {
      return propertyWahlbehoerdeAnschriftStrasseHausnummerRendered;
    }

    public boolean isPropertyWahlbehoerdeAnschriftOrtRendered() {
      return propertyWahlbehoerdeAnschriftOrtRendered;
    }

    public boolean isPropertyWahlbehoerdeAnschriftPlzRendered() {
      return propertyWahlbehoerdeAnschriftPlzRendered;
    }

    public boolean isSectionWahlbehoerdeDokumentErstelltRendered() {
      return sectionWahlbehoerdeDokumentErstelltRendered;
    }

    public boolean isPropertyWahlbehoerdeDokumentErstelltAnschriftStrasseHausnummerRendered() {
      return propertyWahlbehoerdeDokumentErstelltAnschriftStrasseHausnummerRendered;
    }

    public boolean isPropertyWahlbehoerdeDokumentErstelltAnschriftOrtRendered() {
      return propertyWahlbehoerdeDokumentErstelltAnschriftOrtRendered;
    }

    public boolean isPropertyWahlbehoerdeDokumentErstelltAnschriftPlzRendered() {
      return propertyWahlbehoerdeDokumentErstelltAnschriftPlzRendered;
    }

    public boolean isPropertyWahlbehoerdeDokumentErstelltAmRendered() {
      return propertyWahlbehoerdeDokumentErstelltAmRendered;
    }

    public boolean isSectionGewaehltesGremiumRendered() {
      return sectionGewaehltesGremiumRendered;
    }

    public boolean isPropertyGewaehltesGremiumDurchfuehrendesOrganRendered() {
      return propertyGewaehltesGremiumDurchfuehrendesOrganRendered;
    }

    public boolean isPropertyGewaehltesGremiumAnschriftStrasseHausnummerRendered() {
      return propertyGewaehltesGremiumAnschriftStrasseHausnummerRendered;
    }

    public boolean isPropertyGewaehltesGremiumAnschriftOrtRendered() {
      return propertyGewaehltesGremiumAnschriftOrtRendered;
    }

    public boolean isPropertyGewaehltesGremiumAnschriftPlzRendered() {
      return propertyGewaehltesGremiumAnschriftPlzRendered;
    }

    public boolean isSectionWahlausschusssitzungRendered() {
      return sectionWahlausschusssitzungRendered;
    }

    public boolean isPropertyWahlausschusssitzungAnschriftStrasseHausnummerRendered() {
      return propertyWahlausschusssitzungAnschriftStrasseHausnummerRendered;
    }

    public boolean isPropertyWahlausschusssitzungAnschriftOrtRendered() {
      return propertyWahlausschusssitzungAnschriftOrtRendered;
    }

    public boolean isPropertyWahlausschusssitzungAnschriftPlzRendered() {
      return propertyWahlausschusssitzungAnschriftPlzRendered;
    }

    public boolean isPropertyWahlausschusssitzungBeginnRendered() {
      return propertyWahlausschusssitzungBeginnRendered;
    }

    public boolean isPropertyWahlausschusssitzungEndeRendered() {
      return propertyWahlausschusssitzungEndeRendered;
    }

    public boolean isPropertyWahlausschusssitzungEinwaendeRendered() {
      return propertyWahlausschusssitzungEinwaendeRendered;
    }

    public boolean isPropertyWahlausschusssitzungEinwaendeBemerkungenRendered() {
      return propertyWahlausschusssitzungEinwaendeBemerkungenRendered;
    }

    public boolean isSectionWahlvorschlagPruefungUnterzeichnerRendered() {
      return sectionWahlvorschlagPruefungUnterzeichnerRendered;
    }

    public boolean isPropertyWahlvorschlagPruefungUnterzeichner1NameRendered() {
      return propertyWahlvorschlagPruefungUnterzeichner1NameRendered;
    }

    public boolean isPropertyWahlvorschlagPruefungUnterzeichner1RolleRendered() {
      return propertyWahlvorschlagPruefungUnterzeichner1RolleRendered;
    }

    public boolean isPropertyWahlvorschlagPruefungUnterzeichner2NameRendered() {
      return propertyWahlvorschlagPruefungUnterzeichner2NameRendered;
    }

    public boolean isPropertyWahlvorschlagPruefungUnterzeichner2RolleRendered() {
      return propertyWahlvorschlagPruefungUnterzeichner2RolleRendered;
    }

    public boolean isSectionWahlvorschlagPruefungFristZuletztGesetztRendered() {
      return sectionWahlvorschlagPruefungFristZuletztGesetztRendered;
    }

    public boolean isPropertyWahlvorschlagPruefungFristZuletztGesetztBeginnRendered() {
      return propertyWahlvorschlagPruefungFristZuletztGesetztBeginnRendered;
    }

    public boolean isPropertyWahlvorschlagPruefungFristZuletztGesetztEndeRendered() {
      return propertyWahlvorschlagPruefungFristZuletztGesetztEndeRendered;
    }

    public boolean isSectionWahlvorschlagEinreichungRendered() {
      return sectionWahlvorschlagEinreichungRendered;
    }

    public boolean isPropertyWahlvorschlagEinreichungAnschriftOrtRendered() {
      return propertyWahlvorschlagEinreichungAnschriftOrtRendered;
    }

    public boolean isPropertyWahlvorschlagEinreichungAbgabefristRendered() {
      return propertyWahlvorschlagEinreichungAbgabefristRendered;
    }

    public boolean isSectionWahlvorschlagEinreichungUnterzeichnerRendered() {
      return sectionWahlvorschlagEinreichungUnterzeichnerRendered;
    }

    public boolean isPropertyWahlvorschlagEinreichungUnterzeichner1NameRendered() {
      return propertyWahlvorschlagEinreichungUnterzeichner1NameRendered;
    }

    public boolean isSectionWahlvorschlagVeroeffentlichungRendered() {
      return sectionWahlvorschlagVeroeffentlichungRendered;
    }

    public boolean isPropertyWahlvorschlagVeroeffentlichungAnschriftOrtRendered() {
      return propertyWahlvorschlagVeroeffentlichungAnschriftOrtRendered;
    }

    public boolean isPropertyWahlvorschlagVeroeffentlichungBeginnRendered() {
      return propertyWahlvorschlagVeroeffentlichungBeginnRendered;
    }

    public boolean isSectionWahlvorschlagVeroeffentlichungUnterzeichnerRendered() {
      return sectionWahlvorschlagVeroeffentlichungUnterzeichnerRendered;
    }

    public boolean isPropertyWahlvorschlagVeroeffentlichungUnterzeichner1NameRendered() {
      return propertyWahlvorschlagVeroeffentlichungUnterzeichner1NameRendered;
    }

    public boolean isSectionEinwohnerzahlVeroeffentlichungRendered() {
      return sectionEinwohnerzahlVeroeffentlichungRendered;
    }

    public boolean isPropertyEinwohnerzahlVeroeffentlichungIdRendered() {
      return propertyEinwohnerzahlVeroeffentlichungIdRendered;
    }

    public boolean isPropertyEinwohnerzahlVeroeffentlichungDatumRendered() {
      return propertyEinwohnerzahlVeroeffentlichungDatumRendered;
    }
  }
}
