/***************************************************************************
 *   Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>  *
 ***************************************************************************/
/** @file
 * This file is a test script.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include "skgtestmacro.h"
#include "skgbankincludes.h"

/**
 * The main function of the unit test
 * @param argc the number of arguments
 * @param argv the list of arguments
 */
int main(int argc, char** argv)
{
    Q_UNUSED(argc);
    Q_UNUSED(argv);

    // Init test
    SKGINITTEST(true);
    // ============================================================================
    // Init
    {
        // Test bank1 document
        SKGDocumentBank document1;
        SKGTESTERROR("document1.initialize()", document1.initialize(), true);
        SKGError err;
        {
            // Scope of the transaction
            SKGBEGINTRANSACTION(document1, "BANK_T1", err);

            // Creation unit
            SKGUnitObject unit_euro(&document1);
            SKGTESTERROR("BANK:setName", unit_euro.setName("euro"), true);
            SKGTESTERROR("BANK:setSymbol", unit_euro.setSymbol("euro"), true);
            SKGTESTERROR("BANK:save", unit_euro.save(), true);

            // Creation unitvalue
            SKGUnitValueObject unit_euro_val1;
            SKGTESTERROR("BANK:addUnitValue", unit_euro.addUnitValue(unit_euro_val1), true);
            SKGTESTERROR("BANK:setQuantity", unit_euro_val1.setQuantity(1), true);
            SKGTESTERROR("BANK:setDate", unit_euro_val1.setDate(QDate::currentDate()), true);
            SKGTESTERROR("BANK:save", unit_euro_val1.save(), true);

            // Creation bank1
            SKGBankObject bank1(&document1);
            SKGAccountObject account1;
            SKGTESTERROR("BANK:addAccount", bank1.addAccount(account1), false);

            SKGTESTERROR("BANK:setName", bank1.setName("CREDIT COOP"), true);
            SKGTESTERROR("BANK:setIcon", bank1.setIcon("credit cooperatif"), true);
            SKGTESTERROR("BANK:setNumber", bank1.setNumber("111111"), true);
            SKGTESTERROR("BANK:save", bank1.save(), true);
            SKGTEST("BANK:getIcon", bank1.getIcon(), "credit cooperatif");
            SKGTEST("BANK:getNumber", bank1.getNumber(), "111111");

            SKGBankObject bank11(bank1);    // For coverage
            SKGTESTBOOL("BANK:comparison", (bank11 == bank1), true);
            SKGBankObject bank12 = bank1;  // For coverage
            SKGTESTBOOL("BANK:comparison", (bank12 == bank1), true);
            SKGBankObject bank13(SKGNamedObject(bank1));  // For coverage
            SKGTESTBOOL("BANK:comparison", (bank12 == SKGNamedObject(bank1)), true);
            SKGNamedObject bank1n(bank1);
            SKGBankObject bank14(bank1n);  // For coverage

            SKGBankObject bank15(SKGObjectBase(bank1.getDocument(), "xxx", bank1.getID()));    // For coverage
            SKGBankObject bank16(SKGNamedObject(bank1.getDocument(), "xxx", bank1.getID()));    // For coverage

            // Creation account1
            SKGTESTERROR("BANK:addAccount", bank1.addAccount(account1), true);

            SKGOperationObject op;
            SKGTESTERROR("ACCOUNT:addOperation", account1.addOperation(op), false);

            SKGInterestObject it;
            SKGTESTERROR("ACCOUNT:addOperation", account1.addInterest(it), false);

            SKGTESTERROR("ACCOUNT:setName", account1.setName("Courant steph"), true);
            SKGTESTERROR("ACCOUNT:setNumber", account1.setNumber("12345P"), true);
            SKGTESTERROR("ACCOUNT:setAgencyNumber", account1.setAgencyNumber("99999"), true);
            SKGTESTERROR("ACCOUNT:setAgencyAddress", account1.setAgencyAddress("10 rue Albert CAMUS\n31000 TOULOUSE"), true);
            SKGTESTERROR("ACCOUNT:setType", account1.setType(SKGAccountObject::CURRENT), true);
            SKGTESTERROR("ACCOUNT:setComment", account1.setComment("bla bla"), true);
            SKGTESTERROR("ACCOUNT:setMaxLimitAmount", account1.setMaxLimitAmount(15000.0), true);
            SKGTESTERROR("ACCOUNT:setMinLimitAmount", account1.setMinLimitAmount(-500.0), true);
            SKGTESTERROR("ACCOUNT:maxLimitAmountEnabled", account1.maxLimitAmountEnabled(true), true);
            SKGTESTERROR("ACCOUNT:minLimitAmountEnabled", account1.minLimitAmountEnabled(false), true);
            SKGTESTERROR("ACCOUNT:save", account1.save(), true);
            SKGTEST("ACCOUNT:getNumber", account1.getNumber(), "12345P");
            SKGTEST("ACCOUNT:getAgencyNumber", account1.getAgencyNumber(), "99999");
            SKGTEST("ACCOUNT:getAgencyAddress", account1.getAgencyAddress(), "10 rue Albert CAMUS\n31000 TOULOUSE");
            SKGTEST("ACCOUNT:getMaxLimitAmount", account1.getMaxLimitAmount(), 15000.0);
            SKGTEST("ACCOUNT:getMinLimitAmount", account1.getMinLimitAmount(), -500.0);

            SKGTESTERROR("ACCOUNT:setMaxLimitAmount", account1.setMaxLimitAmount(-1000.0), true);
            SKGTEST("ACCOUNT:getMaxLimitAmount", account1.getMaxLimitAmount(), -1000.0);
            SKGTEST("ACCOUNT:getMinLimitAmount", account1.getMinLimitAmount(), -1000.0);

            SKGTESTBOOL("ACCOUNT:isMaxLimitAmountEnabled", account1.isMaxLimitAmountEnabled(), true);
            SKGTESTBOOL("ACCOUNT:isMinLimitAmountEnabled", account1.isMinLimitAmountEnabled(), false);

            SKGTEST("ACCOUNT:getType", static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::CURRENT));

            SKGTESTERROR("ACCOUNT:setType", account1.setType(SKGAccountObject::CREDITCARD), true);
            SKGTEST("ACCOUNT:getType", static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::CREDITCARD));

            SKGTESTERROR("ACCOUNT:setType", account1.setType(SKGAccountObject::ASSETS), true);
            SKGTEST("ACCOUNT:getType", static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::ASSETS));

            SKGTESTERROR("ACCOUNT:setType", account1.setType(SKGAccountObject::INVESTMENT), true);
            SKGTEST("ACCOUNT:getType", static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::INVESTMENT));

            SKGTESTERROR("ACCOUNT:setType", account1.setType(SKGAccountObject::WALLET), true);
            SKGTEST("ACCOUNT:getType", static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::WALLET));

            SKGTESTERROR("ACCOUNT:setType", account1.setType(SKGAccountObject::LOAN), true);
            SKGTEST("ACCOUNT:getType", static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::LOAN));

            SKGTESTERROR("ACCOUNT:setType", account1.setType(SKGAccountObject::SAVING), true);
            SKGTEST("ACCOUNT:getType", static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::SAVING));

            SKGTESTERROR("ACCOUNT:setType", account1.setType(SKGAccountObject::OTHER), true);
            SKGTEST("ACCOUNT:getType", static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::OTHER));

            SKGTESTERROR("ACCOUNT:setType", account1.setType(SKGAccountObject::PENSION), true);
            SKGTEST("ACCOUNT:getType", static_cast<unsigned int>(account1.getType()), static_cast<unsigned int>(SKGAccountObject::PENSION));

            SKGTEST("ACCOUNT:getComment", account1.getComment(), "bla bla");

            QDate n = QDate::currentDate();
            SKGTESTERROR("ACCOUNT:setReconciliationDate", account1.setReconciliationDate(n), true);
            SKGTEST("ACCOUNT:getReconciliationDate", SKGServices::dateToSqlString(QDateTime(account1.getReconciliationDate())), SKGServices::dateToSqlString(QDateTime(n)));

            SKGTESTERROR("ACCOUNT:setInitialBalance", account1.setInitialBalance(125, unit_euro), true);
            double init = 0;
            SKGUnitObject unit;
            SKGTESTERROR("ACCOUNT:getInitialBalance", account1.getInitialBalance(init, unit), true);
            SKGTESTBOOL("ACCOUNT:getInitialBalance", (unit == unit_euro), true);
            SKGTEST("ACCOUNT:getInitialBalance", init, 125);

            SKGAccountObject account11(account1);    // For coverage
            SKGTESTBOOL("BANK:comparison", (account11 == account1), true);
            SKGAccountObject account12(static_cast<SKGNamedObject>(account1));     // For coverage
            SKGTESTBOOL("BANK:comparison", (account12 == account1), true);
            SKGAccountObject account13(static_cast<SKGObjectBase>(account1));     // For coverage
            SKGTESTBOOL("BANK:comparison", (account13 == account1), true);

            SKGAccountObject account14(SKGObjectBase(account1.getDocument(), "xxx", account1.getID()));    // For coverage
            SKGAccountObject account15(SKGNamedObject(account1.getDocument(), "xxx", account1.getID()));    // For coverage

            // Creation bank2
            SKGBankObject bank2(&document1);
            SKGTESTERROR("BANK:setName", bank2.setName("NEF"), true);
            SKGTESTERROR("BANK:save", bank2.save(), true);

            // Creation account2
            SKGAccountObject account2;
            SKGTESTERROR("BANK:addAccount", bank2.addAccount(account2), true);
            SKGTESTERROR("ACCOUNT:setName", account2.setName("Courant steph"), true);
            SKGTESTERROR("ACCOUNT:setNumber", account2.setNumber("98765A"), true);
            SKGTESTERROR("ACCOUNT:save", account2.save(false), false);

            SKGAccountObject account3;
            SKGTESTERROR("BANK:addAccount", bank2.addAccount(account3), true);
            SKGTESTERROR("ACCOUNT:setName", account3.setName("Courant vero"), true);
            SKGTESTERROR("ACCOUNT:setNumber", account3.setNumber("98765A"), true);
            SKGTESTERROR("ACCOUNT:save", account3.save(), true);

            QStringList oResult;
            SKGTESTERROR("BANK:getDistinctValues", document1.getDistinctValues("bank", "t_name", oResult), true);
            SKGTEST("BANK:oResult.size", oResult.size(), 2);

            SKGTESTERROR("BANK:getDistinctValues", document1.getDistinctValues("account", "t_name", oResult), true);
            SKGTEST("BANK:oResult.size", oResult.size(), 2);

            SKGObjectBase::SKGListSKGObjectBase oAccountList;
            SKGTESTERROR("BANK:getAccounts", bank1.getAccounts(oAccountList), true);
            SKGTEST("ACCOUNT:count", oAccountList.count(), 1);

            SKGTESTERROR("BANK:getAccounts", bank2.getAccounts(oAccountList), true);
            SKGTEST("ACCOUNT:count", oAccountList.count(), 1);

            // Modification account1
            SKGBankObject tmpBank;
            SKGTESTERROR("ACCOUNT:getBank", account3.getBank(tmpBank), true);
            SKGTESTBOOL("BANK:tmpBank==bank2", (tmpBank == bank2), true);
            SKGTESTERROR("ACCOUNT:setBank", account3.setBank(bank1), true);
            SKGTESTERROR("ACCOUNT:getBank", account3.getBank(tmpBank), true);
            SKGTESTBOOL("BANK:tmpBank==bank2", (tmpBank == bank1), true);
            SKGTESTERROR("ACCOUNT:save", account3.save(), true);

            SKGTESTERROR("BANK:getAccounts", bank1.getAccounts(oAccountList), true);
            SKGTEST("ACCOUNT:count", oAccountList.count(), 2);

            SKGTESTERROR("BANK:getAccounts", bank2.getAccounts(oAccountList), true);
            SKGTEST("ACCOUNT:count", oAccountList.count(), 0);

            SKGTESTBOOL("ACCOUNT:isBookmarked", account3.isBookmarked(), false);
            SKGTESTERROR("ACCOUNT:bookmark", account3.bookmark(true), true);
            SKGTESTBOOL("ACCOUNT:isBookmarked", account3.isBookmarked(), true);

            SKGTESTBOOL("ACCOUNT:isClosed", account3.isClosed(), false);
            SKGTESTERROR("ACCOUNT:setClosed", account3.setClosed(true), true);
            SKGTESTBOOL("ACCOUNT:isClosed", account3.isClosed(), true);

            SKGTESTERROR("ACCOUNT:save", account3.save(), true);

            // Merge
            SKGTESTERROR("ACCOUNT:merge", account2.merge(account3), true);

            // interest
            SKGObjectBase::SKGListSKGObjectBase oInterestList;
            SKGTESTERROR("ACCOUNT:getInterests", account2.getInterests(oInterestList), true);

            SKGInterestObject oInterest;
            SKGTESTERROR("ACCOUNT:getInterests", account2.getInterest(QDate::currentDate(), oInterest), false);

            SKGObjectBase account4(&document1, "account", account1.getID());
            SKGTESTERROR("ACCOUNT:load", account4.load(), true);
            SKGTESTERROR("ACCOUNT:setAttribute", account4.setAttribute("t_BANK", "bankname"), true);
            SKGTESTERROR("ACCOUNT:save", account4.save(), true);
            SKGTESTERROR("BANK:load", bank1.load(), true);
            SKGTEST("BANK:getName", bank1.getName(), "bankname");

            SKGTESTERROR("DOC:dump", document1.dump(DUMPACCOUNT), true);
        }
    }

    // End test
    SKGENDTEST();
}
