
package de.ivu.elect.dokumente.ergebnis.gesamtergebnis;

import static java.util.stream.Collectors.toList;
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.function.Function;

import javax.inject.Inject;

import de.ivu.elect.business.dokumente.entity.NoDokumentExtraFileOutput;
import de.ivu.elect.business.ergebnis.control.ErgebnisDaten;
import de.ivu.elect.business.ergebnis.control.gesamtergebnis.ErgebnisGesamtergebnisTabellarischDocumentExportContext;
import de.ivu.elect.business.ergebnis.entity.Ergebnisart;
import de.ivu.elect.business.gebietsbaum.boundary.WahlverwaltungGebietDescriptor;
import de.ivu.elect.business.gebietsbaum.boundary.WahlverwaltungGebietInformation;
import de.ivu.elect.business.gebietsbaum.entity.Wahldurchfuehrungsgebiet;
import de.ivu.elect.dokumente.BaseElectContext;
import de.ivu.elect.dokumente.ergebnis.AbstractErgebnisDocumentExportMapper;
import de.ivu.elect.dokumente.ergebnis.ErgebnisDocumentDatenGebietDocument;
import de.ivu.elect.was.exchange.ergebnis.gesamtergebnis.ErgebnisGesamtergebnisExchange;
import de.ivu.elect.was.exchange.ergebnis.gesamtergebnis.ErgebnisGesamtergebnisTabellarischDocumentExportMapper;

/**
 * Zur Nomenklatur SEITEN und TEILE...
 *
 * <pre>
 * ____________________________________________________________________________________________________________________________
 * | SEITE 1/3, TEIL 1/10           | SEITE 2/3, TEIL 1/10                          | SEITE 3/3, TEIL 1/10                     |
 * |_Gemeinde A Kopfzahlen (Urne)___|_Gemeinde A Gültige/Ungültige/Stimmen (Urne)___|_Gemeinde A Stimmen_(Urne, Fortsetzung)___|
 * ____________________________________________________________________________________________________________________________
 * | SEITE 1/3, TEIL 2/10           | SEITE 2/3, TEIL 2/10                          | SEITE 3/3, TEIL 2/10                     |
 * |_Gemeinde A Kopfzahlen (Brief)__|_Gemeinde A Gültige/Ungültige/Stimmen (Brief)__|_Gemeinde A Stimmen_(Brief, Fortsetzung)__|
 * ____________________________________________________________________________________________________________________________
 * | SEITE 1/3, TEIL 3/10           | SEITE 2/3, TEIL 3/10                          | SEITE 3/3, TEIL 3/10                     |
 * |_Gemeinde A Kopfzahlen (Gesamt)_|_Gemeinde A Gültige/Ungültige/Stimmen (Gesamt)_|_Gemeinde A Stimmen_(Gesamt, Fortsetzung)_|
 * ...
 * ____________________________________________________________________________________________________________________________
 * | SEITE 1/3, TEIL 8/10           | SEITE 2/3, TEIL 8/10                          | SEITE 3/3, TEIL 8/10                     |
 * |_Gemeinde X Kopfzahlen (Urne)___|_Gemeinde X Gültige/Ungültige/Stimmen (Urne)___|_Gemeinde X Stimmen_(Urne, Fortsetzung)___|
 * ____________________________________________________________________________________________________________________________
 * | SEITE 1/3, TEIL 9/10           | SEITE 2/3, TEIL 9/10                          | SEITE 3/3, TEIL 9/10                     |
 * |_Gemeinde X Kopfzahlen (Brief)__|_Gemeinde X Gültige/Ungültige/Stimmen (Brief)__|_Gemeinde X Stimmen_(Brief, Fortsetzung)__|
 * ____________________________________________________________________________________________________________________________
 * | SEITE 1/3, TEIL 10/10          | SEITE 2/3, TEIL 10/10                         | SEITE 3/3, TEIL 10/10                    |
 * |_Gemeinde X Kopfzahlen (Gesamt)_|_Gemeinde X Gültige/Ungültige/Stimmen (Gesamt)_|_Gemeinde X Stimmen_(Gesamt, Fortsetzung)_|
 *
 * </pre>
 *
 * <ul>
 * <li>TEILE
 * <ul>
 * <li>nummerieren die Zeilen in der oberen Matrix</li>
 * <li>passen die Zeilen einer Tabelle per Stimmenart nicht auf eine ODT-Seite, entsteht ein neuer TEIL</li>
 * </ul>
 * </li>
 * <li>SEITEN
 * <ul>
 * <li>nummerieren die Spalten in der oberen Matrix</li>
 * <li>passen die Spalten einer Tabelle per Stimmenart nicht auf eine ODT-Seite, entsteht eine neue SEITE</li>
 * </ul>
 * </li>
 * </ul>
 *
 * @see ReferendumErgebnisGesamtergebnisTabellarischDocumentExportMapper!!!
 * @see AbstractGruppenErgebnistabelleExportMapper!!!
 */
public abstract class AbstractErgebnisGesamtergebnisTabellarischDocumentExportMapper
    extends
      AbstractErgebnisDocumentExportMapper<ErgebnisGesamtergebnisTabellarischDocumentExportContext, Wahldurchfuehrungsgebiet, WahlverwaltungGebietInformation, ErgebnisGesamtergebnisTabellarischDocument>
    implements
      ErgebnisGesamtergebnisTabellarischDocumentExportMapper,
      ErgebnisGesamtergebnisExchange {

  @Inject
  private transient ErgebnisGesamtergebnisTabellarischDocumentCreator documentCreator;

  @Inject
  private transient ErgebnisGesamtergebnisTabellarischDocumentZeileCreator documentZeileCreator;

  @Inject
  private transient ErgebnisGesamtergebnisTabellarischDocumentAufteiler documentAufteiler;

  public AbstractErgebnisGesamtergebnisTabellarischDocumentExportMapper(String erfassungsgebietGebietsreferenzFormat) {
    super(erfassungsgebietGebietsreferenzFormat);
  }

  @Override
  protected Function<ErgebnisGesamtergebnisTabellarischDocument, File> getTemplateFileByDocumentFinder(ErgebnisGesamtergebnisTabellarischDocumentExportContext context, ErgebnisDaten ergebnisDaten) {
    Map<ErgebnisGesamtergebnisTabellarischDocumentDokumentVorlageArt, File> templateFilePerDokumentVorlageArt = collectTemplateFilePerDokumentVorlageArt(context);

    return document -> {
      if (templateFilePerDokumentVorlageArt.containsKey(document.dokumentVorlageArt)) {
        return templateFilePerDokumentVorlageArt.get(document.dokumentVorlageArt);
      }

      throw new RuntimeException("Kein Template zum Generieren eines ODT-Dokumentes gefunden [seite = " + document.seitenNummer + ", teil = " + document.teilNummer + ", dokumentVorlageArt = "
          + document.dokumentVorlageArt + "]!");
    };
  }

  private Map<ErgebnisGesamtergebnisTabellarischDocumentDokumentVorlageArt, File> collectTemplateFilePerDokumentVorlageArt(ErgebnisGesamtergebnisTabellarischDocumentExportContext context) {
    Map<ErgebnisGesamtergebnisTabellarischDocumentDokumentVorlageArt, File> result = new HashMap<>();

    if (context.hasDokumentVorlageGesamtergebnis()) {
      result.put(ErgebnisGesamtergebnisTabellarischDocumentDokumentVorlageArt.GESAMTERGEBNIS, getTemplateFile(context.getDokumentVorlageGesamtergebnis()));
    }

    if (context.hasDokumentVorlageErsteSeiteDirektstimmen()) {
      result.put(ErgebnisGesamtergebnisTabellarischDocumentDokumentVorlageArt.DIREKTSTIMMEN_ERSTE_SEITE_ANDERS, getTemplateFile(context.getDokumentVorlageErsteSeiteDirektstimmen()));
    }

    if (context.hasDokumentVorlageWeitereSeitenDirektstimmen()) {
      result.put(ErgebnisGesamtergebnisTabellarischDocumentDokumentVorlageArt.DIREKTSTIMMEN, getTemplateFile(context.getDokumentVorlageWeitereSeitenDirektstimmen()));
    } else if (context.hasDokumentVorlageErsteSeiteDirektstimmen()) {
      result.put(ErgebnisGesamtergebnisTabellarischDocumentDokumentVorlageArt.DIREKTSTIMMEN, getTemplateFile(context.getDokumentVorlageErsteSeiteDirektstimmen()));
    }

    if (context.hasDokumentVorlageErsteSeiteListenstimmen()) {
      result.put(ErgebnisGesamtergebnisTabellarischDocumentDokumentVorlageArt.LISTENSTIMMEN_ERSTE_SEITE_ANDERS, getTemplateFile(context.getDokumentVorlageErsteSeiteListenstimmen()));
    }

    if (context.hasDokumentVorlageWeitereSeitenListenstimmen()) {
      result.put(ErgebnisGesamtergebnisTabellarischDocumentDokumentVorlageArt.LISTENSTIMMEN, getTemplateFile(context.getDokumentVorlageWeitereSeitenListenstimmen()));
    } else if (context.hasDokumentVorlageErsteSeiteListenstimmen()) {
      result.put(ErgebnisGesamtergebnisTabellarischDocumentDokumentVorlageArt.LISTENSTIMMEN, getTemplateFile(context.getDokumentVorlageErsteSeiteListenstimmen()));
    }

    return result;
  }

  @Override
  protected List<Wahldurchfuehrungsgebiet> collectAuswertungseinheiten(ErgebnisGesamtergebnisTabellarischDocumentExportContext context, ErgebnisDaten ergebnisDaten) {
    return collectAuswertungsgebieteOderWurzelgebiet(context, ergebnisDaten);
  }

  @Override
  protected Map<WahlverwaltungGebietInformation, List<ErgebnisGesamtergebnisTabellarischDocument>> createDocuments(ErgebnisGesamtergebnisTabellarischDocumentExportContext context,
      ErgebnisDaten ergebnisDaten, List<Wahldurchfuehrungsgebiet> auswertungsgebiete) {
    // ELECTKOM-409, ELECTKOM-481
    return createDocuments(context, ergebnisDaten, auswertungsgebiete, context.isDocumentsCreatedPerStimmzettelgebiet(), context.isDocumentsCreatedPerGemeinde());
  }

  // Cf. ReferendumErgebnisGesamtergebnisTabellarischDocumentExportMapper#createDocuments!!!
  protected Map<WahlverwaltungGebietInformation, List<ErgebnisGesamtergebnisTabellarischDocument>> createDocuments(ErgebnisGesamtergebnisTabellarischDocumentExportContext context,
      ErgebnisDaten ergebnisDaten, List<Wahldurchfuehrungsgebiet> auswertungsgebiete, boolean documentsCreatedPerStimmzettelgebiet, boolean documentsCreatedPerGemeinde) {
    Map<WahlverwaltungGebietInformation, List<ErgebnisGesamtergebnisTabellarischDocument>> result = new HashMap<>();

    Ergebnisart ergebnisart = ergebnisDaten.getErgebnis().getErgebnisart();

    for (Entry<WahlverwaltungGebietInformation, SortedMap<WahlverwaltungGebietInformation, List<ErgebnisGesamtergebnisTabellarischDocumentZeile>>> entryPerStimmzettelgebiet : collectErfassungsgebieteInAuswertungsgebietenMappedPerGemeindePerStimmzettelgebiet(
        context, ergebnisDaten, auswertungsgebiete).entrySet()) {
      WahlverwaltungGebietInformation stimmzettelgebietInformation = entryPerStimmzettelgebiet.getKey();

      SortedMap<WahlverwaltungGebietInformation, List<ErgebnisGesamtergebnisTabellarischDocumentZeile>> entriesPerGemeinde = entryPerStimmzettelgebiet.getValue();

      info("\tErzeuge Dokumente für Stimmzettelgebiet [ergebnisart = " + ergebnisart + ", art = " + stimmzettelgebietInformation.getArt() + "/" + stimmzettelgebietInformation.getArtIndex()
          + ", nummer = " + stimmzettelgebietInformation.getNummer() + ", name = " + stimmzettelgebietInformation.getName() + ", gebiet in gebietsbaum = "
          + stimmzettelgebietInformation.getGebiet().isPresent() + ", odt-seiten erzeugt = pro" + (documentsCreatedPerStimmzettelgebiet ? " stimmzettelgebiet" : "")
          + (documentsCreatedPerGemeinde ? " gemeinde" : "") + "]");

      if (documentsCreatedPerStimmzettelgebiet) {
        result.put(stimmzettelgebietInformation, createDocuments(context, stimmzettelgebietInformation, entriesPerGemeinde));
      }

      if (documentsCreatedPerGemeinde) {
        Comparator< ? super WahlverwaltungGebietInformation> entryPerGemeindeComparator = entriesPerGemeinde.comparator();

        for (Entry<WahlverwaltungGebietInformation, List<ErgebnisGesamtergebnisTabellarischDocumentZeile>> entryPerGemeinde : entriesPerGemeinde.entrySet()) {
          result.put(entryPerGemeinde.getKey(), createDocuments(context, stimmzettelgebietInformation, asSingletonSortedMap(entryPerGemeinde, entryPerGemeindeComparator)));
        }
      }
    }

    return result;
  }

  protected List<ErgebnisGesamtergebnisTabellarischDocument> createDocuments(ErgebnisGesamtergebnisTabellarischDocumentExportContext context,
      WahlverwaltungGebietInformation stimmzettelgebietInformation, SortedMap<WahlverwaltungGebietInformation, List<ErgebnisGesamtergebnisTabellarischDocumentZeile>> zeilenPerGemeinde) {
    return createDocuments(context, stimmzettelgebietInformation, zeilenPerGemeinde, context.isTabellenCreatedPerDatenArt(), context.isTabellenCreatedPseudoGemeindeGesamt());
  }

  protected List<ErgebnisGesamtergebnisTabellarischDocument> createDocuments(ErgebnisGesamtergebnisTabellarischDocumentExportContext context,
      WahlverwaltungGebietInformation stimmzettelgebietInformation, SortedMap<WahlverwaltungGebietInformation, List<ErgebnisGesamtergebnisTabellarischDocumentZeile>> zeilenPerGemeinde,
      boolean tabellenCreatedPerDatenArt, boolean tabellenCreatedPseudoGemeindeGesamt) {
    List<ErgebnisGesamtergebnisTabellarischDocument> result = new ArrayList<>();

    for (Entry<WahlverwaltungGebietInformation, List<ErgebnisGesamtergebnisTabellarischDocumentZeile>> entryPerGemeinde : zeilenPerGemeinde.entrySet()) {
      WahlverwaltungGebietInformation gemeindeInformation = entryPerGemeinde.getKey();
      List<ErgebnisGesamtergebnisTabellarischDocumentZeile> zeilenInGemeinde = entryPerGemeinde.getValue();

      info("\t\tErzeuge Tabellen für Gemeinde [art = " + gemeindeInformation.getArt() + "/" + gemeindeInformation.getArtIndex() + ", nummer = " + gemeindeInformation.getNummer() + ", name = "
          + gemeindeInformation.getName() + ", gebiet in gebietsbaum = " + gemeindeInformation.getGebiet().isPresent() + ", tabellen = "
          + (tabellenCreatedPerDatenArt ? "per stimmabgabeart" : "kompakt") + ", summentabellen = " + tabellenCreatedPseudoGemeindeGesamt + "]");

      // Debugging...
      //      for (ErgebnisGesamtergebnisTabellarischDocumentZeile zeile : zeilenInGemeinde) {
      //        info("\t\t\t " + zeile);
      //      }

      result.addAll(createTabellen(context, tabellenCreatedPerDatenArt, gemeindeInformation, zeilenInGemeinde));
    }

    // NOTE, dass, falls mehr als eine Gemeinde unterhalb des Stimmzettelgebiets existiert, die Werte aller Gemeinden/Stadtbezirke nochmals zu einer Pseudo-Gemeinde "Gesamt"
    // aggregiert werden und Tabellen für diese Pseudo-Gemeinde "Gesamt" zusätzlich ins ODT-Dokument geschrieben werden!
    if (tabellenCreatedPseudoGemeindeGesamt && zeilenPerGemeinde.size() > 1) {
      List<ErgebnisGesamtergebnisTabellarischDocumentZeile> zeilenInStimmzettelgebiet = zeilenPerGemeinde.values().stream().flatMap(List::stream).collect(toList());

      info("\t\tErzeuge Summentabellen (Pseudo-Gemeinde \"Gesamt\") [art = Pseudo-Gemeinde \"Gesamt\", nummer = " + ErgebnisDocumentDatenGebietDocument.PSEUDO_GEMEINDE_GESAMT_NUMMER + ", name = "
          + ErgebnisDocumentDatenGebietDocument.PSEUDO_GEMEINDE_GESAMT_NAME + ", gebiet in gebietsbaum = " + false + ", tabellen = " + (tabellenCreatedPerDatenArt ? "per stimmabgabeart" : "kompakt")
          + ", summentabellen = " + tabellenCreatedPseudoGemeindeGesamt + "]");

      result.addAll(createSummenTabellen(context, tabellenCreatedPerDatenArt, stimmzettelgebietInformation, zeilenInStimmzettelgebiet));
    }

    postProcessSeitenUndTeile(result);

    return result;
  }

  protected void postProcessSeitenUndTeile(List<ErgebnisGesamtergebnisTabellarischDocument> documents) {
    documentAufteiler.postProcessSeitenUndTeile(documents);
  }

  // Cf. ReferendumErgebnisGesamtergebnisTabellarischDocumentExportMapper#collectErfassungsgebieteInAuswertungsgebietenMappedPerGemeindePerStimmzettelgebiet!!!
  private SortedMap<WahlverwaltungGebietInformation, SortedMap<WahlverwaltungGebietInformation, List<ErgebnisGesamtergebnisTabellarischDocumentZeile>>> collectErfassungsgebieteInAuswertungsgebietenMappedPerGemeindePerStimmzettelgebiet(
      ErgebnisGesamtergebnisTabellarischDocumentExportContext context, ErgebnisDaten ergebnisDaten, List<Wahldurchfuehrungsgebiet> auswertungsgebiete) {
    return collectErfassungsgebieteInAuswertungsgebietenMappedPerGemeindePerStimmzettelgebiet(ergebnisDaten, auswertungsgebiete, (stimmzettelgebietInformation, gemeindeInformation,
        erfassungsgebietDescriptor) -> createDocumentZeile(context, ergebnisDaten, stimmzettelgebietInformation, gemeindeInformation, erfassungsgebietDescriptor));
  }

  protected ErgebnisGesamtergebnisTabellarischDocumentZeile createDocumentZeile(ErgebnisGesamtergebnisTabellarischDocumentExportContext context, ErgebnisDaten ergebnisDaten,
      WahlverwaltungGebietInformation stimmzettelgebietInformation, WahlverwaltungGebietInformation gemeindeInformation, WahlverwaltungGebietDescriptor erfassungsgebietDescriptor) {
    ErgebnisGesamtergebnisTabellarischDocumentZeile result = documentZeileCreator.createZeile(ergebnisDaten, getErfassungsgebietGebietsreferenzFormat(), stimmzettelgebietInformation,
        gemeindeInformation, erfassungsgebietDescriptor);

    if (!result.isDatenArtZwischensumme() && result.wahlbezirk.isSonderstimmbezirk) {
      result.name = addErfassungsgebietGebietsreferenzSuffixSonderstimmbezirk(context, result.name);

      result.wahlbezirk.nummerFormatiert = addErfassungsgebietGebietsreferenzSuffixSonderstimmbezirk(context, defaultIfBlank(result.wahlbezirk.nummerFormatiert, result.wahlbezirk.nummer));

      result.wahlbezirkGebietsreferenz10Stellig = addErfassungsgebietGebietsreferenzSuffixSonderstimmbezirk(context, result.wahlbezirkGebietsreferenz10Stellig);
      result.wahlbezirkGebietsreferenz10StelligFormatiert = addErfassungsgebietGebietsreferenzSuffixSonderstimmbezirk(context, result.wahlbezirkGebietsreferenz10StelligFormatiert);
      result.wahlbezirkGebietsreferenz13Stellig = addErfassungsgebietGebietsreferenzSuffixSonderstimmbezirk(context, result.wahlbezirkGebietsreferenz13Stellig);
      result.wahlbezirkGebietsreferenz13StelligFormatiert = addErfassungsgebietGebietsreferenzSuffixSonderstimmbezirk(context, result.wahlbezirkGebietsreferenz13StelligFormatiert);
    }

    return result;
  }

  protected List<ErgebnisGesamtergebnisTabellarischDocument> createTabellen(ErgebnisGesamtergebnisTabellarischDocumentExportContext context, boolean tabellenCreatedPerDatenArt,
      WahlverwaltungGebietInformation datenGebietInformation, List<ErgebnisGesamtergebnisTabellarischDocumentZeile> zeilenInDatenGebiet) {
    List<ErgebnisGesamtergebnisTabellarischDocument> result = new ArrayList<>();

    BaseElectContext baseElectContext = createBaseElectContext(context, NoDokumentExtraFileOutput.INSTANCE);
    Ergebnisart ergebnisart = context.getErgebnisart();

    if (tabellenCreatedPerDatenArt) {
      result.addAll(teileAufSeitenUndTeile(documentCreator.createDocumentFuerDatenArtUrnenwahl(baseElectContext, ergebnisart, datenGebietInformation, zeilenInDatenGebiet), context));
      result.addAll(teileAufSeitenUndTeile(documentCreator.createDocumentFuerDatenArtBriefwahl(baseElectContext, ergebnisart, datenGebietInformation, zeilenInDatenGebiet), context));
      result.addAll(teileSummenAufSeitenAuf(documentCreator.createDocumentFuerDatenArtGesamt(baseElectContext, ergebnisart, datenGebietInformation, zeilenInDatenGebiet), context));
    } else {
      result.addAll(teileAufSeitenUndTeile(documentCreator.createDocumentAlleDatenArten(baseElectContext, ergebnisart, datenGebietInformation, zeilenInDatenGebiet), context));
    }

    return result;
  }

  protected Collection<ErgebnisGesamtergebnisTabellarischDocument> createSummenTabellen(ErgebnisGesamtergebnisTabellarischDocumentExportContext context, boolean tabellenCreatedPerDatenArt,
      WahlverwaltungGebietInformation datenGebietInformation, List<ErgebnisGesamtergebnisTabellarischDocumentZeile> zeilenInDatenGebiet) {
    List<ErgebnisGesamtergebnisTabellarischDocument> result = new ArrayList<>();

    BaseElectContext baseElectContext = createBaseElectContext(context, NoDokumentExtraFileOutput.INSTANCE);
    Ergebnisart ergebnisart = context.getErgebnisart();

    if (tabellenCreatedPerDatenArt) {
      result.addAll(teileSummenAufSeitenAuf(documentCreator.createSummenDocumentFuerDatenArtUrnenwahl(baseElectContext, ergebnisart, datenGebietInformation, zeilenInDatenGebiet), context));
      result.addAll(teileSummenAufSeitenAuf(documentCreator.createSummenDocumentFuerDatenArtBriefwahl(baseElectContext, ergebnisart, datenGebietInformation, zeilenInDatenGebiet), context));
      result.addAll(teileSummenAufSeitenAuf(documentCreator.createSummenDocumentFuerDatenArtGesamt(baseElectContext, ergebnisart, datenGebietInformation, zeilenInDatenGebiet), context));
    } else {
      result.addAll(teileSummenAufSeitenAuf(documentCreator.createSummenDocumentAlleDatenArten(baseElectContext, ergebnisart, datenGebietInformation, zeilenInDatenGebiet), context));
    }

    return result;
  }

  private List<ErgebnisGesamtergebnisTabellarischDocument> teileAufSeitenUndTeile(ErgebnisGesamtergebnisTabellarischDocument document,
      ErgebnisGesamtergebnisTabellarischDocumentExportContext context) {
    return documentAufteiler.createDocumentCopiesHavingConfiguredAnzahlZeilenAndAnzahlSpalten(document, context.getAnzahlZeilenProSeite(), context);
  }

  // Tabellen für "Summen" enthalten nur eine Summenzeile (und ggf. Urnen-/Briefwahl-Zwischensummen als Inhaltszeilen bei der kompakten Darstellung), daher nur Aufteilung nach Seiten!
  private List<ErgebnisGesamtergebnisTabellarischDocument> teileSummenAufSeitenAuf(ErgebnisGesamtergebnisTabellarischDocument document,
      ErgebnisGesamtergebnisTabellarischDocumentExportContext context) {
    List<ErgebnisGesamtergebnisTabellarischDocument> result = documentAufteiler.createDocumentCopiesHavingConfiguredAnzahlSpalten(document, context);

    for (ErgebnisGesamtergebnisTabellarischDocument teil : result) {
      teil.zeilen.removeIf(zeile -> !zeile.isDatenArtZwischensumme()); // ELECTKOM-416
    }

    return result;
  }
}
