/**
   * Creates a new <code>AccountingEntryDialog</code> to let the user edit an existing entry.
   *
   * @param parent This dialog's parent frame.
   * @param modal Whether this dialog should be modal or not.
   * @param dbcon A connection to the database where the accounting information is stored.
   * @param ID The ID of the entry to be edited.
   * @see salssuite.server.module.AccountingModule#buildDatabase
   */
  public AccountingEntryDialog(java.awt.Frame parent, boolean modal, Connection dbcon, int ID) {
    this(parent, modal, dbcon);
    this.ID = ID;

    // overwrite default values loaded in other constructor
    try {
      ResultSet entry = stmt.executeQuery("SELECT * FROM accounting " + "WHERE id = " + ID);
      entry.next();

      date = entry.getString("date");
      String[] dateParts = Util.parseDateString(date);
      dayInput.setText(dateParts[2]);
      monthInput.setText(dateParts[1]);
      yearInput.setText(dateParts[0]);

      time = entry.getString("time");
      String[] timeParts = Util.parseTimeString(time);
      hourInput.setText(timeParts[0]);
      minutesInput.setText(timeParts[1]);
      secondsInput.setText(timeParts[2]);

      outgoInput.setText(entry.getString("outgo").replaceAll("-", ""));
      incomeInput.setText(entry.getString("income"));
      descriptionInput.setText(entry.getString("description"));
    } catch (SQLException e) {
      JOptionPane.showMessageDialog(
          this,
          "Fehler bei der Kommunikation mit der" + " Datenbank",
          "Netzwerkfehler",
          JOptionPane.ERROR_MESSAGE);
      e.printStackTrace();
      return;
    }

    setTitle("Eintrag bearbeiten");
    outgoInput.requestFocus();
  }
  /**
   * Parses the input and updates all fields of this dialog. Displays error messages if any error
   * occurs.
   *
   * @return false if an error occured (most likely due to bad user input); true if everything went
   *     fine.
   */
  private boolean parseInput() {

    // date and time
    int day, month, year;
    int hour, minutes, seconds;

    try {
      day = Integer.parseInt(dayInput.getText());
      month = Integer.parseInt(monthInput.getText());
      year = Integer.parseInt(yearInput.getText());

      hour = Integer.parseInt(hourInput.getText());
      minutes = Integer.parseInt(minutesInput.getText());
      seconds = Integer.parseInt(secondsInput.getText());

      if (day > 31
          || day < 1
          || month < 1
          || month > 12
          || year < 0
          || hour < 0
          || hour > 24
          || minutes < 0
          || minutes > 59
          || seconds < 0
          || seconds > 60) throw new NumberFormatException();

      date = "" + year + "-" + month + "-" + day;
      time = "" + hour + ":" + minutes + ":" + seconds;
    } catch (NumberFormatException e) {
      JOptionPane.showMessageDialog(
          this,
          "Ungültiges Datums- oder" + "Zeitformat.",
          "Eingabefehler",
          JOptionPane.ERROR_MESSAGE);
      return false;
    }

    // outgo and income
    try {
      if (outgoInput.getText().length() != 0)
        outgo = Double.parseDouble(outgoInput.getText().replaceAll(",", "."));
      else outgo = 0;
      if (incomeInput.getText().length() != 0)
        income = Double.parseDouble(incomeInput.getText().replaceAll(",", "."));
      else income = 0;

      if (outgo == 0 && income == 0) {
        JOptionPane.showMessageDialog(
            this,
            "Mindestens eines der Felder" + " 'Ausgaben' und 'Einnahmen' muss ausgefüllt werden.",
            "Eingabefehler",
            JOptionPane.ERROR_MESSAGE);
        return false;
      }

      if (outgo < 0 || income < 0) {
        JOptionPane.showMessageDialog(
            this,
            "Ausgaben und Einnahmen" + " müssen positiv sein.",
            "Eingabefehler",
            JOptionPane.ERROR_MESSAGE);
        return false;
      }
    } catch (NumberFormatException e) {
      JOptionPane.showMessageDialog(
          this,
          "Ungültige Eingabe von" + " Ausgaben oder Einnahmen.",
          "Eingabefehler",
          JOptionPane.ERROR_MESSAGE);
      return false;
    }

    // category
    category = (String) categoryChooser.getSelectedItem();
    if (category == null) {
      JOptionPane.showMessageDialog(
          this, "Bitte eine Kategorie wählen.", "Eingabefehler", JOptionPane.ERROR_MESSAGE);
      return false;
    }

    // description
    description = descriptionInput.getText();
    if (description.length() == 0) {
      JOptionPane.showMessageDialog(
          this, "Bitte eine Beschreibung eingeben.", "Eingabefehler", JOptionPane.ERROR_MESSAGE);
      return false;
    }

    // check if user attempts to use forbidden characters
    if (!Util.checkInput(description)) return false;

    return true;
  }
  /**
   * Sets the order represented by this component. The visual representation is done accordingly.
   *
   * @param orderID The order to be represented.
   * @param companyID The company which has ordered something.
   */
  public void setOrder(int orderID, int companyID) {

    this.orderID = orderID;

    try {

      // fetch data from the database
      ResultSet order = stmt.executeQuery("SELECT * FROM orders WHERE " + "id = " + orderID);
      order.next();

      // do visual representation
      IDDisplay.setText("" + orderID);
      companyInput.setText("" + order.getInt("companyId"));
      String[] date = Util.parseDateString(order.getString("date"));
      String[] time = Util.parseTimeString(order.getString("time"));

      if (!(date == null) && !(time == null)) {
        dayInput.setText(date[2]);
        monthInput.setText(date[1]);
        yearInput.setText(date[0]);
        hourInput.setText(time[0]);
        minuteInput.setText(time[1]);
      }

      if (order.getInt("processed") == 1) isOrderProcessedCheckbox.setSelected(true);
      else isOrderProcessedCheckbox.setSelected(false);

      if (order.getInt("paid") == 1) isOrderPaidCheckbox.setSelected(true);
      else isOrderPaidCheckbox.setSelected(false);

      // process the wares belonging to this order
      ResultSet orderedWares =
          stmt.executeQuery(
              "SELECT wareId, pieces FROM"
                  + " orderParts WHERE orderId = "
                  + orderID
                  + " ORDER BY (wareId)");

      while (orderedWares.next()) {

        Statement stmt2 = client.getDatabaseConnection().createStatement();
        ResultSet ware =
            stmt2.executeQuery(
                "SELECT name FROM goods " + "WHERE id = " + orderedWares.getInt("wareId"));
        ware.next();

        // new entry for ware display
        String wareEntry = "";
        wareEntry += orderedWares.getInt("wareId") + " // ";
        wareEntry += ware.getString("name") + " // ";
        wareEntry += orderedWares.getInt("pieces");

        wareListModel.addElement(wareEntry);
      }

    } catch (SQLException e) {
      JOptionPane.showMessageDialog(
          client,
          "Fehler bei der Kommunikation" + "mit der Datenbank.",
          "Netzwerkfehler",
          JOptionPane.ERROR_MESSAGE);
      e.printStackTrace();
      return;
    }

    // update total numbers
    updateTotalNumbers();
  }
  /**
   * Saves this ware's ID, date, time, and wares. Does NOT save the 'processed' and 'paid' state.
   */
  private void saveOrder() {

    // parse ID and date
    int newCompanyID;
    GregorianCalendar date;

    try {
      newCompanyID = Integer.parseInt(companyInput.getText());

      date = new GregorianCalendar();
      date.set(GregorianCalendar.DAY_OF_MONTH, Integer.parseInt(dayInput.getText()));
      date.set(GregorianCalendar.MONTH, Integer.parseInt(monthInput.getText()) - 1);
      date.set(GregorianCalendar.YEAR, Util.expandYear(Integer.parseInt(yearInput.getText())));
      date.set(GregorianCalendar.HOUR_OF_DAY, Integer.parseInt(hourInput.getText()));
      date.set(GregorianCalendar.MINUTE, Integer.parseInt(minuteInput.getText()));

    } catch (NumberFormatException e) {
      JOptionPane.showMessageDialog(
          client,
          "Fehler beim Parsen des" + "Bestelldatums oder der Firmen-ID.",
          "Eingabefehler",
          JOptionPane.ERROR_MESSAGE);
      return;
    }

    // parse wares
    TreeMap<Integer, Integer> wares = new TreeMap<Integer, Integer>();

    for (int i = 0; i < wareListModel.getSize(); i++) {
      String wareDescr = (String) wareListModel.get(i);

      int pieces = Integer.parseInt(wareDescr.split("//")[2].trim());

      int ID = Integer.parseInt(wareDescr.split("//")[0].trim());

      wares.put(ID, pieces);
    }

    // update the database entry
    try {
      stmt.executeUpdate(
          "UPDATE orders SET "
              + "companyId = "
              + newCompanyID
              + ", "
              + "date = "
              + "'"
              + Util.getDateString(date)
              + "', "
              + "time = "
              + "'"
              + Util.getTimeString(date)
              + "' "
              + " WHERE id = "
              + orderID);

      stmt.executeUpdate("DELETE FROM orderParts WHERE orderId = " + orderID);

      for (Integer wareID : wares.keySet()) {
        stmt.executeUpdate(
            "INSERT INTO orderParts (orderId, wareId, pieces)"
                + "VALUES ("
                + orderID
                + ","
                + wareID
                + ","
                + wares.get(wareID)
                + ")");
      }
    } catch (SQLException e) {
      JOptionPane.showMessageDialog(
          client,
          "Fehler bei der" + "Kommunikation mit der Datenbank.",
          "Fehler beim Speichern",
          JOptionPane.ERROR_MESSAGE);
      e.printStackTrace();
      return;
    }

    // update the total numbers displays
    updateTotalNumbers();
  }