/* outboxaccjobs.h

 ***************************************************************************
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Lesser General Public            *
 *   License as published by the Free Software Foundation; either          *
 *   version 2.1 of the License, or (at your option) any later version.    *
 *                                                                         *
 *   This library is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   Lesser General Public License for more details.                       *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the Free Software   *
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
 *   MA  02111-1307  USA                                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef OUTBOXACCJOBS_H
#define OUTBOXACCJOBS_H

/** @file outboxaccjobs.h
 *
 * @short Account-related OutboxJobs and their C wrappers. */

#ifdef __cplusplus
#include <string>
#include <list>
#endif /* __cplusplus */

#include <openhbci/dllimport.h>
#include <openhbci/pointer.h>
#include <openhbci/customer.h>
#include <openhbci/user.h>
#include <openhbci/bank.h>
#include <openhbci/account.h>
#include <openhbci/outboxjob.h>

#ifdef __cplusplus

namespace HBCI {

  /**
   * @short Abstract base class for account based OutboxJob in HBCIAPI
   *
   * This is an abstract base class of the OpenHBCI-Wrapper API for account
   * based jobs.
   * @short Abstract base class for account based jobs.
   * @author Martin Preuss<martin@libchipcard.de>
   */
  class DLLIMPORT OutboxAccountJob: public OutboxJob {
  private:
  protected:
    Pointer<Account> _acc;

    string _makeDescription(const string &dscr) const;
  public:
    OutboxAccountJob(Pointer<Customer> c,
		     Pointer<Account> a);
    ~OutboxAccountJob();

    Pointer<Account> account() const { return _acc;};
    virtual list<int> resultCodes() const = 0;
  };

} /* namespace HBCI */
#endif /* __cplusplus */




#ifdef __cplusplus

namespace HBCI {

  /**
   * This job retrieves the balance of one account.
   * @author Martin Preuss<martin@libchipcard.de>
   * @short Job that retrieves the balance of an Account
   */
  class DLLIMPORT OutboxJobGetBalance: public OutboxAccountJob {
  private:
    Pointer<Job> _job;

  public:
    OutboxJobGetBalance(Pointer<Customer> c,
			Pointer<Account> a);
    ~OutboxJobGetBalance();

    bool createHBCIJobs(Pointer<MessageQueue> mbox, int n=0);
    bool evaluate();
    bool commit(int msgNumber=HBCI_COMMIT_WHOLE_JOB);
    string description() const;
    JobProgressType type() const { return JOB_GET_BALANCE; };
    list<int> resultCodes() const;

    /**
     * @short Returns the balance retrieved.
     */
    const AccountBalance &getBalance() const;

    /**
     * @short Checks if getting the balance is supported for the
     * specified account.
     *
     * If this method returns <false>, your application should provide a way
     * to allow this job anyway because some banks just don't tell you that
     * they support this job for the specified account. Only if <true> is
     * returned, you can be sure this job is supported.
     */
    static bool isSupported(Pointer<Account> forAccount);

  };

} /* namespace HBCI */
/** @ingroup HBCI_OutboxJobg */
typedef struct HBCI::OutboxJobGetBalance HBCI_OutboxJobGetBalance;

extern "C" {
#else /* __cplusplus */
  typedef struct HBCI_OutboxJobGetBalance HBCI_OutboxJobGetBalance;
#endif /* __cplusplus */
  /** @name HBCI_OutboxJobGetBalance
   * @ingroup HBCI_OutboxJobg */
  /*@{*/
  /** Constructor */
  extern HBCI_OutboxJobGetBalance *
    HBCI_OutboxJobGetBalance_new(const HBCI_Customer *c, HBCI_Account *a);
  /** Upcast */
  extern HBCI_OutboxJob *
    HBCI_OutboxJobGetBalance_OutboxJob(HBCI_OutboxJobGetBalance *j);
  extern const HBCI_AccountBalance *
    HBCI_OutboxJobGetBalance_getBalance(const HBCI_OutboxJobGetBalance *j);
  /*@}*/
#ifdef __cplusplus
}

namespace HBCI {

  /**
   * This job retrieves the transactions of one account.
   * @short Job that retrieves all Transaction's of one Account
   * @author Martin Preuss<martin@libchipcard.de>
   */
  class DLLIMPORT OutboxJobGetTransactions: public OutboxAccountJob {
  private:
    Pointer<Job> _job;
    Date _fromdate;
    Date _todate;

  public:
    /**
     * This job retrieves a list of transaction statements from the server.
     * @author Martin Preuss<martin@libchipcard.de>
     * @param c Customer that invokes this job.
     * @param a Account that this job should work on.
     * @param fromDate date of the first day you want to inspect, if invalid
     * then the first possible date will be used. Please note that some
     * banks NEED this date to be set
     * @param todate date of the last day you want to inspect, if invalid
     * then the current date will be used.
     */
    OutboxJobGetTransactions(Pointer<Customer> c,
			     Pointer<Account> a,
			     Date fromDate,
			     Date todate);
    ~OutboxJobGetTransactions();

    bool createHBCIJobs(Pointer<MessageQueue> mbox, int n=0);
    bool evaluate();
    bool stillMessagesToSend(int nextMsg) const;
    bool commit(int msgNumber=HBCI_COMMIT_WHOLE_JOB);
    string description() const;
    JobProgressType type() const { return JOB_GET_TRANS; };
    list<int> resultCodes() const;

    /** Returns the fromDate as specified in the constructor. */
    const Date& fromDate() const { return _fromdate; };
    
    /** Returns the toDate as specified in the constructor. */
    const Date& toDate() const { return _todate; };

    /**
     * Returns the last balance detected by this job. This can be used
     * if the bank does not support the JOBGetBalance.
     * @author Martin Preuss<openhbci@aquamaniac.de>
     */
    const Balance& lastBalance() const;
    
    /**
     * @short Returns the list of transactions that this job retrieved.
     */
    const list<Transaction> &transactions() const;

    /**
     * @short Checks if getting transactions is supported for the
     * specified account.
     *
     * If this method returns <false>, your application should provide a way
     * to allow this job anyway because some banks just don't tell you that
     * they support this job for the specified account. Only if <true> is
     * returned, you can be sure this job is supported.
     */
    static bool isSupported(Pointer<Account> forAccount);

  };

} /* namespace HBCI */
/** @ingroup HBCI_OutboxJobg */
typedef struct HBCI::OutboxJobGetTransactions HBCI_OutboxJobGetTransactions;

extern "C" {
#else /* __cplusplus */
  typedef struct HBCI_OutboxJobGetTransactions HBCI_OutboxJobGetTransactions;
#endif /* __cplusplus */
  /** @name HBCI_OutboxJobGetTransactions
   * @ingroup HBCI_OutboxJobg */
  /*@{*/
  /** Constructor */
  extern HBCI_OutboxJobGetTransactions *
    HBCI_OutboxJobGetTransactions_new(const HBCI_Customer *c,
				      HBCI_Account *a,
				      const HBCI_Date *fromdate,
				      const HBCI_Date *todate);
  /** Upcast */
  extern HBCI_OutboxJob *
    HBCI_OutboxJobGetTransactions_OutboxJob(HBCI_OutboxJobGetTransactions *j);
  /** Returns the list of transactions. */
  extern const list_HBCI_Transaction *
    HBCI_OutboxJobGetTransactions_transactions(const HBCI_OutboxJobGetTransactions *j);
  /**
   * Returns the last balance detected by this job. This can be used
   * if the bank does not support the JOBGetBalance.
   */
  extern const HBCI_Balance *
  HBCI_OutboxJobGetTransactions_lastBalance(const HBCI_OutboxJobGetTransactions *j);
  /** Returns the fromDate as specified in the constructor. */
  extern const HBCI_Date * 
  HBCI_OutboxJobGetTransactions_fromDate(const HBCI_OutboxJobGetTransactions *j);

  /** Returns the toDate as specified in the constructor. */
  extern const HBCI_Date * 
  HBCI_OutboxJobGetTransactions_toDate(const HBCI_OutboxJobGetTransactions *j);
  /*@}*/
#ifdef __cplusplus
}

namespace HBCI {

  /**
   * @short Job that initiates a money transfer from a Account
   * This job transfers money from one of our account to somebody else's account.
   * @author Martin Preuss<martin@libchipcard.de>
   */
  class DLLIMPORT OutboxJobTransfer: public OutboxAccountJob {
  private:
    Pointer<Job> _job;
    Transaction _xaction;

  public:
    OutboxJobTransfer(Pointer<Customer> c,
		      Pointer<Account> a,
		      Transaction xa);
    ~OutboxJobTransfer();

    /* retrieve data that is needed to create a transaction for this account */

    /**
     * Bank-information - needed to create a valid transaction<br>
     * Returns the max. allowed number of lines in the description-field
     */
    static int maxDescriptionLines(const Bank &forBank);

    /**
     * Bank-information - needed to create a valid transaction<br>
     * Returns a list of all transaction codes that are allowed
     * @see transactionCode()
     */
    static list<int> transactionCodes(const Bank &forBank);

    /**
     * Return the transaction this job is/was supposed to perform.
     * @author Martin Preuss<martin@libchipcard.de>
     */
    const Transaction &transaction() const { return _xaction;};

    /**
     * @short Checks if making a money transfer is supported for the
     * specified account.
     *
     * If this method returns <false>, your application should provide a way
     * to allow this job anyway because some banks just don't tell you that
     * they support this job for the specified account. Only if <true> is
     * returned, you can be sure this job is supported.
     */
    static bool isSupported(Pointer<Account> forAccount);

    /**
     * @short Returns the limit for transfers.
     *
     * Note: Not all banks tell us about the existance of a limit.
     * There might be a limit for this job even if limit().isValid()==false!
     */
    static const Limit limit(Pointer<Account> forAccount);

    bool createHBCIJobs(Pointer<MessageQueue> mbox, int n=0);
    bool evaluate();
    bool commit(int msgNumber=HBCI_COMMIT_WHOLE_JOB);
    string description() const;
    JobProgressType type() const { return JOB_NEW_TRANSFER; };
    list<int> resultCodes() const;

    /**
     * Returns the number of the segment to be used for status reports.
     * Returns "-1" as default, meaning no segment number (NOTE: In this case
     * the corresponding field in HKPRO will be left out)
     */
    virtual int segmentForStatusReport() const;
  };

} /* namespace HBCI */
/** @ingroup HBCI_OutboxJobg */
typedef struct HBCI::OutboxJobTransfer HBCI_OutboxJobTransfer;

extern "C" {
#else /* __cplusplus */
  typedef struct HBCI_OutboxJobTransfer HBCI_OutboxJobTransfer;
#endif /* __cplusplus */
  /** @name HBCI_OutboxJobTransfer
   * @ingroup HBCI_OutboxJobg */
  /*@{*/
  /** Constructor */
  extern HBCI_OutboxJobTransfer *
    HBCI_OutboxJobTransfer_new(const HBCI_Customer *c,
			       HBCI_Account *a,
			       const HBCI_Transaction *trans);
  /** Upcast */
  extern HBCI_OutboxJob *
    HBCI_OutboxJobTransfer_OutboxJob(HBCI_OutboxJobTransfer *j);
  /*@}*/
#ifdef __cplusplus
}


namespace HBCI {

  /**
   * @short Job that issues a debit note in favor of a Account
   *
   * This job draws money from a foreign account to one of yours.
   * You'll need to sign a special contract with your credit institute to enable this
   * feature.
   * @author Martin Preuss<martin@libchipcard.de>
   */
  class DLLIMPORT OutboxJobDebitNote: public OutboxAccountJob {
  private:
    Pointer<Job> _job;
    Transaction _xaction;

  public:
    OutboxJobDebitNote(Pointer<Customer> c,
		       Pointer<Account> a,
		       Transaction xa);
    ~OutboxJobDebitNote();

    bool createHBCIJobs(Pointer<MessageQueue> mbox, int n=0);
    bool evaluate();
    bool commit(int msgNumber=HBCI_COMMIT_WHOLE_JOB);
    string description() const;
    JobProgressType type() const { return JOB_DEBIT_NOTE; };
    list<int> resultCodes() const;

    /**
     * Return the transaction (debit note) this job is/was supposed to perform.
     * @author Martin Preuss<martin@libchipcard.de>
     */
    const Transaction &transaction() const { return _xaction;};

    /**
     * @short Checks if making a debit note is supported for the
     * specified account.
     *
     * If this method returns <false>, your application should provide a way
     * to allow this job anyway because some banks just don't tell you that
     * they support this job for the specified account. Only if <true> is
     * returned, you can be sure this job is supported.
     */
    static bool isSupported(Pointer<Account> forAccount);

    /**
     * @short Returns the limit for debit notes
     *
     * Note: Not all banks tell us about the existance of a limit.
     * There might be a limit for this job even if limit().isValid()==false!
     */
    static const Limit limit(Pointer<Account> forAccount);

    /**
     * Returns the number of the segment to be used for status reports.
     * Returns "-1" as default, meaning no segment number (NOTE: In this case
     * the corresponding field in HKPRO will be left out)
     */
    virtual int segmentForStatusReport() const;
  };

} /* namespace HBCI */
/** @ingroup HBCI_OutboxJobg */
typedef struct HBCI::OutboxJobDebitNote HBCI_OutboxJobDebitNote;

extern "C" {
#else /* __cplusplus */
  typedef struct HBCI_OutboxJobDebitNote HBCI_OutboxJobDebitNote;
#endif /* __cplusplus */
  /** @name HBCI_OutboxJobDebitNote
   * @ingroup HBCI_OutboxJobg */
  /*@{*/
  /** Constructor */
  extern HBCI_OutboxJobDebitNote *
    HBCI_OutboxJobDebitNote_new(const HBCI_Customer *c,
				HBCI_Account *a,
				const HBCI_Transaction *trans);
  /** Upcast */
  extern HBCI_OutboxJob *
    HBCI_OutboxJobDebitNote_OutboxJob(HBCI_OutboxJobDebitNote *j);
  /*@}*/
#ifdef __cplusplus
}
#endif /* __cplusplus */



#endif
