/***************************************************************************
 * SPDX-FileCopyrightText: 2024 S. MANKOWSKI stephane@mankowski.fr
 * SPDX-FileCopyrightText: 2024 G. DE BURE support@mankowski.fr
 * SPDX-License-Identifier: GPL-3.0-or-later
 ***************************************************************************/
/** @file
 * This file is a test script.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include <qfile.h>

#include "skgbankincludes.h"
#include "skgtestmacro.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)

    QString filename = SKGTest::getTestPath(QLatin1String("OUT")) % "/skgtestoperation.skg";
    QDate now = QDate::currentDate();
    QDate tomorrow = QDate::currentDate().addDays(+1);
    // ============================================================================
    {
        // Test bank document
        SKGDocumentBank document1;
        SKGTESTERROR(QLatin1String("document1.initialize()"), document1.initialize(), true)
        SKGUnitValueObject unit_euro_val1;
        SKGBankObject bank(&document1);
        SKGUnitObject unit_euro(&document1);
        SKGAccountObject account;
        SKGError err;
        {
            // Scope of the transaction
            SKGBEGINTRANSACTION(document1, QLatin1String("BANK_T1"), err)

            // Creation bank
            SKGTESTERROR(QLatin1String("BANK:setName"), bank.setName(QLatin1String("CREDIT COOP")), true)
            SKGTESTERROR(QLatin1String("BANK:save"), bank.save(), true)

            // Creation account
            SKGTESTERROR(QLatin1String("BANK:addAccount"), bank.addAccount(account), true)
            SKGTESTERROR(QLatin1String("ACCOUNT:setName"), account.setName(QLatin1String("Courant steph")), true)

            SKGOperationObject op_1;
            SKGTESTERROR(QLatin1String("ACCOUNT:addOperation"), account.addOperation(op_1), false)
            SKGTESTERROR(QLatin1String("OP:setParentAccount"), op_1.setParentAccount(account), false)

            SKGTESTERROR(QLatin1String("ACCOUNT:setClosed"), account.setClosed(true), true)
            SKGTESTERROR(QLatin1String("ACCOUNT:save"), account.save(), true)

            // Creation transaction ==> failed
            SKGTESTERROR(QLatin1String("ACCOUNT:addOperation"), account.addOperation(op_1), false)

            // Reopen account
            SKGTESTERROR(QLatin1String("ACCOUNT:setClosed"), account.setClosed(false), true)
            SKGTESTERROR(QLatin1String("ACCOUNT:save"), account.save(), true)

            // Creation unit
            SKGTESTERROR(QLatin1String("UNIT:setName"), unit_euro.setName(QLatin1String("euro")), true)
            SKGTESTERROR(QLatin1String("UNIT:save"), unit_euro.save(), true)

            // Creation unitvalue
            SKGTESTERROR(QLatin1String("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
            SKGTESTERROR(QLatin1String("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
            SKGTESTERROR(QLatin1String("UNITVALUE:setDate"), unit_euro_val1.setDate(now), true)
            SKGTESTERROR(QLatin1String("UNITVALUE:save"), unit_euro_val1.save(), true)

            // Creation transaction ==> OK
            SKGTESTERROR(QLatin1String("ACCOUNT:addOperation"), account.addOperation(op_1), true)

            SKGSubOperationObject subop_1;
            SKGTESTERROR(QLatin1String("OPE:addSubOperation"), op_1.addSubOperation(subop_1), false)

            SKGTESTERROR(QLatin1String("OPE:setDate"), op_1.setDate(now), true)
            SKGTESTERROR(QLatin1String("OPE:setUnit"), op_1.setUnit(unit_euro), true)
            SKGTESTERROR(QLatin1String("OPE:save"), op_1.save(), true)

            SKGTESTERROR(QLatin1String("OPE:addSubOperation"), op_1.addSubOperation(subop_1), true)
            SKGTESTERROR(QLatin1String("SUBOPE:save"), subop_1.save(), true)

            SKGTESTERROR(QLatin1String("OPE:setDate"), op_1.setDate(now), true)
            SKGTESTERROR(QLatin1String("OPE:save"), op_1.save(), true)

            SKGTEST(QLatin1String("OPE:getDate"), SKGServices::dateToSqlString(op_1.getDate()), SKGServices::dateToSqlString(now))
            SKGTEST(QLatin1String("SUBOPE:getDate"), SKGServices::dateToSqlString(subop_1.getDate()), SKGServices::dateToSqlString(now))

            SKGTESTERROR(QLatin1String("SUBOPE:setDate"), subop_1.setDate(tomorrow), true)
            SKGTESTERROR(QLatin1String("SUBOPE:save"), subop_1.save(), true)

            SKGTEST(QLatin1String("SUBOPE:getDate"), SKGServices::dateToSqlString(subop_1.getDate()), SKGServices::dateToSqlString(tomorrow))

            SKGTESTERROR(QLatin1String("OPE:setDate"), op_1.setDate(tomorrow), true)
            SKGTESTERROR(QLatin1String("OPE:save"), op_1.save(), true)
            SKGTESTERROR(QLatin1String("SUBOPE:load"), subop_1.load(), true)

            SKGTEST(QLatin1String("OPE:getDate"), SKGServices::dateToSqlString(op_1.getDate()), SKGServices::dateToSqlString(tomorrow))
            SKGTEST(QLatin1String("SUBOPE:getDate"), SKGServices::dateToSqlString(subop_1.getDate()), SKGServices::dateToSqlString(tomorrow.addDays(+1)))
        }
    }

    // ============================================================================
    {
        // Test bank document
        SKGDocumentBank document1;
        SKGTESTERROR(QLatin1String("document1.initialize()"), document1.initialize(), true)
        SKGUnitValueObject unit_euro_val1;
        SKGBankObject bank(&document1);
        SKGUnitObject unit_euro(&document1);
        SKGAccountObject account;
        SKGError err;
        {
            // Scope of the transaction
            SKGBEGINTRANSACTION(document1, QLatin1String("BANK_T1"), err)

            // Creation bank
            SKGTESTERROR(QLatin1String("BANK:setName"), bank.setName(QLatin1String("CREDIT COOP")), true)
            SKGTESTERROR(QLatin1String("BANK:save"), bank.save(), true)

            // Creation account
            SKGTESTERROR(QLatin1String("BANK:addAccount"), bank.addAccount(account), true)
            SKGTESTERROR(QLatin1String("ACCOUNT:setName"), account.setName(QLatin1String("Courant steph")), true)
            SKGTESTERROR(QLatin1String("ACCOUNT:setNumber"), account.setNumber(QLatin1String("12345P")), true)
            SKGTESTERROR(QLatin1String("ACCOUNT:save"), account.save(), true)

            // Creation unit
            SKGTESTERROR(QLatin1String("UNIT:setName"), unit_euro.setName(QLatin1String("euro")), true)
            SKGTESTERROR(QLatin1String("UNIT:save"), unit_euro.save(), true)

            // Creation unitvalue
            SKGTESTERROR(QLatin1String("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
            SKGTESTERROR(QLatin1String("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
            SKGTESTERROR(QLatin1String("UNITVALUE:setDate"), unit_euro_val1.setDate(now), true)
            SKGTESTERROR(QLatin1String("UNITVALUE:save"), unit_euro_val1.save(), true)

            // Creation categories
            SKGCategoryObject cat_1(&document1);
            SKGTESTERROR(QLatin1String("CAT:setName"), cat_1.setName(QLatin1String("transport")), true)
            SKGTESTERROR(QLatin1String("CAT:save"), cat_1.save(), true)

            SKGCategoryObject cat_2;
            SKGTESTERROR(QLatin1String("CAT:addCategory"), cat_1.addCategory(cat_2), true)
            SKGTESTERROR(QLatin1String("CAT:setName"), cat_2.setName(QLatin1String("train")), true)
            SKGTESTERROR(QLatin1String("CAT:save"), cat_2.save(), true)

            // Creation operation
            SKGOperationObject mainOperation;
            double balance = 0;
            for (int i = 1; i <= 10; ++i) {
                SKGOperationObject op_1;
                SKGTESTERROR(QLatin1String("ACCOUNT:addOperation"), account.addOperation(op_1), true)
                SKGTESTERROR(QLatin1String("OPE:setTemplate"), op_1.setTemplate(true), true)
                SKGTESTBOOL("OPE:isTemplate", op_1.isTemplate(), true)
                SKGTESTERROR(QLatin1String("OPE:setTemplate"), op_1.setTemplate(false), true)
                SKGTESTBOOL("OPE:isTemplate", op_1.isTemplate(), false)
                SKGTESTERROR(QLatin1String("OPE:setNumber"), op_1.setNumber(SKGServices::intToString(1000 + i)), true)
                SKGTESTERROR(QLatin1String("OPE:setMode"), op_1.setMode(QLatin1String("cheque")), true)
                SKGTESTERROR(QLatin1String("OPE:setComment"), op_1.setComment(QLatin1String("10 tickets")), true)
                SKGTESTERROR(QLatin1String("OPE:setDate"), op_1.setDate(now), true)
                SKGTESTERROR(QLatin1String("OPE:setUnit"), op_1.setUnit(unit_euro), true)
                SKGUnitObject u;
                SKGTESTERROR(QLatin1String("OPE:setUnit"), op_1.getUnit(u), true)
                SKGTESTERROR(QLatin1String("OPE:bookmark"), op_1.bookmark(i % 2 == 0), true)
                SKGTESTERROR(QLatin1String("OPE:save"), op_1.save(), true)
                if (i == 1) {
                    mainOperation = op_1;
                    SKGTESTERROR(QLatin1String("OPE:setGroupOperation"), mainOperation.setGroupOperation(mainOperation), true)
                    SKGTESTERROR(QLatin1String("OPE:save"), mainOperation.save(), true)
                } else {
                    if (!op_1.isBookmarked()) {
                        SKGTESTERROR(QLatin1String("OPE:setGroupOperation"), op_1.setGroupOperation(mainOperation), true)
                    }
                    SKGTESTERROR(QLatin1String("OPE:save"), op_1.save(), true)
                }

                // Creation suboperation
                for (int j = 1; j <= 5; ++j) {
                    SKGSubOperationObject subop_1;
                    SKGTESTERROR(QLatin1String("OPE:addSubOperation"), op_1.addSubOperation(subop_1), true)
                    SKGTESTERROR(QLatin1String("SUBOPE:setCategory"), subop_1.setCategory(cat_2), true)
                    SKGTESTERROR(QLatin1String("SUBOPE:setComment"), subop_1.setComment(QLatin1String("subop")), true)
                    SKGTEST(QLatin1String("SUBOPE:getComment"), subop_1.getComment(), QLatin1String("subop"))
                    SKGTESTERROR(QLatin1String("OPE:setFormula"), subop_1.setFormula(QLatin1String("total*0.196")), true)
                    SKGTEST(QLatin1String("SUBOPE:getFormula"), subop_1.getFormula(), QLatin1String("total*0.196"))
                    SKGTESTERROR(QLatin1String("SUBOPE:setQuantity"), subop_1.setQuantity(i * j), true)
                    SKGTESTERROR(QLatin1String("SUBOPE:save"), subop_1.save(), true)

                    SKGTESTERROR(QLatin1String("SUBOPE:load"), subop_1.load(), true)
                    SKGOperationObject opget;
                    SKGTESTERROR(QLatin1String("SUBOPE:getParentOperation"), subop_1.getParentOperation(opget), true)
                    SKGTESTBOOL("OPE:comparison", (opget == op_1), true)

                    SKGSubOperationObject subop_12 = subop_1;
                    SKGSubOperationObject subop_13((SKGObjectBase(subop_1)));
                    SKGSubOperationObject subop_14 = SKGSubOperationObject(subop_1);

                    SKGObjectBase subop_base = subop_1;
                    SKGSubOperationObject subop_15;
                    subop_15 = subop_base;
                }

                // Checks
                SKGTESTERROR(QLatin1String("OPE:load"), op_1.load(), true)
                SKGTEST(QLatin1String("OPE:getCurrentAmount"), op_1.getCurrentAmount(), i * 15)
                balance += i * 15;
                SKGTEST(QLatin1String("OPE:getNbSubOperations"), op_1.getNbSubOperations(), 5)
                SKGTEST(QLatin1String("OPE:getBalance"), op_1.getBalance(), balance)
            }

            SKGTESTERROR(QLatin1String("ACCOUNT:load"), account.load(), true)
            SKGTEST(QLatin1String("ACCOUNT:getCurrentAmount"), account.getCurrentAmount(), 55 * 15)
            SKGTEST(QLatin1String("ACCOUNT:getAmount"), account.getAmount(QDate::currentDate()), 55 * 15)

            SKGUnitObject getUnit;
            SKGTESTERROR(QLatin1String("ACCOUNT:getUnit"), account.getUnit(getUnit), true)
            SKGTESTBOOL("ACCOUNT:unit", (getUnit == unit_euro), true)

            SKGTESTERROR(QLatin1String("OPE:load"), mainOperation.load(), true)
            SKGObjectBase::SKGListSKGObjectBase oGroupedOperations;
            SKGTESTERROR(QLatin1String("OPE:getGroupedOperations"), mainOperation.getGroupedOperations(oGroupedOperations), true)
            SKGTEST(QLatin1String("OPE:oGroupedOperations"), oGroupedOperations.size(), 2)  // Normal
            SKGTESTBOOL("OPE:isInGroup", mainOperation.isInGroup(), true)  // Normal
            SKGOperationObject mainOpe;
            SKGTESTERROR(QLatin1String("OPE:getGroupedOperations"), mainOperation.getGroupOperation(mainOpe), true)
            SKGTESTBOOL("OPE:isImported", mainOperation.isImported(), false)
            SKGTESTBOOL("OPE:isTransfer", mainOperation.isTransfer(mainOpe), false)

            SKGTEST(QLatin1String("OPE:getAmount"), mainOpe.getAmount(QDate::currentDate()), 135)

            SKGAccountObject acc;
            SKGTESTERROR(QLatin1String("OPE:getParentAccount"), mainOperation.getParentAccount(acc), true)
            SKGTESTBOOL("OPE:account==acc", (account == acc), true)
            SKGTEST(QLatin1String("OPE:getImportID"), mainOperation.getImportID(), QLatin1String(""))

            SKGObjectBase::SKGListSKGObjectBase oSubOperations;
            SKGTESTERROR(QLatin1String("OPE:getSubOperations"), mainOperation.getSubOperations(oSubOperations), true)
            SKGTEST(QLatin1String("OPE:oSubOperations"), oSubOperations.size(), 5)

            SKGTESTERROR(QLatin1String("BANK:load"), bank.load(), true)
        }  // A commit is done here because the scope is close

        {
            // Scope of the transaction
            SKGBEGINTRANSACTION(document1, QLatin1String("BANK_T2"), err)

            SKGTESTERROR(QLatin1String("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(2.5), true)
            SKGTESTERROR(QLatin1String("UNITVALUE:save"), unit_euro_val1.save(), true)

            SKGTESTERROR(QLatin1String("ACCOUNT:load"), account.load(), true)
            SKGTEST(QLatin1String("ACCOUNT:getCurrentAmount"), account.getCurrentAmount(), 55 * 15 * 2.5)

            SKGTESTERROR(QLatin1String("BANK:load"), bank.load(), true)
            SKGTEST(QLatin1String("BANK:getCurrentAmount"), bank.getCurrentAmount(), 55 * 15 * 2.5)
        }

        QFile(filename).remove();
        SKGTESTERROR(QLatin1String("DOC:saveAs"), document1.saveAs(filename), true)

        {
            // Scope of the transaction
            SKGBEGINTRANSACTION(document1, QLatin1String("BANK_T3"), err)

            // Test foreign key constrain
            SKGTESTERROR(QLatin1String("UNIT:remove"), unit_euro.remove(), false)
        }
    }

    // ============================================================================
    {
        // Test bank document
        SKGDocumentBank document1;
        SKGTESTERROR(QLatin1String("document1.load"), document1.load(filename), true)

        SKGAccountObject account;
        SKGTESTERROR(QLatin1String("SKGAccountObject::getObjectByName"), SKGAccountObject::getObjectByName(&document1, QLatin1String("v_account"), QLatin1String("Courant steph"), account), true)

        SKGTEST(QLatin1String("ACCOUNT:getCurrentAmount"), account.getCurrentAmount(), 55 * 15 * 2.5)

        SKGBankObject bank;
        SKGTESTERROR(QLatin1String("SKGBankObject::getObjectByName"), SKGBankObject::getObjectByName(&document1, QLatin1String("v_bank"), QLatin1String("CREDIT COOP"), bank), true)

        SKGTEST(QLatin1String("BANK:getCurrentAmount"), bank.getCurrentAmount(), 55 * 15 * 2.5)

        SKGTESTERROR(QLatin1String("BANK:undoRedoTransaction"), document1.undoRedoTransaction(), true)

        SKGTESTERROR(QLatin1String("ACCOUNT:load"), account.load(), true)
        SKGTEST(QLatin1String("ACCOUNT:getCurrentAmount"), account.getCurrentAmount(), 55 * 15)
        SKGTESTERROR(QLatin1String("BANK:load"), bank.load(), true)
        SKGTEST(QLatin1String("BANK:getCurrentAmount"), bank.getCurrentAmount(), 55 * 15)

        // delete cascade
        SKGError err;
        {
            // Scope of the transaction
            SKGBEGINTRANSACTION(document1, QLatin1String("BANK_T2"), err)

            SKGTESTERROR(QLatin1String("BANK:delete"), bank.remove(), true)
        }
        QStringList oResult;
        SKGTESTERROR(QLatin1String("BANK:getDistinctValues"), document1.getDistinctValues(QLatin1String("bank"), QLatin1String("id"), oResult), true)
        SKGTEST(QLatin1String("BANK:oResult.size"), oResult.size(), 0)
        SKGTESTERROR(QLatin1String("ACCOUNT:getDistinctValues"), document1.getDistinctValues(QLatin1String("account"), QLatin1String("id"), oResult), true)
        SKGTEST(QLatin1String("ACCOUNT:oResult.size"), oResult.size(), 0)
        SKGTESTERROR(QLatin1String("OPE:getDistinctValues"), document1.getDistinctValues(QLatin1String("operation"), QLatin1String("id"), oResult), true)
        SKGTEST(QLatin1String("OPE:oResult.size"), oResult.size(), 0)
        SKGTESTERROR(QLatin1String("SUBOPE:getDistinctValues"), document1.getDistinctValues(QLatin1String("suboperation"), QLatin1String("id"), oResult), true)
        SKGTEST(QLatin1String("SUBOPE:oResult.size"), oResult.size(), 0)

        SKGTESTERROR(QLatin1String("BANK:undoRedoTransaction"), document1.undoRedoTransaction(), true)
        SKGTESTERROR(QLatin1String("BANK:undoRedoTransaction(SKGDocument::REDO)"), document1.undoRedoTransaction(SKGDocument::REDO), true)


        QFile(filename).remove();
    }

    // ============================================================================
    {
        // Test bank document
        SKGDocumentBank document1;
        SKGTESTERROR(QLatin1String("document1.initialize()"), document1.initialize(), true)
        SKGUnitValueObject unit_euro_val1;
        SKGBankObject bank(&document1);
        SKGUnitObject unit_euro(&document1);
        SKGAccountObject account1;
        SKGAccountObject account2;
        SKGError err;
        {
            // Scope of the transaction
            SKGBEGINTRANSACTION(document1, QLatin1String("BANK_T1"), err)

            // Creation bank
            SKGTESTERROR(QLatin1String("BANK:setName"), bank.setName(QLatin1String("CREDIT COOP")), true)
            SKGTESTERROR(QLatin1String("BANK:save"), bank.save(), true)

            // Creation account
            SKGTESTERROR(QLatin1String("BANK:addAccount"), bank.addAccount(account1), true)
            SKGTESTERROR(QLatin1String("ACCOUNT:setName"), account1.setName(QLatin1String("Courant steph")), true)
            SKGTESTERROR(QLatin1String("ACCOUNT:setType"), account1.setType(SKGAccountObject::CURRENT), true)
            SKGTESTERROR(QLatin1String("ACCOUNT:save"), account1.save(), true)

            SKGTESTERROR(QLatin1String("BANK:addAccount"), bank.addAccount(account2), true)
            SKGTESTERROR(QLatin1String("ACCOUNT:setName"), account2.setName(QLatin1String("Loan")), true)
            SKGTESTERROR(QLatin1String("ACCOUNT:setType"), account2.setType(SKGAccountObject::CURRENT), true)
            SKGTESTERROR(QLatin1String("ACCOUNT:save"), account2.save(), true)

            // Creation unit
            SKGTESTERROR(QLatin1String("UNIT:setName"), unit_euro.setName(QLatin1String("euro")), true)
            SKGTESTERROR(QLatin1String("UNIT:save"), unit_euro.save(), true)

            // Creation unitvalue
            SKGTESTERROR(QLatin1String("UNIT:addUnitValue"), unit_euro.addUnitValue(unit_euro_val1), true)
            SKGTESTERROR(QLatin1String("UNITVALUE:setQuantity"), unit_euro_val1.setQuantity(1), true)
            SKGTESTERROR(QLatin1String("UNITVALUE:setDate"), unit_euro_val1.setDate(now), true)
            SKGTESTERROR(QLatin1String("UNITVALUE:save"), unit_euro_val1.save(), true)

            // Creation transactions
            SKGOperationObject op_1;
            SKGTESTERROR(QLatin1String("ACCOUNT:addOperation"), account1.addOperation(op_1), true)
            SKGTESTERROR(QLatin1String("OPE:setDate"), op_1.setDate(now), true)
            SKGTESTERROR(QLatin1String("OPE:setUnit"), op_1.setUnit(unit_euro), true)
            SKGTESTERROR(QLatin1String("OPE:setNumber"), op_1.setNumber(QLatin1String("5490990004")), true)
            SKGTESTERROR(QLatin1String("OPE:save"), op_1.save(), true)
            SKGTEST(QLatin1String("OPE:getNumber"), op_1.getNumber(), QLatin1String("5490990004"))

            SKGSubOperationObject subop_1;
            SKGTESTERROR(QLatin1String("OPE:addSubOperation"), op_1.addSubOperation(subop_1), true)
            SKGTESTERROR(QLatin1String("SUBOPE:setQuantity"), subop_1.setQuantity(10), true)
            SKGTESTERROR(QLatin1String("SUBOPE:save"), subop_1.save(), true)

            SKGOperationObject op_2;
            SKGTESTERROR(QLatin1String("ACCOUNT:addOperation"), account2.addOperation(op_2), true)
            SKGTESTERROR(QLatin1String("OPE:setDate"), op_2.setDate(now), true)
            SKGTESTERROR(QLatin1String("OPE:setUnit"), op_2.setUnit(unit_euro), true)
            SKGTESTERROR(QLatin1String("OPE:save"), op_2.save(), true)

            SKGSubOperationObject subop_2;
            SKGTESTERROR(QLatin1String("OPE:addSubOperation"), op_2.addSubOperation(subop_2), true)
            SKGTESTERROR(QLatin1String("SUBOPE:setQuantity"), subop_2.setQuantity(-10), true)
            SKGTESTERROR(QLatin1String("SUBOPE:save"), subop_2.save(), true)


            SKGTESTERROR(QLatin1String("OPE:setGroupOperation"), op_1.setGroupOperation(op_2), true)
            SKGTESTERROR(QLatin1String("OPE:setStatus"), op_1.setStatus(SKGOperationObject::MARKED), true)
            SKGTESTERROR(QLatin1String("OPE:save"), op_1.save(), true)

            SKGOperationObject tmp;
            SKGOperationObject tmp2;
            SKGTESTBOOL("OPE:isTransfer", op_1.isTransfer(tmp), true)
            SKGTESTBOOL("OPE:isTransfer", tmp.isTransfer(tmp2), true)
            SKGTESTBOOL("OPE:equal", (tmp == op_2), true)

            SKGTESTERROR(QLatin1String("ACCOUNT:setType"), account2.setType(SKGAccountObject::LOAN), true)
            SKGTESTERROR(QLatin1String("ACCOUNT:save"), account2.save(), true)

            SKGTESTERROR(QLatin1String("OPE:load"), op_1.load(), true)
            SKGTESTBOOL("OPE:isTransfer", op_1.isTransfer(tmp), false)
            SKGTESTBOOL("OPE:isTransfer", tmp.isTransfer(tmp2), false)
            SKGTESTBOOL("OPE:equal", (tmp == op_2), true)

            SKGTESTERROR(QLatin1String("OPE:mergeSuboperations"), op_1.mergeSuboperations(op_2), true)

            SKGTESTERROR(QLatin1String("ACCOUNT:setLinkedAccount"), account1.setLinkedAccount(account2), true)
            SKGAccountObject account2_2;
            SKGTESTERROR(QLatin1String("ACCOUNT:getLinkedAccount"), account1.getLinkedAccount(account2_2), true)
            SKGTESTBOOL("OPE:equal", (account2 == account2_2), true)

            SKGObjectBase::SKGListSKGObjectBase accounts;
            SKGTESTERROR(QLatin1String("ACCOUNT:getLinkedByAccounts"), account2.getLinkedByAccounts(accounts), true)

            SKGTESTERROR(QLatin1String("ACCOUNT:transferDeferredOperations"), account1.transferDeferredOperations(account2), true)

            // Creation template
            SKGOperationObject template1;
            SKGTESTERROR(QLatin1String("ACCOUNT:addOperation"), account1.addOperation(template1), true)
            SKGTESTERROR(QLatin1String("OPE:setDate"), template1.setDate(now.addDays(-5)), true)
            SKGTESTERROR(QLatin1String("OPE:setUnit"), template1.setUnit(unit_euro), true)
            SKGTESTERROR(QLatin1String("OPE:setComment"), template1.setComment(QLatin1String("Comment op")), true)
            SKGTESTERROR(QLatin1String("OPE:setTemplate"), template1.setTemplate(true), true)
            SKGTESTERROR(QLatin1String("OPE:save"), template1.save(), true)

            SKGSubOperationObject template1_1;
            SKGTESTERROR(QLatin1String("OPE:addSubOperation"), template1.addSubOperation(template1_1), true)
            SKGTESTERROR(QLatin1String("SUBOPE:setDate"), template1_1.setDate(now.addDays(-4)), true)
            SKGTESTERROR(QLatin1String("SUBOPE:setQuantity"), template1_1.setQuantity(10), true)
            SKGTESTERROR(QLatin1String("SUBOPE:setComment"), template1.setComment(QLatin1String("Comment sub op 1")), true)
            SKGTESTERROR(QLatin1String("SUBOPE:save"), template1_1.save(), true)

            SKGSubOperationObject template1_2;
            SKGTESTERROR(QLatin1String("OPE:addSubOperation"), template1.addSubOperation(template1_2), true)
            SKGTESTERROR(QLatin1String("SUBOPE:setDate"), template1_2.setDate(now.addDays(-3)), true)
            SKGTESTERROR(QLatin1String("SUBOPE:setQuantity"), template1_2.setQuantity(90), true)
            SKGTESTERROR(QLatin1String("SUBOPE:setComment"), template1_2.setComment(QLatin1String("Comment sub op 2")), true)
            SKGTESTERROR(QLatin1String("SUBOPE:save"), template1_2.save(), true)

            // Creation op
            SKGOperationObject opbasic;
            SKGTESTERROR(QLatin1String("ACCOUNT:addOperation"), account1.addOperation(opbasic), true)
            SKGTESTERROR(QLatin1String("OPE:setDate"), opbasic.setDate(now), true)
            SKGTESTERROR(QLatin1String("OPE:setUnit"), opbasic.setUnit(unit_euro), true)
            SKGTESTERROR(QLatin1String("OPE:setComment"), opbasic.setComment(QLatin1String("Comment op2")), true)
            SKGTESTERROR(QLatin1String("OPE:save"), opbasic.save(), true)

            SKGSubOperationObject opbasic_1;
            SKGTESTERROR(QLatin1String("OPE:addSubOperation"), opbasic.addSubOperation(opbasic_1), true)
            SKGTESTERROR(QLatin1String("SUBOPE:setQuantity"), opbasic_1.setQuantity(200), true)
            SKGTESTERROR(QLatin1String("SUBOPE:save"), opbasic_1.save(), true)

            document1.dump(DUMPOPERATION);

            SKGTESTERROR(QLatin1String("SUBOPE:load"), template1.load(), true)
            SKGTEST(QLatin1String("OPE:getCurrentAmount"), template1.getCurrentAmount(), 100)
            SKGTEST(QLatin1String("OPE:getNbSubOperations"), template1.getNbSubOperations(), 2)

            SKGTESTERROR(QLatin1String("SUBOPE:load"), opbasic.load(), true)
            SKGTEST(QLatin1String("OPE:getCurrentAmount"), opbasic.getCurrentAmount(), 200)
            SKGTEST(QLatin1String("OPE:getNbSubOperations"), opbasic.getNbSubOperations(), 1)

            // Apply the template
            SKGOperationObject op;
            SKGTESTERROR(QLatin1String("OPE:duplicate"), template1.duplicate(op), true)
            SKGTESTERROR(QLatin1String("OPE:load"), op.load(), true)
            SKGTEST(QLatin1String("OPE:d_createdate"), static_cast<unsigned int>(op.getAttribute(QLatin1String("d_createdate")) != QLatin1String("")), static_cast<unsigned int>(true))

            SKGTESTERROR(QLatin1String("OPE:setProperty"), op.setProperty("a", "1"), true)
            SKGTESTERROR(QLatin1String("OPE:setProperty"), opbasic.setProperty("a", "2"), true)

            SKGTESTERROR(QLatin1String("OPE:mergeAttribute"), op.mergeAttribute(opbasic, SKGOperationObject::PROPORTIONAL), true)
            document1.dump(DUMPOPERATION);

            SKGTEST(QLatin1String("OPE:getCurrentAmount"), template1.getCurrentAmount(), 100)
            SKGTEST(QLatin1String("OPE:getNbSubOperations"), template1.getNbSubOperations(), 2)

            SKGTEST(QLatin1String("OPE:getCurrentAmount"), op.getCurrentAmount(), 200)
            SKGTEST(QLatin1String("OPE:getNbSubOperations"), op.getNbSubOperations(), 2)
        }
    }

    // End test
    SKGENDTEST()
}
