/* outboxstojobs.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 OUTBOXSTOJOBS_H
#define OUTBOXSTOJOBS_H

/** @file outboxstojobs.h
 *
 * @short Standing Order 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/outboxaccjobs.h>
#include <openhbci/limit.h>

#ifdef __cplusplus

namespace HBCI {

/**
 * This job retrieves all standing orders for one account.
 * @short Job that retrieves all standing orders for one Account
 * @author Fabian Kaiser<openhbci@derzach.de>
 */
class DLLIMPORT OutboxJobGetStandingOrders: public OutboxAccountJob {
private:
    Pointer<Job> _job;
    list<Pointer<StandingOrder> > _orders;
public:
    OutboxJobGetStandingOrders(Pointer<Customer> c,
                               Pointer<Account> a);
    ~OutboxJobGetStandingOrders();

    /**
     * @short Returns the list of standing orders that were retrieved.
     */
    const list<Pointer<StandingOrder> > &getOrders() const;

	/**
	 * @short Checks if getting a list of standing orders 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);

    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_STO; };
    list<int> resultCodes() const;
};

} /* namespace HBCI */
/** @ingroup HBCI_OutboxJobg */
typedef struct HBCI::OutboxJobGetStandingOrders HBCI_OutboxJobGetStOs;
extern "C" {
#else /* __cplusplus */
    typedef struct HBCI_OutboxJobGetStOs HBCI_OutboxJobGetStOs;
#endif /* __cplusplus */
    /** @name HBCI_OutboxJobGetStOs 
     * @ingroup HBCI_OutboxJobg */
    /*@{*/
    /** Constructor */
    extern HBCI_OutboxJobGetStOs *
    HBCI_OutboxJobGetStOs_new(const HBCI_Customer *c, 
			      HBCI_Account *a);
    /** Upcast */
    extern HBCI_OutboxJob *
    HBCI_OutboxJobGetStOs_OutboxJob(HBCI_OutboxJobGetStOs *j);
    /** Returns the retrieved list of StandingOrders. */
    extern const list_HBCI_StO *
    HBCI_OutboxJobGetStOs_getOrders(const HBCI_OutboxJobGetStOs *j);
    /*@}*/
#ifdef __cplusplus
}

namespace HBCI {
/**
 * This job creates a new standing order.
 * @short Job that creates a new standing order for a Account at the bank
 * @author Fabian Kaiser<openhbci@derzach.de>
 */
class DLLIMPORT OutboxJobNewStandingOrder: public OutboxAccountJob {
private:
    Pointer<Job> _job;
    StandingOrder _newOrder;
public:
    OutboxJobNewStandingOrder(Pointer<Customer> c,
                              Pointer<Account> a,
                              const StandingOrder &newOrder);
    ~OutboxJobNewStandingOrder();

    /* retrieve date that is needed to create a valid order for this account */

    /**
     * Bank-information - needed to create a valid order<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 order<br>
     * Returns the min. number of days to elapse before the order may be
     * executed the first time (next time if you are modifying an existing
     * order)
     */
    static int minDaysToExec(const Bank &forBank);

    /**
     * Bank-information - needed to create a valid order<br>
     * Returns the max. number of days to elapse before the order may be
     * executed the first time (next time if you are modifying an existing
     * order)
     */
    static int maxDaysToExec(const Bank &forBank);

    /**
     * Bank-information - needed to create a valid order<br>
     * Returns a list of all monthly cycles that are allowed.<br>
     * Possible values:<br>
     * <ul>
     * <li> 0 - everything from 1 to 12
     * <li> 1 - every month
     * <li> 2 - every second month
     * <li> ...
     * <li> 12 - once a year
     * </ul>
     */
    static list<int> monthlyCycle(const Bank &forBank);

    /**
     * Bank-information - needed to create a valid order<br>
     * Returns a list of all days that are allowed for monthly execution.<br>
     * Possible values:<br>
     * <ul>
     * <li> 0 - everything from 1 to 30
     * <li> 1 - the 1st of each month
     * <li> 2 - the 2nd of each moth
     * <li> ...
     * <li> 30 - the 30th of each month
     * <li> 98 - (last-1) of each month
     * <li> 99 - last of each month
     * </ul>
     */
    static list<int> execDaysMonth(const Bank &forBank);

    /**
     * Bank-information - needed to create a valid order<br>
     * Returns a list of all weekly cycles that are allowed.<br>
     * Possible values:<br>
     * <ul>
     * <li> 0 - everything from 1 to 52
     * <li> 1 - every week
     * <li> 2 - every 2nd week
     * <li> ...
     * <li> 52 - every 52nd week
     * </ul>
     */
    static list<int> weeklyCycle(const Bank &forBank);

    /**
     * Bank-information - needed to create a valid order<br>
     * Returns a list of all days that are allowed for weekly execution.<br>
     * Possible values:<br>
     * <ul>
     * <li> 0 - everything from 1 to 7
     * <li> 1 - the 1st of each week
     * <li> 2 - the 2nd of each week
     * <li> ...
     * <li> 7 - the 7th of each week
     * </ul>
     */
    static list<int> execDaysWeek(const Bank &forBank);

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

	/**
	 * @short Checks if creating a standing order 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 standing orders
	 *
	 * 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);

    /**
     * Return the order this job is/was supposed to create.
     */
    const StandingOrder &standingOrder() const { return _newOrder;};

    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_NEW_STO; };
    list<int> resultCodes() const;
};

} /* namespace HBCI */
/** @ingroup HBCI_OutboxJobg */
typedef struct HBCI::OutboxJobNewStandingOrder HBCI_OutboxJobNewStO;
extern "C" {
#else /* __cplusplus */
    typedef struct HBCI_OutboxJobNewStO HBCI_OutboxJobNewStO;
#endif /* __cplusplus */
    /** @name HBCI_OutboxJobNewStO 
     * @ingroup HBCI_OutboxJobg */
    /*@{*/
    /** Constructor */
    extern HBCI_OutboxJobNewStO *
    HBCI_OutboxJobNewStO_new(const HBCI_Customer *c, 
			     HBCI_Account *a,
			     const HBCI_StandingOrder *sto);
    /** Upcast */
    extern HBCI_OutboxJob *
    HBCI_OutboxJobNewStO_OutboxJob(HBCI_OutboxJobNewStO *j);
    /*@}*/
#ifdef __cplusplus
}

namespace HBCI {
/**
 * This job deletes an existing standing order.
 * If the bank does not support terminable deletions, you should set
 * StandingOrder::setExecutionDate() to Date() (a zero-date), otherwise 
 * it has to be a future execution date.
 * @short Job that deletes an existing standing order
 * @author Fabian Kaiser<openhbci@derzach.de>
 */
class DLLIMPORT OutboxJobDeleteStandingOrder: public OutboxAccountJob {
private:
    Pointer<Job> _job;
    StandingOrder _order2Delete;
public:
    OutboxJobDeleteStandingOrder(Pointer<Customer> c,
                              Pointer<Account> a,
                              const StandingOrder &order2Delete);
    ~OutboxJobDeleteStandingOrder();

    /**
     * Bank-information - needed to create a valid deletion-job<br>
     * Returns the minimum number of days to elapse before the order
     * can be deleted
     */
    static int minDaysBeforeDelete(const Bank &forBank);

    /**
     * Bank-information - needed to create a valid deletion-job<br>
     * Returns the maximum number of days to elapse before the order
     * can be deleted
     */
    static int maxDaysBeforeDelete(const Bank &forBank);

    /**
     * Bank-information - needed to create a valid deletion-job<br>
     * Returns <code>true</code> if you are allowed to specify a date
     * on which the deletion should be executed
     */
    static bool deletionTerminable(const Bank &forBank);

	/**
	 * @short Checks if deleting a standing order 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);

    /**
     * Return the order this job is/was supposed to delete.
     */
    const StandingOrder &standingOrder() const { return _order2Delete;};

    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_DELETE_STO; };
    list<int> resultCodes() const;
};

} /* namespace HBCI */
/** @ingroup HBCI_OutboxJobg */
typedef struct HBCI::OutboxJobDeleteStandingOrder HBCI_OutboxJobDeleteStO;
extern "C" {
#else /* __cplusplus */
    typedef struct HBCI_OutboxJobDeleteStO HBCI_OutboxJobDeleteStO;
#endif /* __cplusplus */
    /** @name HBCI_OutboxJobDeleteStO 
     * @ingroup HBCI_OutboxJobg */
    /*@{*/
    /** Constructor */
    extern HBCI_OutboxJobDeleteStO *
    HBCI_OutboxJobDeleteStO_new(const HBCI_Customer *c, 
				HBCI_Account *a,
				const HBCI_StandingOrder *sto);
    /** Upcast */
    extern HBCI_OutboxJob *
    HBCI_OutboxJobDeleteStO_OutboxJob(HBCI_OutboxJobDeleteStO *j);
    /*@}*/
#ifdef __cplusplus
}
#endif /* __cplusplus */


#endif



