package semorg.sql.tables;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import semorg.gui.util.DBTableChangedListener;
import semorg.sql.access.DBAccess;
import semorg.sql.util.DBColumn;
import semorg.sql.util.DBConstraint;
import semorg.sql.util.DistinctVector;
import semorg.sql.util.Utility;

/** Models a company. */
public class Company extends AbstractTable implements SimpleIDKey {

    /**
     * A list of the ids of locked records. This list is meant to avoid the
     * deletion of records, which are currently edited.
     */
    public static List<Integer> lockedIds = new ArrayList<Integer>();

    /** The DB-ID. */
    protected int id;

    /** The short name of a company. */
    protected String shortName;

    /** The salutation. */
    protected String salutation;

    /** The title. */
    protected String title;

    /** The firstname. */
    protected String firstname;

    /** The name. */
    protected String name;

    /** The street. */
    protected String street;

    /** The Zipcode. */
    protected String zipCode;

    /** The city. */
    protected String city;

    /** The country. */
    protected String country;

    /** The annex. */
    protected String annex;

    /** The phone number. */
    protected String phone;

    /** The number of the mobile phone. */
    protected String mobile;

    /** The fax number. */
    protected String fax;

    /** The email address. */
    protected String email;

    /** The salutation of the contact person. */
    protected String cpSalutation;

    /** The title of the contact person. */
    protected String cpTitle;

    /** The firstname of the contact person. */
    protected String cpFirstname;

    /** The lastname of the contact person. */
    protected String cpName;

    /** The phone number of the contact person. */
    protected String cpPhone;

    /** The number of the mobile phone of the contact person. */
    protected String cpMobile;

    /** The fax number of the contact person. */
    protected String cpFax;

    /** The email address of the contact person. */
    protected String cpEmail;

    /** The departement of the contact person. */
    protected String cpDepartment;

    /** The birthday of the contact person. */
    protected Date cpBirthDay;

    /** The task of the contact person in the company. */
    protected String cpTask;

    /** The short information. */
    protected String shortInfo;

    /** The notices. */
    protected String notices;

    /** The turnover produced by a company. */
    protected Float turnover;

    /** The date of becoming a customer. */
    protected Date customerSince;

    /** The name of the corresponding table in the db. */
    private static String tableName = "company";

    /** Parameterized SQL statement for inserting a data record. */
    protected static String companyInsertString = "INSERT INTO " + tableName
	    + " " + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, "
	    + "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, "
	    + "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

    /** SQL statement for creating the table "person" (if not exists). */
    private static String createTableSQLString = "CREATE TABLE IF NOT EXISTS `"
	    + tableName
	    + "` ("
	    + "`id_pk` integer NOT NULL auto_increment,"
	    + "`shortname` varchar(10) NOT NULL,"
	    + "`salutation` varchar(13) NOT NULL,"
	    + "`title` varchar(13),"
	    + "`firstname` varchar(30),"
	    + "`name` varchar(30) NOT NULL,"
	    + "`street` varchar(50),"
	    + "`zipcode` varchar(5),"
	    + "`city` varchar(30),"
	    + "`country` varchar(13),"
	    + "`annex` varchar(13),"
	    + "`phone` varchar(20),"
	    + "`mobile` varchar(20),"
	    + "`fax` varchar(20),"
	    + "`email` varchar(256),"
	    + "`cpsalutation` varchar(13) NOT NULL,"
	    + "`cptitle` varchar(13),"
	    + "`cpfirstname` varchar(30),"
	    + "`cpname` varchar(30) NOT NULL,"
	    + "`cpphone` varchar(20),"
	    + "`cpmobile` varchar(20),"
	    + "`cpfax` varchar(20),"
	    + "`cpemail` varchar(256),"
	    + "`cpdepartment` varchar(30),"
	    + "`cpbirthday` date,"
	    + "`cptask` varchar(30),"
	    + "`shortinfo` varchar(200),"
	    + "`notices` varchar(200),"
	    + "`turnover` float,"
	    + "`customersince` date,"
	    + "`creationdate` timestamp NOT NULL default '0000-00-00 00:00:00',"
	    + "`modificationdate` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,"
	    + "PRIMARY KEY  (`id_pk`) )";

    /** Parameterized SQL statement for updating a data record. */
    protected static String companyUpdateString = "UPDATE " + tableName
	    + " SET "
	    + "shortname=?, salutation=?, title=?, firstname=?, name=?, "
	    + "street=?, zipcode=?, city=?, country=?, annex=?, "
	    + "phone=?, mobile=?, fax=?, email=?, cpsalutation=?, cptitle=?, "
	    + "cpfirstname=?, cpname=?, cpphone=?, cpmobile=?, "
	    + "cpfax=?, cpemail=?, cpdepartment=?, cpbirthday=?, cptask=?, "
	    + "shortinfo=?, notices=?, turnover=?, customersince=?, "
	    + "modificationdate=? WHERE id_pk=?";

    /** SQL query to get all company records from the database. */
    private static String queryString = "SELECT id_pk, shortname, salutation, title,"
	    + "firstname, name, street, zipcode, city, country, annex, "
	    + "phone, mobile, fax, email, cpsalutation, cptitle, "
	    + "cpfirstname, cpname, cpphone, cpmobile, "
	    + "cpfax, cpemail, cpdepartment, cpbirthday, cptask, "
	    + "shortinfo, notices, turnover, customersince, "
	    + "creationdate, modificationdate FROM "
	    + tableName
	    + " WHERE true";

    /** Creates an instance of the class Company with the given parameters. */
    public Company(int id, String shortName, String salutation, String title,
	    String firstname, String name, String street, String zipCode,
	    String city, String country, String annex, String phone,
	    String mobile, String fax, String email, String cpSalutation,
	    String cpTitle, String cpFirstname, String cpName, String cpPhone,
	    String cpMobile, String cpFax, String cpEmail, String cpDepartment,
	    Date cpBirthDay, String cpTask, String shortInfo, String notices,
	    Float turnover, Date customerSince, Timestamp creationDate,
	    Timestamp modificationDate) {

	super(creationDate, modificationDate);

	this.id = id;
	this.shortName = shortName;
	this.salutation = salutation;
	this.title = title;
	this.firstname = firstname;
	this.name = name;

	this.street = street;
	this.zipCode = zipCode;
	this.city = city;
	this.country = country;
	this.annex = annex;

	this.phone = phone;
	this.mobile = mobile;
	this.fax = fax;
	this.email = email;

	this.cpSalutation = cpSalutation;
	this.cpTitle = cpTitle;
	this.cpFirstname = cpFirstname;
	this.cpName = cpName;

	this.cpPhone = cpPhone;
	this.cpMobile = cpMobile;
	this.cpFax = cpFax;
	this.cpEmail = cpEmail;

	this.cpDepartment = cpDepartment;
	this.cpBirthDay = cpBirthDay;
	this.cpTask = cpTask;

	this.shortInfo = shortInfo;
	this.notices = notices;
	this.turnover = turnover;
	this.customerSince = customerSince;

	this.creationDate = creationDate;
	this.modificationDate = modificationDate;
    }

    /**
     * Checks if the according DB table exists.
     * 
     * @see semorg.sql.tables.AbstractTable#tableOK(String)
     * @return <code>true</code>, if the table is ok, <code>false</code>
     *         otherwise.
     */
    public static boolean tableOK() {
	return AbstractTable.tableOK(tableName);
    }

    /**
     * Creates the table "company" if it does not exist.
     * 
     * @param statement
     *                instance of the class Statement, which is used for
     *                executing the SQL statement {@link #createTableSQLString}.
     * @throws SQLException
     *                 If the execution of the given statement with the query
     *                 {@link #createTableSQLString} or its closing fails.
     */
    public static void createCompanyTable(Statement statement)
	    throws SQLException {
	statement.execute(createTableSQLString);
	statement.close();
    }

    /**
     * Converts the actual Company object into a database record and inserts it
     * into the table "company". Furthermore this method queries the
     * auto-generated id, sets the appropriate property {@link #id} and returns
     * the id. If a salutation, title, country, annex, contact person salutation
     * or contact person title has been inserted into the form, this method also
     * inserts the concerning properties into the table "enumeration" for later
     * use. Finally it fires a TableChanged-EventListener to update the UI.
     * 
     * @return the auto-generated id of the inserted company record.
     * @throws SQLException
     *                 If the auto-generated id can't resolved from the db, i.e.
     *                 it hasnt been generated, or the PreparedStatement
     *                 instance can't be created or executed etc.
     */
    public int insertIntoDB() throws SQLException {
	PreparedStatement insertStmt = DBAccess.dbAccess
		.getPreparedStatement(Company.companyInsertString);

	// PK with AUTO_INCREMENT
	insertStmt.setNull(1, Types.INTEGER);
	// NOT NULL
	insertStmt.setString(2, shortName);
	insertStmt.setString(3, salutation);

	insertStmt.setString(4, title);
	insertStmt.setString(5, firstname);
	// NOT NUL
	insertStmt.setString(6, name);

	insertStmt.setString(7, street);
	insertStmt.setString(8, zipCode);
	insertStmt.setString(9, city);
	insertStmt.setString(10, country);
	insertStmt.setString(11, annex);
	insertStmt.setString(12, phone);
	insertStmt.setString(13, mobile);
	insertStmt.setString(14, fax);
	insertStmt.setString(15, email);
	// NOT NULL
	insertStmt.setString(16, cpSalutation);

	insertStmt.setString(17, cpTitle);
	insertStmt.setString(18, cpFirstname);
	// NOT NULL
	insertStmt.setString(19, cpName);

	insertStmt.setString(20, cpPhone);
	insertStmt.setString(21, cpMobile);
	insertStmt.setString(22, cpFax);
	insertStmt.setString(23, cpEmail);
	insertStmt.setString(24, cpDepartment);

	if (cpBirthDay != null)
	    insertStmt.setDate(25, Utility.convertToSQLDate(cpBirthDay));
	else
	    insertStmt.setNull(25, Types.DATE);

	insertStmt.setString(26, cpTask);
	insertStmt.setString(27, shortInfo);
	insertStmt.setString(28, notices);

	if (turnover != null)
	    insertStmt.setFloat(29, turnover);
	else
	    insertStmt.setNull(29, Types.FLOAT);

	if (customerSince != null)
	    insertStmt.setDate(30, Utility.convertToSQLDate(customerSince));
	else
	    insertStmt.setNull(30, Types.DATE);

	insertStmt.setTimestamp(31, Utility.convertToTimestamp(creationDate));
	insertStmt.setTimestamp(32, Utility
		.convertToTimestamp(modificationDate));

	insertStmt.executeUpdate();

	ResultSet rs = insertStmt.getGeneratedKeys();
	if (rs.next()) {
	    this.id = rs.getInt(1);
	} else {
	    // TODO: korrekte Exception werfen
	    throw new SQLException();
	}

	rs.close();
	insertStmt.close();

	if (salutation.length() > 0)
	    Enumeration.insertSalutationStringInDB(salutation);
	if (title.length() > 0)
	    Enumeration.insertTitleStringInDB(title);
	if (country.length() > 0)
	    Enumeration.insertcountryStringInDB(country);
	if (annex.length() > 0)
	    Enumeration.insertAnnexStringInDB(annex);
	if (cpSalutation.length() > 0)
	    Enumeration.insertSalutationStringInDB(cpSalutation);
	if (cpTitle.length() > 0)
	    Enumeration.insertTitleStringInDB(cpTitle);

	AbstractTable
		.fireTableChangedEvent(DBTableChangedListener.TYPE_COMPANY);

	return this.id;

    }

    /**
     * Converts the actual Company object into a database company record and
     * updates a existing record to the changes made. If a salutation, title,
     * country or annex has been inserted into the form, this method also
     * inserts the concerning properties into the table "enumeration" for later
     * use. Finally it fires a TableChanged-EventListener to update the UI.
     * 
     * @throws SQLException
     *                 If the PreparedStatement instance can't be created or
     *                 executed, this exception is thrown.
     */
    public void updateDB() throws SQLException {

	PreparedStatement updateStmt = DBAccess.dbAccess
		.getPreparedStatement(companyUpdateString);

	updateStmt.setString(1, shortName);
	updateStmt.setString(2, salutation);
	updateStmt.setString(3, title);
	updateStmt.setString(4, firstname);
	updateStmt.setString(5, name);
	updateStmt.setString(6, street);
	updateStmt.setString(7, zipCode);
	updateStmt.setString(8, city);
	updateStmt.setString(9, country);
	updateStmt.setString(10, annex);
	updateStmt.setString(11, phone);
	updateStmt.setString(12, mobile);
	updateStmt.setString(13, fax);
	updateStmt.setString(14, email);
	updateStmt.setString(15, cpSalutation);
	updateStmt.setString(16, cpTitle);
	updateStmt.setString(17, cpFirstname);
	updateStmt.setString(18, cpName);
	updateStmt.setString(19, cpPhone);
	updateStmt.setString(20, cpMobile);
	updateStmt.setString(21, cpFax);
	updateStmt.setString(22, cpEmail);
	updateStmt.setString(23, cpDepartment);
	if (cpBirthDay != null)
	    updateStmt.setDate(24, Utility.convertToSQLDate(cpBirthDay));
	else
	    updateStmt.setNull(24, Types.DATE);

	updateStmt.setString(25, cpTask);
	updateStmt.setString(26, shortInfo);
	updateStmt.setString(27, notices);

	if (turnover != null)
	    updateStmt.setFloat(28, turnover);
	else
	    updateStmt.setNull(28, Types.FLOAT);

	if (customerSince != null)
	    updateStmt.setDate(29, Utility.convertToSQLDate(customerSince));
	else
	    updateStmt.setNull(29, Types.DATE);

	updateStmt.setTimestamp(30, new Timestamp(System.currentTimeMillis()));

	// WHERE - Teil
	updateStmt.setInt(31, id);

	updateStmt.executeUpdate();

	updateStmt.close();

	if (salutation.length() > 0)
	    Enumeration.insertSalutationStringInDB(salutation);
	if (title.length() > 0)
	    Enumeration.insertTitleStringInDB(title);
	if (country.length() > 0)
	    Enumeration.insertcountryStringInDB(country);
	if (annex.length() > 0)
	    Enumeration.insertAnnexStringInDB(annex);
	if (cpSalutation.length() > 0)
	    Enumeration.insertSalutationStringInDB(cpSalutation);
	if (cpTitle.length() > 0)
	    Enumeration.insertTitleStringInDB(cpTitle);

	AbstractTable
		.fireTableChangedEvent(DBTableChangedListener.TYPE_COMPANY);

    }

    /**
     * Removes the given elements from the table "company". Due to the FK
     * connections (with an ON-DELETE-cascade) this method fires several
     * TableChanged-Events to update the UI.
     * 
     * @param selectedElements
     *                the elements, which should be deleted from the database.
     * @throws SQLException
     *                 Throws a SQL exception if the Statement instance can't be
     *                 created or executed.
     */
    public static void removeFromDB(Iterable selectedElements)
	    throws SQLException {

	String deleteString = "DELETE FROM " + tableName + " WHERE ";
	Iterator<Company> it = selectedElements.iterator();

	// insert first element
	int idToDelete = it.next().getId();
	deleteString += "id_pk=" + idToDelete + " ";

	// insert the rest of the elements
	while (it.hasNext()) {
	    idToDelete = it.next().getId();
	    deleteString += "OR id_pk=" + idToDelete + " ";
	}
	Statement stmt = DBAccess.dbAccess.getStatement();
	stmt.executeUpdate(deleteString);
	stmt.close();

	AbstractTable
		.fireTableChangedEvent(DBTableChangedListener.TYPE_COMPANY);
	// because of FK-connections (on delete cascade)
	AbstractTable
		.fireTableChangedEvent(DBTableChangedListener.TYPE_BOOKING);
	AbstractTable
		.fireTableChangedEvent(DBTableChangedListener.TYPE_COMPANYBOOKING);

    }

    /**
     * Creates for each element in a given ResultSet instance an Company object
     * and returns a vector with the resulting Company instances.
     * 
     * @param resultSet
     *                given ResultSet instance.
     * @return a DistinctVector instance filled with the created {@link Company}
     *         instances.
     */
    private static DistinctVector<Company> getVector(ResultSet resultSet) {
	DistinctVector<Company> set = new DistinctVector<Company>();
	try {
	    while (resultSet.next()) {

		int id = resultSet.getInt("id_pk");
		String shortName = resultSet.getString("shortname");

		String salutation = resultSet.getString("salutation");
		String title = resultSet.getString("title");
		String firstname = resultSet.getString("firstname");
		String name = resultSet.getString("name");

		String street = resultSet.getString("street");
		String zipCode = resultSet.getString("zipcode");
		String city = resultSet.getString("city");
		String country = resultSet.getString("country");
		String annex = resultSet.getString("annex");

		String phone = resultSet.getString("phone");
		String mobile = resultSet.getString("mobile");
		String fax = resultSet.getString("fax");
		String email = resultSet.getString("email");

		String cpSalutation = resultSet.getString("cpsalutation");
		String cpTitle = resultSet.getString("cptitle");
		String cpFirstname = resultSet.getString("cpfirstname");
		String cpName = resultSet.getString("cpname");

		String cpPhone = resultSet.getString("cpphone");
		String cpMobile = resultSet.getString("cpmobile");
		String cpFax = resultSet.getString("cpfax");
		String cpEmail = resultSet.getString("cpemail");

		String cpDepartment = resultSet.getString("cpdepartment");
		Date cpBirthDay = resultSet.getDate("cpbirthday");
		String cpTask = resultSet.getString("cptask");

		String shortInfo = resultSet.getString("shortinfo");
		String notices = resultSet.getString("notices");
		Float turnover = resultSet.getFloat("turnover");
		if (resultSet.wasNull())
		    turnover = null;
		Date customerSince = resultSet.getDate("customersince");

		Timestamp creationDate = resultSet.getTimestamp("creationdate");
		Timestamp modificationDate = resultSet
			.getTimestamp("modificationdate");

		set
			.add(new Company(id, shortName, salutation, title,
				firstname, name, street, zipCode, city,
				country, annex, phone, mobile, fax, email,
				cpSalutation, cpTitle, cpFirstname, cpName,
				cpPhone, cpMobile, cpFax, cpEmail,
				cpDepartment, cpBirthDay, cpTask, shortInfo,
				notices, turnover, customerSince, creationDate,
				modificationDate));
	    }
	} catch (SQLException e) {
	    e.printStackTrace();
	}
	return set;
    }

    /**
     * Creates a PreparedStatement instance with the given parameters, executes
     * the query and returns a vector of Company instances corresponding to the
     * ResultSet of the query.
     * 
     * @param additionalConstraints
     *                additional conditions of the WHERE-clause
     * @param sortString
     *                sort string with the following structure
     *                <code>ORDER BY attribute [ASC|DSC]</code>
     * @return a DistinctVector instance filled with the created Company
     *         instances.
     * @throws SQLException
     *                 sf the PreparedStatement can't be created or the
     *                 execution of the query fails.
     */
    public static DistinctVector<Company> getVectorFromDB(
	    Vector<DBConstraint> additionalConstraints, String sortString)
	    throws SQLException {

	PreparedStatement stmt = AbstractTable.createExtendedQueryString(
		queryString, additionalConstraints, sortString);

	ResultSet rs = stmt.executeQuery();

	DistinctVector<Company> returnValue = Company.getVector(rs);
	rs.close();
	stmt.close();
	return returnValue;
    }

    /**
     * Returns a vector of {@link semorg.sql.util.DBColumn} instances according to
     * the properties of the table "company".
     * 
     * @return the vector of DBColumn instances according to the properties of
     *         the class Company.
     * @see semorg.sql.tables.AbstractTable#getColumns(String tableAbbreviation)
     */
    public static Vector<DBColumn> getColumns() {

	Vector<DBColumn> columns = new Vector<DBColumn>();
	columns.add(new DBColumn("id_pk", "Nummer", Integer.class));
	columns.add(new DBColumn("shortname", "Kurzname", String.class));

	columns.add(new DBColumn("salutation", "Firma-Anrede", String.class));
	columns.add(new DBColumn("title", "Firma-Titel", String.class));
	columns.add(new DBColumn("firstname", "Firma-Vorname", String.class));
	columns.add(new DBColumn("name", "Firma-Name", String.class));

	columns.add(new DBColumn("street", "Firma-Strasse", String.class));
	columns.add(new DBColumn("zipcode", "Firma-PLZ", String.class));
	columns.add(new DBColumn("city", "Firma-Stadt", String.class));
	columns.add(new DBColumn("country", "Firma-Land", String.class));
	columns.add(new DBColumn("annex", "Firma-Zusatz", String.class));

	columns.add(new DBColumn("phone", "Firma-Telefon", String.class));
	columns.add(new DBColumn("mobile", "Firma-Handy", String.class));
	columns.add(new DBColumn("fax", "Firma-Fax", String.class));
	columns.add(new DBColumn("email", "Firma-Email", String.class));

	columns
		.add(new DBColumn("cpsalutation", "Partner-Anrede",
			String.class));
	columns.add(new DBColumn("cptitle", "Partner-Titel", String.class));
	columns
		.add(new DBColumn("cpfirstname", "Partner-Vorname",
			String.class));
	columns.add(new DBColumn("cpname", "Partner-Name", String.class));

	columns.add(new DBColumn("cpphone", "Partner-Telefon", String.class));
	columns.add(new DBColumn("cpmobile", "Partner-Handy", String.class));
	columns.add(new DBColumn("cpfax", "Partner-Fax", String.class));
	columns.add(new DBColumn("cpemail", "Partner-Email", String.class));

	columns.add(new DBColumn("cpdepartment", "Partner-Abteilung",
		String.class));
	columns
		.add(new DBColumn("cpbirthday", "Partner-Geburtstag",
			Date.class));
	columns.add(new DBColumn("cptask", "Partner-Funktion", String.class));

	columns.add(new DBColumn("shortinfo", "Kurzmitteilung", String.class));
	columns.add(new DBColumn("notices", "Notizen", String.class));
	columns.add(new DBColumn("turnover", "Umsatz", Float.class));
	columns.add(new DBColumn("customersince", "Kunde seit", Date.class));

	columns.addAll(AbstractTable.getColumns(""));
	return columns;
    }

    /**
     * Returns for a DB-ID the Company instance according to the record which
     * has the next bigger id.
     * 
     * @param lecturerId
     *                the key of the current record
     * @return the Company instance corresponding to the next record in the
     *         table "company" or if it does not exist the Company instance with
     *         the smallest id.
     * @see semorg.sql.tables.AbstractTable#getNext(String, DBColumn, int)
     */
    public static Company getNext(int lecturerId) {
	Company returnValue = null;
	ResultSet rs = AbstractTable.getNext(queryString, getColumns().get(0),
		lecturerId);
	if (rs != null) {
	    returnValue = Company.getVector(rs).iterator().next();
	    try {
		Statement producingStatement = rs.getStatement();
		rs.close();
		if (producingStatement != null)
		    producingStatement.close();

	    } catch (SQLException e) {
		e.printStackTrace();
	    }

	}
	return returnValue;
    }

    /**
     * Returns for a DB-ID the Company instance according to the record which
     * has the next smaller id.
     * 
     * @param lecturerId
     *                the key of the current record
     * @return the Company instance corresponding to the previous record in the
     *         table "company" or if it does not exist the Company instance with
     *         the biggest id.
     * @see semorg.sql.tables.AbstractTable#getPrevious(String, DBColumn, int)
     */
    public static Company getPrevious(int lecturerId) {
	Company returnValue = null;
	ResultSet rs = AbstractTable.getPrevious(queryString, getColumns().get(
		0), lecturerId);
	if (rs != null) {
	    returnValue = Company.getVector(rs).iterator().next();
	    try {
		// the statement which produced the resultset
		Statement producingStatement = rs.getStatement();
		rs.close();
		if (producingStatement != null)
		    producingStatement.close();

	    } catch (SQLException e) {
		e.printStackTrace();
	    }

	}
	return returnValue;
    }

    /**
     * Returns a Company instance for a given company id.
     * 
     * @param companyId
     *                id of the wanted Company instance
     * @return the Company instance according to the given id
     * @throws SQLException
     *                 if the execution for the wanted company fails.
     */
    public static Company getCompany(int companyId) throws SQLException {
	Vector<DBConstraint> keyConstraint = new Vector<DBConstraint>();
	// key constraint: id_pk = companyId
	keyConstraint.add(new DBConstraint(Company.getColumns().get(0)
		.getInternalColumnName(), DBConstraint.REL_EQ, new Integer(
		companyId), DBConstraint.CONJ_END));
	// get companies for the constraint
	DistinctVector<Company> companys = Company.getVectorFromDB(
		keyConstraint, null);
	// return the first
	return companys.iterator().next();
    }

    /** Returns the id. */
    public int hashCode() {
	return id;
    }

    /**
     * If the given object is an instance of the Company class this method
     * compares the id of the given and the actual object, otherwise it calls
     * the equal-method of the AbstractTable class with the given object.
     * 
     * @param otherCompany
     *                object to be compared with the actual object.
     * @return <code>true</code> if the id of the given object and the actual
     *         object are the same, <code>false</code> otherwise.
     */
    public boolean equals(Object otherCompany) {
	if (otherCompany instanceof Company)
	    return id == (((Company) otherCompany).id);
	else
	    return super.equals(otherCompany);
    }

    public int getId() {
	return id;
    }

    public String getAnnex() {
	return annex;
    }

    public void setAnnex(String annex) {
	this.annex = annex;
    }

    public String getCity() {
	return city;
    }

    public void setCity(String city) {
	this.city = city;
    }

    public String getCountry() {
	return country;
    }

    public void setCountry(String country) {
	this.country = country;
    }

    public Date getCpBirthDay() {
	return cpBirthDay;
    }

    public void setCpBirthDay(Date cpBirthDay) {
	this.cpBirthDay = cpBirthDay;
    }

    public String getCpDepartment() {
	return cpDepartment;
    }

    public void setCpDepartment(String cpDepartment) {
	this.cpDepartment = cpDepartment;
    }

    public String getCpEmail() {
	return cpEmail;
    }

    public void setCpEmail(String cpEmail) {
	this.cpEmail = cpEmail;
    }

    public String getCpFax() {
	return cpFax;
    }

    public void setCpFax(String cpFax) {
	this.cpFax = cpFax;
    }

    public String getCpFirstname() {
	return cpFirstname;
    }

    public void setCpFirstname(String cpFirstname) {
	this.cpFirstname = cpFirstname;
    }

    public String getCpMobile() {
	return cpMobile;
    }

    public void setCpMobile(String cpMobile) {
	this.cpMobile = cpMobile;
    }

    public String getCpName() {
	return cpName;
    }

    public void setCpName(String cpName) {
	this.cpName = cpName;
    }

    public String getCpPhone() {
	return cpPhone;
    }

    public void setCpPhone(String cpPhone) {
	this.cpPhone = cpPhone;
    }

    public String getCpSalutation() {
	return cpSalutation;
    }

    public void setCpSalutation(String cpSalutation) {
	this.cpSalutation = cpSalutation;
    }

    public String getCpTask() {
	return cpTask;
    }

    public void setCpTask(String cpTask) {
	this.cpTask = cpTask;
    }

    public String getCpTitle() {
	return cpTitle;
    }

    public void setCpTitle(String cpTitle) {
	this.cpTitle = cpTitle;
    }

    public Date getCustomerSince() {
	return customerSince;
    }

    public void setCustomerSince(Date customerSince) {
	this.customerSince = customerSince;
    }

    public String getEmail() {
	return email;
    }

    public void setEmail(String email) {
	this.email = email;
    }

    public String getFax() {
	return fax;
    }

    public void setFax(String fax) {
	this.fax = fax;
    }

    public String getFirstname() {
	return firstname;
    }

    public void setFirstname(String firstname) {
	this.firstname = firstname;
    }

    public String getMobile() {
	return mobile;
    }

    public void setMobile(String mobile) {
	this.mobile = mobile;
    }

    public String getName() {
	return name;
    }

    public void setName(String name) {
	this.name = name;
    }

    public String getNotices() {
	return notices;
    }

    public void setNotices(String notices) {
	this.notices = notices;
    }

    public String getPhone() {
	return phone;
    }

    public void setPhone(String phone) {
	this.phone = phone;
    }

    public String getSalutation() {
	return salutation;
    }

    public void setSalutation(String salutation) {
	this.salutation = salutation;
    }

    public String getShortInfo() {
	return shortInfo;
    }

    public void setShortInfo(String shortInfo) {
	this.shortInfo = shortInfo;
    }

    public String getShortName() {
	return shortName;
    }

    public void setShortName(String shortName) {
	this.shortName = shortName;
    }

    public String getStreet() {
	return street;
    }

    public void setStreet(String street) {
	this.street = street;
    }

    public String getTitle() {
	return title;
    }

    public void setTitle(String title) {
	this.title = title;
    }

    public Float getTurnover() {
	return turnover;
    }

    public void setTurnover(Float turnover) {
	this.turnover = turnover;
    }

    public String getZipCode() {
	return zipCode;
    }

    public void setZipCode(String zipCode) {
	this.zipCode = zipCode;
    }
}
