private boolean addInvoice0(final I_C_Invoice invoice) {
    //
    // Skip not posted invoices, but warn the user
    if (!invoice.isPosted()) {
      loggable.addLog("@Error@: @C_Invoice_ID@ @Posted@=@N@: " + invoiceBL.getSummary(invoice));
      return false;
    }

    //
    // Tax declaration lines (one for each invoice tax record)
    final List<I_C_InvoiceTax> invoiceTaxes = invoiceDAO.retrieveTaxes(invoice);
    final Map<Integer, I_C_TaxDeclarationLine> taxId2taxDeclarationLine =
        new HashMap<>(invoiceTaxes.size());
    for (final I_C_InvoiceTax invoiceTax : invoiceTaxes) {
      final int taxId = invoiceTax.getC_Tax_ID();
      final I_C_TaxDeclarationLine taxDeclarationLine =
          createTaxDeclarationLine(invoice, invoiceTax);
      final I_C_TaxDeclarationLine taxDeclarationLineOld =
          taxId2taxDeclarationLine.put(taxId, taxDeclarationLine);
      Check.assumeNull(
          taxDeclarationLineOld,
          "More than one invoice tax line for {0}, taxId={1}",
          invoice,
          taxId);
    }

    //
    // Tax declaration accounting records
    final List<I_Fact_Acct> factAcctRecords =
        factAcctDAO
            .retrieveQueryForDocument(invoice)
            // fetch only those Fact_Acct records which are about taxes, i.e.
            .addNotEqualsFilter(I_Fact_Acct.COLUMN_C_Tax_ID, null) // C_Tax_ID is set
            .addEqualsFilter(I_Fact_Acct.COLUMN_Line_ID, null) // Line_ID is NOT set
            //
            .create()
            .list();
    for (final I_Fact_Acct factAcctRecord : factAcctRecords) {
      //
      // Link to Tax Declaration Line only if this Fact_Acct is about tax bookings. Which means:
      // * it's document level booking (Line_ID <= 0)
      // * we have a C_TaxDeclarationLine which has the same tax as this booking
      I_C_TaxDeclarationLine taxDeclarationLine = null;
      if (factAcctRecord.getLine_ID() <= 0) {
        final int taxId = factAcctRecord.getC_Tax_ID();
        taxDeclarationLine = taxId2taxDeclarationLine.get(taxId);
      }

      createTaxDeclarationAcct(taxDeclarationLine, factAcctRecord);
    }

    return true;
  }
  private final I_C_TaxDeclarationLine createTaxDeclarationLine(
      final I_C_Invoice invoice, final I_C_InvoiceTax invoiceTax) {
    final I_C_TaxDeclarationLine taxDeclarationLine = newTaxDeclarationLine();

    taxDeclarationLine.setAD_Org_ID(invoice.getAD_Org_ID());
    taxDeclarationLine.setIsManual(false);
    //
    taxDeclarationLine.setC_Invoice(invoice);
    taxDeclarationLine.setIsSOTrx(invoice.isSOTrx());
    taxDeclarationLine.setC_BPartner_ID(invoice.getC_BPartner_ID());
    taxDeclarationLine.setC_Currency_ID(invoice.getC_Currency_ID());
    taxDeclarationLine.setDateAcct(invoice.getDateAcct());
    taxDeclarationLine.setC_DocType_ID(invoice.getC_DocType_ID());
    taxDeclarationLine.setDocumentNo(invoice.getDocumentNo());
    //
    taxDeclarationLine.setC_Tax_ID(invoiceTax.getC_Tax_ID());
    taxDeclarationLine.setTaxBaseAmt(invoiceTax.getTaxBaseAmt());
    taxDeclarationLine.setTaxAmt(invoiceTax.getTaxAmt());

    save(taxDeclarationLine);

    return taxDeclarationLine;
  }