package elektra;

import java.io.*;
import java.util.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
import de.orestes.XMLParseSpecial;

import com.paypal.sdk.core.nvp.NVPDecoder;
import com.paypal.sdk.core.nvp.NVPEncoder;
import com.paypal.sdk.profiles.APIProfile;
import com.paypal.sdk.profiles.ProfileFactory;
import com.paypal.sdk.services.NVPCallerServices;

//import gnu.inet.encoding.IDNA;
//import gnu.inet.encoding.IDNAException;

/**
 * Servlet, welches als Interface zwischen dem Browser und dem Appliaktionsserver
 * fungiert.
 * Bei WebOrder wird per Anzahl der Karten pro PG/Ermaessigung gebucht, bei WebBook per Kartenindex
 * Folgende Daten werden angenommen und weitergeleitet:<br>
 * - Systemnummer<br>
 * - Mandantennummer<br>
 * - Eventnummer<br>
 * - Shownummer<br>
 * - Preisgruppe<br>
 * - Anzahl Karten<br>
 * - Adresse des Kunden (Name, Strasse, PLZ, Ort, Telefon, eMail)<br>
 * Zurueckgesendet werden:<br>
 * - Auftragsnummer<br>
 * - Kundennummer<br>
 * - Optionsdatum<br>
 *
 * @author Karsten Rolfs, Orestes GmbH
 *
 * @since 8.3.2000: Umstellung auf Property-File "elektra.properties"<br>
 * @since 14.7.2000: Erweiterung Interface um Actioncode, Positionen, Auftragstypem, etc.<br>
 * @since 6.11.2000: Wenn kein Kreditkartenbesitzer eingetragen ist, den Namen verwenden<br>
 * @since 7.12.2000: External payment (Zahlart "y")<br>
 * @since 27.8.2001: Erweiterung um mehrere Ermaessigungen<br>
 * @since 25.03.2002: Erweiterung um CVC (wird an Kreditkartennummer angehaengt)<br>
 * @since 06.03.2003: Erweiterung um StandardReduction<br>
 * @since 01.08.2003: Erweiterung um MailFrom<br>
 * @since 06.10.2003: Erweiterung um Lieferanschrift<br>
 * @since 30.12.2003: Erweiterung um Ebene/Seite<br>
 * @since 06.01.2004: Erweiterung um Multiorder<br>
 * @since 28.04.2005: Bei Fehlermeldungen wird der ErrorBodyStart etc. aufgerufen<br>
 * @since 10.05.2005: Zusammen als Default<br>
 * @since 11.08.2005: Erweiterung um print@home<br>
 * @since 31.03.2006: Erweiterung um Voucher, JSP dispatch aus elektra.properties, Debitoren<br>
 * @since 07.06.2006: Erweiterung um Reply-Adresse<br>
 * @since 12.10.2007: Erweiterung um Special<br>
 * @since 30.04.2008: Erweiterung um IBAN/Swift<br>
 * @since 30.03.2009: Umstellung auf MailSender-Klasse<br>
 * @since 23.02.2009: Umstellung auf Configuration, Erweiterung um QPay, Mail nur bei erfolgreicher Buchung<br>
 * @since 14.06.2010: Default encoding aus properties
 * @since 2011: mit PayPal
 * @since 04.11.2011: Erweiterung um mehrere Zahlarten
 */

public class WebOrderPaypal extends HttpServlet
{
  private static final long serialVersionUID = 4L;

  /** Name der Konfigurationsdatei aus der web.xml */
  protected String szElektraConfig = "";
  /** Adresse/Name des Applikationsservers, definiert in elektra.properties */
  protected String szElektraServer = "";
  /** Port des Applikationsservers, definiert in elektra.properties */
  protected String szElektraServerPort = "";
  /** Adresse/Name des Mailservers, definiert in elektra.properties */
  protected String szMailServer = "";
  /** gewuenschte From-Adresse, definiert in elektra.properties */
  protected String szMailFrom = "";
  /** Liste der CC-Adressen, definiert in elektra.properties */
  protected String szMailCC = "";
  /** Liste der BCC-Adressen, definiert in elektra.properties */
  protected String szMailBCC = "";
  /** Liste der Reply-Adressen, definiert in elektra.properties */
  protected String szMailReply = "";
  /** Benutzer auf Mailserver: optional, definiert in elektra.properties */
  protected String szMailUserName = "";
  /** Passwort auf Mailserver: optional, definiert in elektra.properties */
  protected String szMailUserPassword = "";

  /** Standardlaenderkennzeichen, definiert in elektra.properties */
  protected String szDefaultCountry = "";

  /** Requestnummer im Interface. Muss "3" enthalten */
  protected String szRequest = "3";           // 1 : Request, 2: Buchung, 3: Auftrag (wie bisher)
  /** Interface-Version  */
  protected Integer version = 280;                 // mit IBAN/Swift
  
  /** Debuglevel 0-5, wird in der web.xml eingestellt */
  protected Integer nDebug;
  /** Anzahl der moeglichen Applikationsserver */
  protected Integer nWebBookCount;
  protected int nNoRed = 0;
  protected int nFirstRed = 1;
  protected int nFirstPG = 0;

  protected String strVerteilerXML = "";
  protected String strJSP = "";
  protected String strJSPError = "";
  protected String strJSPReload = "";
  protected String formname = "";
  protected String formnameerr = "";
  protected String strDispatch = "";
  protected String defaultEncoding;

  private ServletContext context;
  Properties props;

  NVPCallerServices caller = null;

  /*******************************************************************************************************
  * Globale Variablen initialisieren
  */
  @Override
  public void init(ServletConfig config) throws ServletException
  {
    super.init(config);

    // Remember context
    context = config.getServletContext();

    try { szElektraConfig = context.getInitParameter("ElektraConfig"); } catch (Exception e) { e.printStackTrace(); }
    if (null == szElektraConfig)
    {
      throw new ServletException("Servlet configuration property \"ElektraConfig\" is not defined!");
    }

    String szDebug = "";
    try { szDebug = context.getInitParameter("Debug"); } catch (Exception e) { e.printStackTrace(); }
    if (null == szDebug)
      nDebug = new Integer(0);
    else
      nDebug = new Integer(szDebug);

    // Properties laden
    props = new Properties();
    try
    {
      props.load(new FileInputStream(szElektraConfig));

      strVerteilerXML = props.getProperty("SpecialXML");
      strJSP = props.getProperty("OrderPage");
      if (null == strJSP)
        strJSP = "/jsp/weborder.jsp";
      strJSPError = props.getProperty("OrderErrorPage");
      if (null == strJSPError)
        strJSPError = "/jsp/webordererr.jsp";
      strJSPReload = props.getProperty("OrderReloadPage");
      if (null == strJSPReload)
        strJSPReload = "/jsp/weborderreload.jsp";

      defaultEncoding = props.getProperty("Charset");

    }
    catch (IOException ex)
    {
      ex.printStackTrace();
    }

  }

  /*******************************************************************************************************
  * Debug-Ausgabe
  */
  void WriteDebug(HttpServletResponse response, String szText, ResourceBundle resource, Exception e)
  {
    if (nDebug.intValue() > 0)
      System.out.println(szText);
    if (nDebug.intValue() > 1)
      e.printStackTrace();
    if (nDebug.intValue() > 2)
    {
      response.setContentType(resource.getString("_texthtml_"));
      try {
        PrintWriter out = response.getWriter();

        out.println(resource.getString("_html_"));
        out.println(resource.getString("_head_"));
        out.println(resource.getString("_title_"));
        out.println("Exception");
        out.println(resource.getString("_end_title_"));
        out.println(resource.getString("_end_head_"));

        out.println(resource.getString("_body_"));
        out.println(szText);
        out.println(resource.getString("_end_body_"));
        out.println(resource.getString("_end_html_"));
      } catch (IOException ioe) {}
    }
  }

  /*******************************************************************************************************
   * 
  */
   public String ECSetExpressCheckoutCode(String returnURL,String cancelURL,String amount,
          String paymentType,String currencyCode)
  {

    NVPEncoder encoder = new NVPEncoder();
    NVPDecoder decoder = new NVPDecoder();

    try
    {
            caller = new NVPCallerServices();
            APIProfile profile = ProfileFactory.createSignatureAPIProfile();
            /*
             WARNING: Do not embed plaintext credentials in your application code.
             Doing so is insecure and against best practices.
             Your API credentials must be handled securely. Please consider
             encrypting them for use in any production environment, and ensure
             that only authorized individuals may view or modify them.
             */

    // Set up your API credentials, PayPal end point, API operation and version.
            profile.setAPIUsername("sdk-three_api1.sdk.com");
            profile.setAPIPassword("QFZCWN5HZM8VBG7Q");
            profile.setSignature("AVGidzoSQiGWu.lGj3z15HLczXaaAcK6imHawrjefqgclVwBe8imgCHZ");
            profile.setEnvironment("sandbox");
            profile.setSubject("");
            caller.setAPIProfile(profile);
            encoder.add("VERSION", "51.0");
            encoder.add("METHOD","SetExpressCheckout");

    // Add request-specific fields to the request string.
            encoder.add("RETURNURL",returnURL);
            encoder.add("CANCELURL",cancelURL);
            encoder.add("AMT",amount);
            encoder.add("PAYMENTACTION",paymentType);
            encoder.add("CURRENCYCODE",currencyCode);

    // Execute the API operation and obtain the response.
            String NVPRequest= encoder.encode();
            String NVPResponse =caller.call(NVPRequest);
            decoder.decode(NVPResponse);

    }
    catch (Exception ex)
    {
            ex.printStackTrace();
    }
    String token = decoder.get("TOKEN");
    return decoder.get("ACK");
  }

  /*******************************************************************************************************
  * Die HTTP-Anforderung Post bearbeiten
  */
  @Override
  public void doPost(HttpServletRequest request, HttpServletResponse response)
         throws ServletException, IOException
  {
    Date d = new Date();  // Getting current date
    Address     addrCust = new Address();
    Address     addrShip = new Address();// Lieferaddresse
    OrderInData orderData = new OrderInData();
    Vector<Payment> payments = new Vector<Payment>();
    short       paymentCnt = 0;
    boolean     bHeaderPrinted = false;
    boolean     bCardPos = false;
    String      pdffile = "";
    String      homeprint;

    HttpSession httpsession = request.getSession();
    int cnt = 0;
    int booked = 0;

    if (null != defaultEncoding)
      request.setCharacterEncoding(defaultEncoding);

    
    if (!httpsession.isNew() )
    {
      String o = (String) httpsession.getAttribute( "cnt" );
      if ( o != null )
        cnt = Integer.parseInt( o );
      cnt++;

      String alreadybooked = (String) httpsession.getAttribute( "booked" );
      if ( alreadybooked != null )
      {
        booked = Integer.parseInt(alreadybooked);

        if (0 != booked)
        {
          context.log(request.getRemoteAddr()+": booked: "+alreadybooked+" Dispatcher: "+strJSPReload);
          if ((null != strJSPReload) && (!strJSPReload.equals("")))
          {
            if (!strVerteilerXML.equals(""))
            {
              String strTemp[] = strJSPReload.split("\\.");
              strDispatch = strTemp[0]+formname+"."+strTemp[1];
            }
            else
              strDispatch = strJSPReload;
            
            //  hole den Request Dispatcher f�r die JSP Datei
            RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(strDispatch);
            dispatcher.forward(request, response);
          }
          return;
        }
      }
      booked++;
    }
    httpsession.setAttribute( "cnt", ""+cnt );
    httpsession.setAttribute( "booked", ""+booked  );
    context.log(request.getRemoteAddr()+": Buchen nach "+cnt+" Schritten (SessionID: "+request.getSession().getId()+")");

    // Session-ID wird direkt geholt
    orderData.setSession(httpsession.getId());

    String szLang = "";
    String szCtry = "";
    String szSpecial = "";
    ResourceBundle resource;

    // Falls Sprachabhaengige Ausgabe gewuenscht
    try { szLang = request.getParameter("lang"); } catch (Exception e) { e.printStackTrace(); }
    if ((null == szLang) || szLang.equals(""))
      orderData.setLanguage("de");
    else
      orderData.setLanguage(szLang);
    try { szCtry = request.getParameter("ctry"); } catch (Exception e) { e.printStackTrace(); }
    if ((null == szCtry) || szCtry.equals(""))
      orderData.setCountry("DE");
    else
      orderData.setCountry(szCtry);
    try { szSpecial = request.getParameter("special"); } catch (Exception e) { e.printStackTrace(); }

    if (orderData.getLanguage().equals("de") && orderData.getCountry().equals("DE"))
    {
      resource = ResourceBundle.getBundle("elektra.Resource");
    }
    else
    {
      Locale localeID = new Locale(szLang, szCtry);
      resource = ResourceBundle.getBundle("elektra.Resource", localeID);
    }

    String szTemp = "";

    //
    try { szTemp = request.getParameter("SysID"); } catch (Exception e) { WriteDebug(response, "Feld SysID fehlt", resource, e); }
    orderData.setSysID(szTemp);
    //
    try { szTemp = request.getParameter("ClientID"); } catch (Exception e) { WriteDebug(response, "Feld ClientID fehlt", resource, e); }
    orderData.setClientID(szTemp);
    //
    try { szTemp = request.getParameter("Abholung"); } catch (Exception e) { WriteDebug(response, "Feld Abholung fehlt", resource, e); }
    if (null == szTemp)
      orderData.setAbholung("0");
    else
      orderData.setAbholung(szTemp);

    //PRINT AT HOME
    try { szTemp = request.getParameter("PrintAtHome"); } catch (Exception e) { e.printStackTrace(); }
    if ((null == szTemp) || (szTemp.equals("null")) || (szTemp.equals("")))
      homeprint = "0";
    else
      homeprint = szTemp;

    //
    try { szTemp = request.getParameter("actioncode"); } catch (Exception e) { WriteDebug(response, "Feld actioncode fehlt", resource, e); }
    if (null == szTemp)
      orderData.setActioncode("");
    else
      orderData.setActioncode(szTemp);

    //
    try { szTemp = request.getParameter("Currency"); } catch (Exception e) { e.printStackTrace(); }
    orderData.setCurrency(szTemp);


    //##############
    try { szTemp = request.getParameter("DebitorNumber"); } catch (Exception e) { WriteDebug(response, "Feld DebitorNumber fehlt", resource, e); }
    if ((null == szTemp) || (szTemp.equals("null") || szTemp.equals("")))
      orderData.setDebitorNumber("0");
    else
      orderData.setDebitorNumber(szTemp);
    //
    try { szTemp = request.getParameter("CustomerNumber"); } catch (Exception e) { WriteDebug(response, "Feld CustomerNumber fehlt", resource, e); }
    if ((null == szTemp) || (szTemp.equals("null") || szTemp.equals("")))
      orderData.setCustomerNumber("0");
    else
      orderData.setCustomerNumber(szTemp);
    //
    try { szTemp = request.getParameter("Passwort"); } catch (Exception e) { WriteDebug(response, "Feld Passwort fehlt", resource, e); }
    if ((null == szTemp) || (szTemp.equals("null")))
      orderData.setPasswort("");
    else
      orderData.setPasswort(szTemp);

    try { szTemp = request.getParameter("InfosGenerell"); } catch (Exception e) { e.printStackTrace(); }
    if ((null == szTemp) || (szTemp.equals("null")))
      orderData.setInfos("0");
    else
      orderData.setInfos(szTemp);

    try { szTemp = request.getParameter("AddData"); } catch (Exception e) { e.printStackTrace(); }
    if ((null == szTemp) || (szTemp.equals("null")))
      orderData.setAddData("");
    else
      orderData.setAddData(szTemp);

    // Anzahl Kartenpositionen
    szTemp = "";
    try { szTemp = request.getParameter("CardPosCount"); } catch (Exception e) { e.printStackTrace(); }
    if ((null == szTemp) || szTemp.equals("null") || szTemp.equals(""))
    {
      bCardPos = false;
      orderData.setCardPosCount("1");
    }
    else
    {
      bCardPos = true;
      orderData.setCardPosCount(szTemp);
    }

    for (int nAktCardPos = 0; nAktCardPos < orderData.getCardPosCount(); nAktCardPos++)
    {
      String szCardPos = "";
      if (bCardPos)
        szCardPos = "_" + nAktCardPos;
      //
      try { szTemp = request.getParameter("EventNumber"+szCardPos); } catch (Exception e) { e.printStackTrace(); }
      if (null == szTemp)
        orderData.setCardPosCount("0");
      else
      {
        orderData.setCardPosCount("1");
      }
      orderData.setCardEventNumber(szTemp, nAktCardPos);
      //
      try { szTemp = request.getParameter("EventName"+szCardPos); } catch (Exception e) { e.printStackTrace(); }
      orderData.setCardEventName(szTemp, nAktCardPos);
      //
      try { szTemp = request.getParameter("ShowDate"+szCardPos); } catch (Exception e) { e.printStackTrace(); }
      orderData.setCardShowDate(szTemp, nAktCardPos);
      //
      try { szTemp = request.getParameter("ShowTime"+szCardPos); } catch (Exception e) { e.printStackTrace(); }
      orderData.setCardShowTime(szTemp, nAktCardPos);
      //
      try { szTemp = request.getParameter("ShowNumber"+szCardPos); } catch (Exception e) { e.printStackTrace(); }
      orderData.setCardShowNumber(szTemp, nAktCardPos);
      //
      try { szTemp = request.getParameter("Block"+szCardPos); } catch (Exception e) { e.printStackTrace(); }
      orderData.setCardBlock(szTemp, nAktCardPos);
      //
      try { szTemp = request.getParameter("BlockNumber"+szCardPos); } catch (Exception e) { e.printStackTrace(); }
      orderData.setCardBlockNumber(szTemp, nAktCardPos);
      // Anzahl Karten gesamt
      try { szTemp = request.getParameter("Tickets"+szCardPos); } catch (Exception e) { e.printStackTrace(); }
      if (null == szTemp)
        orderData.setCardTotalTickets("0", nAktCardPos);
      else
        orderData.setCardTotalTickets(szTemp, nAktCardPos);
      //
      szTemp = "";
      try { szTemp = request.getParameter("Level"+szCardPos); } catch (Exception e) { e.printStackTrace(); }
      if (null == szTemp)
        orderData.setCardEbene("", nAktCardPos);
      else
        orderData.setCardEbene(szTemp, nAktCardPos);
      //
      szTemp = "";
      try { szTemp = request.getParameter("Side"+szCardPos); } catch (Exception e) { e.printStackTrace(); }
      if (null == szTemp)
        orderData.setCardSeite("", nAktCardPos);
      else
        orderData.setCardSeite(szTemp, nAktCardPos);
      //
      szTemp = "1";
      try { szTemp = request.getParameter("Zusammen"+szCardPos); } catch (Exception e) { e.printStackTrace(); }
      if (null == szTemp)
        orderData.setCardZusammen("1", nAktCardPos);
      else
        orderData.setCardZusammen(szTemp, nAktCardPos);

      //##########
      try { szTemp = request.getParameter("PriceGroupCount"+szCardPos); } catch (Exception e) { WriteDebug(response, "Feld PriceGroupCount"+szCardPos+" fehlt", resource, e); }
      int nPriceGroupCount = 0;
      try
      {
        Integer intPriceGroupCount = new Integer(szTemp);
        nPriceGroupCount = intPriceGroupCount.intValue();
      } catch (Exception e) { WriteDebug(response, "Fehlender Wert fuer PriceGroupCount"+szCardPos, resource, e); }

      orderData.setCardPriceGroupCount(szTemp, nAktCardPos);

      for (int nAktPriceGroup = 0; nAktPriceGroup < nPriceGroupCount; nAktPriceGroup++)
      {
        String szPG = "_" + nAktPriceGroup;

        try { szTemp = request.getParameter("PriceGroup"+szCardPos+szPG); } catch (Exception e) { WriteDebug(response, "Feld PriceGroup"+szCardPos+" fehlt", resource, e); }
        orderData.setCardPriceGroup(szTemp, nAktCardPos, nAktPriceGroup);

        try { szTemp = request.getParameter("Level"+szCardPos+szPG); } catch (Exception e) { WriteDebug(response, "Feld Level"+szCardPos+" fehlt", resource, e); }
        if (null == szTemp)
          orderData.setCardEbene("", nAktCardPos, nAktPriceGroup);
        else
          orderData.setCardEbene(szTemp, nAktCardPos, nAktPriceGroup);
        //
        try { szTemp = request.getParameter("Side"+szCardPos+szPG); } catch (Exception e) { WriteDebug(response, "Feld Side"+szCardPos+" fehlt", resource, e); }
        if (null == szTemp)
          orderData.setCardSeite("", nAktCardPos, nAktPriceGroup);
        else
          orderData.setCardSeite(szTemp, nAktCardPos, nAktPriceGroup);

        try { szTemp = request.getParameter("ReductionCount"+szCardPos+szPG); } catch (Exception e) { WriteDebug(response, "Feld ReductionCount"+szCardPos+" fehlt", resource, e); }
        int nRedCount = 0;
        try
        {
          Integer nReductionCount = new Integer(szTemp);
          nRedCount = nReductionCount.intValue();
        } catch (Exception e) { WriteDebug(response, "Fehlender Wert fuer ReductionCount"+szCardPos, resource, e); }
        orderData.setCardReductionCount(szTemp, nAktCardPos, nAktPriceGroup);
        for (int nAktReduction = 0; nAktReduction < nRedCount; nAktReduction++)
        {
          String szRed = "_" + nAktReduction;

          // Ermaessigung
          try { szTemp = request.getParameter("Reduction"+szCardPos+szPG+szRed); } catch (Exception e) { WriteDebug(response, "Feld Reduction"+szCardPos+szPG+szRed+" fehlt", resource, e); }
          orderData.setCardReduction(szTemp, nAktCardPos, nAktPriceGroup, nAktReduction);

          szTemp = null;
          // Anzahl ermaessigter Karten
          try { szTemp = request.getParameter("Tickets"+szCardPos+szPG+szRed); } catch (Exception e) { WriteDebug(response, "Feld Tickets"+szCardPos+szPG+szRed+" fehlt", resource, e); }
          if ((null == szTemp) || szTemp.equals("null"))
            orderData.setCardTickets("0", nAktCardPos, nAktPriceGroup, nAktReduction);
          else
          {
            orderData.setCardTickets(szTemp, nAktCardPos, nAktPriceGroup, nAktReduction);
          }
        }

        //
        try { szTemp = request.getParameter("Price"); } catch (Exception e) { e.printStackTrace(); }
        if (null != szTemp)
          orderData.setCardPrice(szTemp, nAktCardPos);
        else
          orderData.setCardPrice("0", nAktCardPos);
        //
        try { szTemp = request.getParameter("Infos"+szCardPos); } catch (Exception e) { WriteDebug(response, "Feld Infos"+szCardPos+" fehlt", resource, e); }
        if (null != szTemp)
          orderData.setCardInfos(szTemp, nAktCardPos);
        else
          orderData.setCardInfos("Infos", nAktCardPos);
        // Kartengebuehren
        try { szTemp = request.getParameter("CardChargeCount"+szCardPos); } catch (Exception e) { e.printStackTrace(); }
        if (null == szTemp )
          szTemp = "0";
        orderData.setCardCardChargesCount(szTemp, nAktCardPos);
        for (int nAktCardCharge = 0; nAktCardCharge < orderData.getCardCardChargesCount(nAktCardPos).intValue(); nAktCardCharge++)
        {
          try { szTemp = request.getParameter("CardCharge"+szCardPos+"_"+nAktCardCharge); } catch (Exception e) { e.printStackTrace(); }
          if (null == szTemp )
            szTemp = "0";
          Integer nCharge = new Integer(szTemp );
          orderData.setCardCardCharge(nAktCardPos, nAktCardCharge, nCharge , orderData.getCurrency());
        }
        // Positionsgebuehren
        try { szTemp = request.getParameter("PosChargeCount"+szCardPos); } catch (Exception e) { e.printStackTrace(); }
        if (null == szTemp )
          szTemp = "0";
        orderData.setCardPosChargesCount(szTemp, nAktCardPos);
        for (int nAktPosCharge = 0; nAktPosCharge < orderData.getCardPosChargesCount(nAktCardPos).intValue(); nAktPosCharge ++)
        {
          try { szTemp = request.getParameter("PosCharge"+szCardPos+"_"+nAktPosCharge ); } catch (Exception e) { e.printStackTrace(); }
          if (null == szTemp )
            szTemp = "0";
          Integer nCharge = new Integer(szTemp );
          orderData.setCardPosCharge(nAktCardPos, nAktPosCharge , nCharge , orderData.getCurrency());
        }
         //
        try { szTemp = request.getParameter("AutoGeb"+szCardPos); } catch (Exception e) { WriteDebug(response, "Feld AutoGeb"+szCardPos+" fehlt", resource, e); }
        if (null != szTemp)
          orderData.setCardAutoGeb(szTemp, nAktCardPos);
        else
          orderData.setCardAutoGeb("0", nAktCardPos);
        //
        try { szTemp = request.getParameter("PrintAtHome"+szCardPos); } catch (Exception e) { WriteDebug(response, "Feld PrintAtHome"+szCardPos+" fehlt", resource, e); }
        if (null != szTemp)
          orderData.setCardPrintAtHome(szTemp, nAktCardPos);
        else
          orderData.setCardPrintAtHome("0", nAktCardPos);
      }
    }
    // #### Artikel ####
    try { szTemp = request.getParameter("ArtikelPosCount"); } catch (Exception e) { e.printStackTrace(); }
    if (null != szTemp)
      orderData.setArtikelPosCount(szTemp);
    else
      orderData.setArtikelPosCount("0");
    //
    for (int nAktArtPos = 0; nAktArtPos < orderData.getArtikelPosCount(); nAktArtPos++)
    {
      String szNumber = "_" + nAktArtPos;
      try { szTemp = request.getParameter("ArtikelNumber" + szNumber); } catch (Exception e) { e.printStackTrace(); }
      if (null != szTemp)
        orderData.setArtikelNo(szTemp, nAktArtPos);
      else
       orderData.setArtikelNo("999", nAktArtPos);
      //
      try { szTemp = request.getParameter("ArtikelCount" + szNumber); } catch (Exception e) { e.printStackTrace(); }
      if (null != szTemp)
        orderData.setArtikelCount(szTemp, nAktArtPos);
      else
        orderData.setArtikelCount("0", nAktArtPos);
      //
      try { szTemp = request.getParameter("ArtikelName" + szNumber); } catch (Exception e) { e.printStackTrace(); }
      if (null != szTemp)
        orderData.setArtikelName(szTemp, nAktArtPos);
      //
      try { szTemp = request.getParameter("ArtikelAmount" + szNumber); } catch (Exception e) { e.printStackTrace(); }
      if (null != szTemp)
        orderData.setArtikelAmount(szTemp, nAktArtPos);
      //
      try { szTemp = request.getParameter("ArtikelInfos" + szNumber); } catch (Exception e) { e.printStackTrace(); }
      if (null == szTemp)
        orderData.setArtikelInfos("ArtikelInfos", nAktArtPos);
      else
        orderData.setArtikelInfos(szTemp, nAktArtPos);

      // printathome
      orderData.setArtikelPrintAtHome(homeprint, nAktArtPos);

    }

    // #### Gutscheinauftrag ####
    try { szTemp = request.getParameter("BonPosCount"); } catch (Exception e) { e.printStackTrace(); }
    if (null != szTemp)
      orderData.setBonPosCount(szTemp);
    else
      orderData.setBonPosCount("0");

    for (int nAktBonPos = 0; nAktBonPos < orderData.getBonPosCount(); nAktBonPos++)
    {
      String szNumber = "_" + nAktBonPos;

      //
      try { szTemp = request.getParameter("BonType" + szNumber); } catch (Exception e) { e.printStackTrace(); }
      orderData.setBonType(szTemp, nAktBonPos);
      //
      try { szTemp = request.getParameter("BonSerieNo" + szNumber); } catch (Exception e) { e.printStackTrace(); }
      orderData.setBonSerieNo(szTemp, nAktBonPos);
      //
      try { szTemp = request.getParameter("BonCurrency" + szNumber); } catch (Exception e) { e.printStackTrace(); }
      if ((null == szTemp) || (szTemp.equals("")))
        orderData.setBonCurr(orderData.getCurrency(), nAktBonPos);
      else
        orderData.setBonCurr(szTemp, nAktBonPos);
      //
      try { szTemp = request.getParameter("BonCount" + szNumber); } catch (Exception e) { e.printStackTrace(); }
      orderData.setBonCount(szTemp, nAktBonPos);
      //
      try { szTemp = request.getParameter("BonWert" + szNumber); } catch (Exception e) { e.printStackTrace(); }
      orderData.setBonWert(szTemp, nAktBonPos);
      //
      try { szTemp = request.getParameter("BonCharge" + szNumber); } catch (Exception e) { e.printStackTrace(); }
      orderData.setBonCharge(szTemp, nAktBonPos);
      //
      try { szTemp = request.getParameter("BonWidmung" + szNumber); } catch (Exception e) { e.printStackTrace(); }
      orderData.setBonWidmung(szTemp, nAktBonPos);
      //
      try { szTemp = request.getParameter("BonInfos" + szNumber); } catch (Exception e) { e.printStackTrace(); }
      if (null == szTemp)
        orderData.setBonInfos("BonInfos", nAktBonPos);
      else
        orderData.setBonInfos(szTemp, nAktBonPos);
      // printathome
      orderData.setBonPrintAtHome(homeprint, nAktBonPos);
    }

    // Adresse
    boolean bNoAddr = !(orderData.getCustomerNumber().equals("0") && orderData.getDebitorNumber().equals("0"));
    
    // Sonderbehandlung FAKE ...... fuer Debitorennummer mit -99999
    if (orderData.getDebitorNumber().startsWith("-"))
    {
      bNoAddr = false;
    }
    
    try { szTemp = request.getParameter("Anrede"); } catch (Exception e) { e.printStackTrace(); }
    if ((null != szTemp) && !bNoAddr)
      addrCust.setAnrede(szTemp);
    else
      addrCust.setAnrede("");
    //
    try { szTemp = request.getParameter("Name"); } catch (Exception e) { e.printStackTrace(); }
    if ((null != szTemp) && !bNoAddr)
    {
      addrCust.setName(szTemp);
      String temp[] = szTemp.split("\\|");
      if (temp.length > 0)
        addrCust.setName1(temp[0]);
      if (temp.length > 1)
        addrCust.setName2(temp[1]);
      if (temp.length > 2)
        addrCust.setName3(temp[2]);
    }
    else
      addrCust.setName("");
    //
    try { szTemp = request.getParameter("Strasse"); } catch (Exception e) { e.printStackTrace(); }
    if ((null != szTemp) && !bNoAddr)
      addrCust.setStrasse(szTemp);
    else
      addrCust.setStrasse("");
    //
    try { szTemp = request.getParameter("Country"); } catch (Exception e) { e.printStackTrace(); }
    if (null == szTemp)
      if (!bNoAddr)
        addrCust.setCountry(szDefaultCountry);
      else
        addrCust.setCountry("");
    else
      addrCust.setCountry(szTemp);
    //
    try { szTemp = request.getParameter("PLZ"); } catch (Exception e) { e.printStackTrace(); }
    if ((null != szTemp) && !bNoAddr)
      addrCust.setPLZ(szTemp);
    else
      addrCust.setPLZ("");
    //
    try { szTemp = request.getParameter("Ort"); } catch (Exception e) { e.printStackTrace(); }
    if ((null != szTemp) && !bNoAddr)
      addrCust.setOrt(szTemp);
    else
      addrCust.setOrt("");
    //
    try { szTemp = request.getParameter("Telefon"); } catch (Exception e) { e.printStackTrace(); }
    if ((null != szTemp) && !bNoAddr)
      addrCust.setPhone(szTemp);
    else
      addrCust.setPhone("");
    //
    try { szTemp = request.getParameter("EMail"); } catch (Exception e) { e.printStackTrace(); }
    if ((null != szTemp) && !bNoAddr)
      addrCust.setEMail(szTemp);
    else
      addrCust.setEMail("");

    //
    try { szTemp = request.getParameter("LAnrede"); } catch (Exception e) { e.printStackTrace(); }
    if (null == szTemp)
      addrShip.setAnrede("");
    else
      addrShip.setAnrede(szTemp);
    //
    try { szTemp = request.getParameter("LName"); } catch (Exception e) { e.printStackTrace(); }
    if (null == szTemp)
      addrShip.setName("");
    else
      addrShip.setName(szTemp);
    //
    try { szTemp = request.getParameter("LStrasse"); } catch (Exception e) { e.printStackTrace(); }
    if (null == szTemp)
      addrShip.setStrasse("");
    else
      addrShip.setStrasse(szTemp);

    //
    try { szTemp = request.getParameter("LCountry"); } catch (Exception e) { e.printStackTrace(); }
    if (null == szTemp)
      addrShip.setCountry(szTemp, szDefaultCountry);
    else
      addrShip.setCountry(szTemp, szDefaultCountry);
    //
    try { szTemp = request.getParameter("LPLZ"); } catch (Exception e) { e.printStackTrace(); }
    if (null == szTemp)
      addrShip.setPLZ("");
    else
      addrShip.setPLZ(szTemp);
    //
    try { szTemp = request.getParameter("LOrt"); } catch (Exception e) { e.printStackTrace(); }
    if (null == szTemp)
      addrShip.setOrt("");
    else
      addrShip.setOrt(szTemp);

    // Bezahlung
    if (version >= 280)
    {

    }
    Boolean multiPays = false;
    try { szTemp = request.getParameter("PaymentCount"); } catch (Exception e) { e.printStackTrace(); }
    if (null != szTemp)
    {
      paymentCnt = new Integer(szTemp).shortValue();
      multiPays = true;
    }
    else
      paymentCnt = 1;
    for (short aktPayment = 0; aktPayment < paymentCnt; aktPayment++)
    {
      Payment     paymentData    = new Payment();
      String aktPay = "";
      if (multiPays)
        aktPay="_"+aktPayment;

      try { szTemp = request.getParameter("Bezahlung"+aktPay); } catch (Exception e) { e.printStackTrace(); }
      paymentData.setPayment(szTemp);

      // in Cent!!
      try { szTemp = request.getParameter("PaymentAmount"+aktPay); } catch (Exception e) { e.printStackTrace(); }
      if (null == szTemp)
        paymentData.setAmount( 0 );
      else
        paymentData.setAmount( szTemp );

      try { szTemp = request.getParameter("PaymentCurrency"+aktPay); } catch (Exception e) { e.printStackTrace(); }
      paymentData.setCurrency(szTemp);

      if (paymentData.isCreditcard())
      {
        try { szTemp = request.getParameter("cardType"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setCardType(szTemp);

        try { szTemp = request.getParameter("cardOwner"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        if (null == szTemp)
          szTemp = addrCust.getName();
        paymentData.setCardOwner(szTemp);

        try { szTemp = request.getParameter("cardNumber")+aktPay; } catch (Exception e) { e.printStackTrace(); }
        paymentData.setCardNumber(szTemp);

        try { szTemp = request.getParameter("cardAlias")+aktPay; } catch (Exception e) { e.printStackTrace(); }
        if (null == szTemp)
          paymentData.setCardAlias("");
        else
          paymentData.setCardAlias(szTemp);

        try { szTemp = request.getParameter("cardCVC"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setCardCVC(szTemp);

        try { szTemp = request.getParameter("cardMonth"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setCardMonth(szTemp);

        try { szTemp = request.getParameter("cardYear"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setCardYear(szTemp);
      }
      if (paymentData.isBankeinzug())
      {
        try { szTemp = request.getParameter("bankOwner"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setBankAccountOwner(szTemp);

        try { szTemp = request.getParameter("bankName"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setBankName(szTemp);

        try { szTemp = request.getParameter("bankNumber"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setBankNumber(szTemp);

        try { szTemp = request.getParameter("bankAccount"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setBankAccount(szTemp);

        try { szTemp = request.getParameter("bankIBAN"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setBankIBAN(szTemp);

        try { szTemp = request.getParameter("bankSWIFT"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setBankSWIFT(szTemp);
      }
      if (paymentData.isGutschein())
      {
        try { szTemp = request.getParameter("payBonType"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setBontype(szTemp);

        try { szTemp = request.getParameter("payBonSerNo"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setBonserialnumber(szTemp);

        try { szTemp = request.getParameter("payBonNo"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setBonnumber(szTemp);

        try { szTemp = request.getParameter("payBonSerName"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setBonSerialName(szTemp);

        try { szTemp = request.getParameter("payBonBarcode"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setBonBarcode(szTemp);

        try { szTemp = request.getParameter("payBonValid"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setBonGueltig(szTemp);
      }
      if (paymentData.isInternalCredit() || paymentData.isLieferschein())
      {
        try { szTemp = request.getParameter("Voucher"+aktPay); } catch (Exception e) { e.printStackTrace(); }
        paymentData.setVoucher(szTemp);
      }

      payments.add(paymentData);
    }
    Configuration conf = new Configuration(context, szElektraConfig, "ElektraServerBook", orderData.getSysID(), orderData.getClientID(), nDebug.intValue());
    szElektraServer = conf.getServerName();
    szElektraServerPort = conf.getServerPort();
    szMailServer = conf.getMailServer();
    szMailFrom = conf.getMailFrom();
    szMailCC = conf.getMailCC();
    szMailBCC = conf.getMailBCC();
    szMailReply = conf.getMailReply();
    szDefaultCountry = conf.getDefaultCountry();

    // Ab hier die Ausgabe
    response.setContentType("text/html;charset=\"UTF-8\"");
    OrderBookResponse order = new OrderBookResponse(response.getWriter());

    if (null == szElektraServer)
    {
      if (!bHeaderPrinted)
      {
        order.writeErrorHeader("Internal error");
        order.writeErrorBodyStart();
      }
      order.writeError("System error: Elektra-Server not defined!<br />SystemID: "+orderData.getSysID());
      order.writeBodyEnd();
      context.log("Elektra-Server not defined!");
    }
    else
    {
      // Bezahlung extern nur mit Null-Betrag!
      if ((0 == payments.get(0).getAmount() ) && (payments.get(0).isExternalPayment()))
      {
        if (!bHeaderPrinted)
        {
          order.writeErrorHeader("JavaScript error");
          order.writeErrorBodyStart();
        }
        order.writeError("Bitte schalten Sie JavaScript in Ihrem Browser ein, da sonst keine Bezahlung m&ouml;glich ist!<br />");
        order.writeErrorBodyEnd();
        context.log(request.getRemoteAddr()+": Error: order amount = 0");
      }
      else
      {
        if (nDebug.intValue() > 4)
        {
          order.writeHeader(resource.getString("Order_from") + d.toString() + ".");
          order.writeBodyStart();
          order.writeDebug(addrCust, addrShip, orderData);
          bHeaderPrinted = true;
        }
        else
          bHeaderPrinted = false;

        // Daten an DB-Server senden
        Socket socket = null;
        BookOutData orderOut = new BookOutData();

        if (nDebug.intValue() > 0)
          context.log(request.getRemoteAddr()+": starting booking. (SessionID: "+request.getSession().getId()+")");
        try
        {
          socket = new Socket(szElektraServer, Integer.parseInt(szElektraServerPort));
          if (nDebug.intValue() > 1)
            context.log(request.getRemoteAddr()+":  socket created. (SessionID: "+request.getSession().getId()+")");

          //BufferedInputStream is = new BufferedInputStream(socket.getInputStream());
          BufferedReader in = new BufferedReader( new InputStreamReader(socket.getInputStream()));
          BufferedOutputStream os = new BufferedOutputStream(socket.getOutputStream());

          // Daten senden
          try { os.write(version.toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(szRequest.getBytes() ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          // Encryption
          try { os.write("NONE".getBytes() ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          // compression
          try { os.write("NONE".getBytes() ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(orderData.getSysID().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(orderData.getClientID().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(orderData.getActioncode().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(orderData.getAbholung().toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(orderData.getDebitorNumber().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(orderData.getCustomerNumber().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(orderData.getPasswort().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(orderData.getInfos().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(orderData.getSession().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(orderData.getLanguage().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );

          Integer PosCount = new Integer(orderData.getPosCount());
          try { os.write(PosCount.toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );

          // #### Kartenauftrag ####
          for (int nAktCardPos = 0; nAktCardPos < orderData.getCardPosCount(); nAktCardPos++)
          {
            try { os.write(orderData.getCardPosType(nAktCardPos).toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getCardPosStatus(nAktCardPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getCardEventName(nAktCardPos).getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getCardEventNumber(nAktCardPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getCardShowNumber(nAktCardPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getCardShowDate(nAktCardPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getCardShowTime(nAktCardPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getCardBlockNumber(nAktCardPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getCardEbene(nAktCardPos).getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getCardSeite(nAktCardPos).getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getCardZusammen(nAktCardPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getCardPriceGroupCount(nAktCardPos).toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            for (int j = 0; j < orderData.getCardPriceGroupCount(nAktCardPos).intValue() ; j++)
            {
              try { os.write(orderData.getCardPriceGroup(nAktCardPos, j).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
              os.write( 9 );
              try { os.write(orderData.getCardReductionCount(nAktCardPos, j).toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
              os.write( 9 );
              try { os.write(orderData.getCardEbene(nAktCardPos, j).getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
              os.write( 9 );
              try { os.write(orderData.getCardSeite(nAktCardPos, j).getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
              os.write( 9 );
              for (int k = 0; k < orderData.getCardReductionCount(nAktCardPos, j).intValue() ; k++)
              {
                try { os.write(orderData.getCardReduction(nAktCardPos, j, k).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
                os.write( 9 );
                try { os.write(orderData.getCardTickets(nAktCardPos, j, k).toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
                os.write( 9 );
              }
            }
            // Gebuehren
            try { os.write(orderData.getCardPosChargesCount(nAktCardPos ).toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            for (int nAktPosCharge = 0; nAktPosCharge < orderData.getCardPosChargesCount(nAktCardPos).intValue(); nAktPosCharge ++)
            {
              try { os.write(orderData.getCardPosChargeIndex(nAktCardPos, nAktPosCharge ).toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
              os.write( 9 );
            }
            try { os.write(orderData.getCardCardChargesCount(nAktCardPos ).toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            for (int nAktCardCharge = 0; nAktCardCharge < orderData.getCardCardChargesCount(nAktCardPos).intValue(); nAktCardCharge ++)
            {
              try { os.write(orderData.getCardCardChargeIndex(nAktCardPos, nAktCardCharge ).toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
              os.write( 9 );
            }

            if (0 == orderData.getCardAutoGeb(nAktCardPos).compareTo("1"))
              os.write("1".getBytes() );
            else
              os.write("0".getBytes() );
            os.write( 9 );

            if (0 == orderData.getCardPrintAtHome(nAktCardPos).compareTo("1"))
              os.write("1".getBytes() );
            else
              os.write("0".getBytes() );
            os.write( 9 );
            try { os.write(orderData.getCardInfos(nAktCardPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
          }
          // #### Gutschein ####
          for (int nAktBonPos = 0; nAktBonPos < orderData.getBonPosCount(); nAktBonPos++)
          {
            try { os.write(orderData.getBonPosType(nAktBonPos).toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getBonPosStatus(nAktBonPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getBonType(nAktBonPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getBonSerieNo(nAktBonPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getCurrency().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getBonCount(nAktBonPos).toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getBonWert(nAktBonPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getBonCharge(nAktBonPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getBonWidmung(nAktBonPos).getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getBonInfos(nAktBonPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
          }
          // #### Artikel ####
          for (int nAktArtPos = 0; nAktArtPos < orderData.getArtikelPosCount(); nAktArtPos++)
          {
            try { os.write(orderData.getArtPosType(nAktArtPos).toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getArtPosStatus(nAktArtPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getArtikelNo(nAktArtPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getArtikelName(nAktArtPos).getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getArtikelCount(nAktArtPos).toString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getArtikelAmount(nAktArtPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            try { os.write(orderData.getArtikelInfos(nAktArtPos).getBytes() ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
          }

          // #### Adresse ####
          try { os.write(addrCust.getAnrede().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(addrCust.getName().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(addrCust.getStrasse().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(addrCust.getCountry().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(addrCust.getPLZ().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(addrCust.getOrt().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(addrCust.getPhone().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(addrCust.getEMail().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          // #### Lieferadresse ####
          try { os.write(addrShip.getAnrede().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(addrShip.getName().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(addrShip.getStrasse().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(addrShip.getCountry().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(addrShip.getPLZ().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );
          try { os.write(addrShip.getOrt().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );

          // Ab Version 280
          try { os.write(new Integer(payments.size()).toString().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
          os.write( 9 );

          for (int aktPayment = 0; aktPayment< payments.size(); aktPayment++)
          {
            Payment paymentData    =  payments.get(aktPayment);
            try { os.write(paymentData.getPayment().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
            os.write( 9 );
            if (paymentData.isCreditcard())
            {
              try { os.write(paymentData.getCardType().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
              os.write( 9 );
              try { os.write(paymentData.getCardOwner().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
              os.write( 9 );
              try { os.write(paymentData.getCardNumber().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
              if (null != paymentData.getCardCVC())
              {
                os.write( '-' );
                try { os.write(paymentData.getCardCVC().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
              }
              os.write( 9 );
              try { os.write(paymentData.getCardMonth().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
              os.write( 9 );
              try { os.write(paymentData.getCardYear().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
              os.write( 9 );
              try { os.write(paymentData.getCardAlias().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
              os.write( 9 );
              // Ab Version 280
              try { os.write(paymentData.getAmountString().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
              os.write( 9 );
              try { os.write(paymentData.getCurrency().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
              os.write( 9 );
            }
            else
            {
              if (paymentData.isBankeinzug())
              {
      //          os.write(szCardType.getBytes() );
                try { os.write(paymentData.getBankSWIFT().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                os.write( 9 );
                try { os.write(paymentData.getBankAccountOwner().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                os.write( 9 );
                try { os.write(paymentData.getBankAccount().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                os.write( 9 );
                try { os.write(paymentData.getBankName().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                os.write( 9 );
                try { os.write(paymentData.getBankNumber().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                os.write( 9 );
                try { os.write(paymentData.getBankIBAN().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
      //          os.write(szCardYear.getBytes() );
                os.write( 9 );
                // Ab Version 280
                try { os.write(paymentData.getAmountString().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                os.write( 9 );
                try { os.write(paymentData.getCurrency().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                os.write( 9 );
              }
              else
              {
                if (paymentData.isExternalPayment())
                {
                  os.write( 9 );
                  os.write( 9 );
                  try { os.write(paymentData.getAmountString().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                  os.write( 9 );
                  os.write( 9 );
                  os.write( 9 );
                  os.write( 9 );
                  os.write( 9 );
                  try { os.write(paymentData.getCurrency().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                  os.write( 9 );
                }
                else
                {
                  if (paymentData.isInternalCredit())
                  {
                    os.write( 9 );
                    try { os.write(paymentData.getVoucher().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                    os.write( 9 );
                    os.write( 9 );
                    os.write( 9 );
                    os.write( 9 );
                    os.write( 9 );
                    os.write( 9 );
                    try { os.write(paymentData.getCurrency().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                    os.write( 9 );
                  }
                  else
                  {
                    if (paymentData.isDIBS() || paymentData.isPayPal() || paymentData.isQPay())
                    {  // in der Nummer steht ggfs. eine TranskationsID
                      os.write( 9 );
                      os.write( 9 );
                      try { os.write(paymentData.getTransId().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                      os.write( 9 );
                      try { os.write(paymentData.getAmountString().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                      os.write( 9 );
                      os.write( 9 );
                      os.write( 9 );
                      os.write( 9 );
                      try { os.write(paymentData.getCurrency().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                      os.write( 9 );
                    }
                    else
                    {
                      if (paymentData.isGutschein())
                      {
                        try { os.write(paymentData.getBonserialnumber().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                        os.write( 9 );
                        try { os.write(paymentData.getBontype().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                        os.write( 9 );
                        try { os.write(paymentData.getBonnumber().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                        os.write( 9 );
                        try { os.write(paymentData.getBonBarcode().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                        os.write( 9 );
                        try { os.write(paymentData.getAmountString().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                        os.write( 9 );
                        try { os.write(paymentData.getBonGueltig().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                        os.write( 9 );
                        try { os.write(paymentData.getBonSerialName().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                        os.write( 9 );
                        try { os.write(paymentData.getCurrency().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                        os.write( 9 );
                      }
                      else
                      {
                        os.write( 9 );
                        os.write( 9 );
//                      try { os.write(paymentData.getCardNumber().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
                        os.write( 9 );
                        try { os.write(paymentData.getAmountString().getBytes() ); } catch (IOException e) { e.printStackTrace(); }
                        os.write( 9 );
                        os.write( 9 );
                        os.write( 9 );
                        os.write( 9 );
                        try { os.write(paymentData.getCurrency().getBytes("ISO-8859-1") ); } catch (IOException e) { e.printStackTrace(); }
                        os.write( 9 );
                      }
                    }
                  }
                }
              }
            }
          }
          if (nDebug.intValue() > 1)
            context.log(request.getRemoteAddr()+":  flushing: "+os.toString());
          os.flush();

          // Daten senden, nun auf die Buchung warten
          orderOut.readSock(in, version);
          if (nDebug.intValue() > 4)
          {
            order.writeDebug("<br><h2>Getting:</h2>" );
            order.writeDebug("Error:  "+orderOut.getErrorCode() );
            order.writeDebug("System: "+orderOut.getSystemNumber() );
            order.writeDebug("Order:  "+orderOut.getBookingNumber()  );
            order.writeDebug("Client: "+orderOut.getClientNumber()  );
            order.writeDebug("Name:   "+orderOut.getClientName1()  );
            order.writeDebug("Price:  "+orderOut.getGesamtPreis()  );
            order.writeDebug("Abhol:  "+orderOut.getAbholDatum()  );
            order.writeDebug("Option: "+orderOut.getOptionsDatum()  );
            order.writeDebug("PosCount: "+orderOut.getPositionCnt()  );
          }
          if (nDebug.intValue() > 0)
            context.log(request.getRemoteAddr()+": booking performed. OrderNo = "+orderOut.getClientNumber()+"-"+orderOut.getBookingNumber()+"-"+orderOut.getSystemNumber()+" (SessionID: "+request.getSession().getId()+")");

          // Bei vorhandenem Kunden/Debitoren ggfs. die Daten fuer Anzeige, EMailversand fuellen
          if (null == addrCust.getName() || addrCust.getName().equals(""))
          {
              addrCust.setName1(orderOut.getCustomerName1());
              addrCust.setName2(orderOut.getCustomerName2());
              addrCust.setName3(orderOut.getCustomerName3());
          }
          if (null == addrCust.getAnrede() || addrCust.getAnrede().equals(""))
              addrCust.setAnrede(orderOut.getCustomerAnrede());
          if (null == addrCust.getStrasse() || addrCust.getStrasse().equals(""))
              addrCust.setStrasse(orderOut.getCustomerStrasse());
          if (null == addrCust.getCountry() || addrCust.getCountry().equals(""))
              addrCust.setCountry(orderOut.getCustomerLand());
          if (null == addrCust.getOrt() || addrCust.getOrt().equals(""))
              addrCust.setOrt(orderOut.getCustomerOrt());
          if (null == addrCust.getPLZ() || addrCust.getPLZ().equals(""))
              addrCust.setPLZ(orderOut.getCustomerPLZ());

          if (null == addrCust.getEMail() || addrCust.getEMail().equals(""))
          {
              addrCust.setEMail(orderOut.getCustomerEMail());
          }

/* PayPal */
          String returnURL = "www.orestes.de/returnurl";
          String cancelURL = "www.orestes.de/cancelurl";
          String amount = "10";
          String paymentType = "Sale";
          String currencyCode = "EUR";
         
          String x = ECSetExpressCheckoutCode(returnURL, cancelURL, amount, paymentType, currencyCode);

          // Um den erweiterten Formnamen herauszufinden
          if (!strVerteilerXML.equals(""))
          {
            XMLParseSpecial xsp = new XMLParseSpecial();
            // Sonderbehandlung Auftraege ohne Veranstaltung
            if (0 != orderData.getCardPosCount())
            {              
              formname = xsp.getSpecial(szLang, szCtry, szSpecial, orderData.getCardEventName(0), orderData.getActioncode(), strVerteilerXML, true);
              formnameerr = xsp.getSpecial(szLang, szCtry, szSpecial, orderData.getCardEventName(0), orderData.getActioncode(), strVerteilerXML, false);
            }
            else
            {
              formname = xsp.getSpecial(szLang, szCtry, szSpecial, "", orderData.getActioncode(), strVerteilerXML, true);
              formnameerr = xsp.getSpecial(szLang, szCtry, szSpecial, "", orderData.getActioncode(), strVerteilerXML, false);
            }
          }
          // Buchung okay, bzw. nur Capture nicht durchgegangen
          if ((0 != orderOut.getErrorCode()) && (-103 != orderOut.getErrorCode()))
          {
            if ((null != strJSPError) && !strJSPError.equals(""))
            {
              request.setAttribute("addrcust", addrCust);
              request.setAttribute("addrship", addrShip);
              request.setAttribute("orderdata", orderData);
              request.setAttribute("orderout", orderOut);
              request.setAttribute("payments", payments);
              // um kompatibel bei einer Zahlart zu bleiben
              request.setAttribute("paymentdata", payments.get(0));

              if (!strVerteilerXML.equals(""))
              {
                String strTemp[] = strJSPError.split("\\.");
                strDispatch = strTemp[0]+formnameerr+"."+strTemp[1];
              }
              else
                strDispatch = strJSPError;
            
              //  hole den Request Dispatcher fuer die JSP Datei
              RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(strDispatch);
              dispatcher.forward(request, response);
            }
            else
            {
              if (!bHeaderPrinted)
              {
                order.writeErrorHeader("Systemerror");
                order.writeErrorBodyStart();
              }
              if (nDebug.intValue() > 4)
                order.writeError("Systemerror: "+orderOut.getErrorCode());
              
              switch (orderOut.getErrorCode())
              {
                case -9:  // Zahlungsfehler
                  switch (orderOut.getPayment())
                  {
                    case -10:
                    case -11:
                    case -12:
                    case -13:
                    case -21:
                    case -22:
                    case -23:
                    case -24:
                    case -25:
                    case -26:
                       order.writeError("<br /><b>"+resource.getString("payment_error")+resource.getString("error_"+orderOut.getPayment())+"</b><br />");
                       break;
                    default:
                       order.writeError("<br /><b>"+resource.getString("payment_error")+orderOut.getPayment()+"</b><br />");
                       break;
                  }
                  break;
                  
                default:
                  order.writeError(resource.getString("error_"+orderOut.getErrorCode()));
              }
              order.writeErrorBodyEnd();
            }
            context.log(request.getRemoteAddr()+": Systemerror: "+orderOut.getErrorCode());
          }
          else
          {
            orderOut.readSockTickets(in, version);

            if (0 == orderOut.getBookNo())
            {
              if ((null != strJSPError) && !strJSPError.equals(""))
              {
                request.setAttribute("addrcust", addrCust);
                request.setAttribute("addrship", addrShip);
                request.setAttribute("orderdata", orderData);
                request.setAttribute("orderout", orderOut);
                request.setAttribute("payments", payments);
                // um kompatibel bei einer Zahlart zu bleiben
                request.setAttribute("paymentdata", payments.get(0));
                if (!strVerteilerXML.equals(""))
                {
                  String strTemp[] = strJSPError.split("\\.");
                  strDispatch = strTemp[0]+formnameerr+"."+strTemp[1];
                }
                else
                  strDispatch = strJSPError;
            
                //  hole den Request Dispatcher fuer die JSP Datei
                RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(strDispatch);
                
                dispatcher.forward(request, response);
              }
              else
              {
                if (!bHeaderPrinted)
                {
                  order.writeErrorHeader("Systemerror");
                  order.writeErrorBodyStart();
               }
                order.writeError(resource.getString("error_"+orderOut.getErrorCode()));
                order.writeErrorBodyEnd();
              }
            }
            else
            {
              //PRINT AT HOME
              if (homeprint.equals("1") && 
                  (orderOut.isPayed() || ( !orderData.getDebitorNumber().equals("0") && (payments.get(0).isInternalCredit() || payments.get(0).isLieferschein()) ) ))
              {
                PdfTicket pdf_billet = new PdfTicket(props);
                if (pdf_billet.getTicketData( orderData, orderOut ))
                {
                  pdf_billet.printTickets();
                  pdffile = pdf_billet.getPdf_http();
                }
                else
                  pdffile = "";
              }
              else
              {
                pdffile = "";
              }
              if ((null != strJSP) && !strJSP.equals(""))
              {
                request.setAttribute("addrcust", addrCust);
                request.setAttribute("addrship", addrShip);
                request.setAttribute("orderdata", orderData);
                request.setAttribute("orderout", orderOut);
                request.setAttribute("payments", payments);
                // um kompatibel bei einer Zahlart zu bleiben
                request.setAttribute("paymentdata", payments.get(0));
                request.setAttribute("pdffile", pdffile);
                
                if (!strVerteilerXML.equals(""))
                {
                  String strTemp[] = strJSP.split("\\.");
                  strDispatch = strTemp[0]+formname+"."+strTemp[1];
                }
                else
                  strDispatch = strJSP;
            
                //  hole den Request Dispatcher fuer die JSP Datei
                RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(strDispatch);
                
                dispatcher.forward(request, response);
              }
              else
              {
                if (!bHeaderPrinted)
                {
                  order.writeHeader(resource.getString("Order_from") + d.toString() + ".");
                  order.writeBodyStart();
                }
                order.writeAll(addrCust, addrShip, orderData, orderOut, payments.get(0), pdffile);
//TODO                order.writeAll(addrCust, addrShip, orderData, orderOut, paymentData, pdffile);
                order.writeBodyEnd();
              }
            }
          }
        }
        catch (IOException ioex)
        {
          orderOut.setErrorCode( -999);
          orderOut.setErrorMessage(ioex.getLocalizedMessage());
          if ( (null != strJSPError) && !strJSPError.equals(""))
          {
            request.setAttribute("orderdata", orderData);
            request.setAttribute("orderout", orderOut);
            request.setAttribute("payments", payments);
            // um kompatibel bei einer Zahlart zu bleiben
            request.setAttribute("paymentdata", payments.get(0));
            
            if (!strVerteilerXML.equals(""))
            {
              String strTemp[] = strJSPError.split("\\.");
              strDispatch = strTemp[0]+formnameerr+"."+strTemp[1];
            }
            else
              strDispatch = strJSPError;
            
            //  hole den Request Dispatcher fuer die JSP Datei
            RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(strDispatch);
            dispatcher.forward(request, response);
          }
          else
            order.writeProcessor(false);
        }
        catch (Exception ex)
        {
          ex.printStackTrace();
        }
        finally
        {
          if (socket != null)
          {
            try
            {
              socket.close();
            }
            catch (IOException ioex)
            {
              ioex.printStackTrace();
            }
          }
        }
        if (0 != orderOut.getBookNo())
        {
          if (null != szMailServer)
          {
            StringBuffer sb = new StringBuffer();
            MailBookResponse mailresp = new MailBookResponse(sb, request);
            mailresp.writeAll(addrCust, addrShip, orderData, orderOut, payments, pdffile);
//TODO            mailresp.writeAll(addrCust, addrShip, orderData, orderOut, paymentData, pdffile);
          
            String strSubject = resource.getString("Order_from") + d.toString() + ".";
          
            Mail m = new Mail(szMailServer, szMailFrom , addrCust.getEMail(), szMailBCC, szMailCC, szMailReply, strSubject, mailresp.getText().toString());
            MailSender.getInstance().sendMail(m);
          }
/* Ende Mailing */
        }
      }
    }
  }

//Servlet-Information holen
  @Override
  public String getServletInfo()
  {
    return "elektra.WebOrder Version:"+version;
  }
}

