/***************************************************************************
*   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 defines classes SKGBudgetRuleObject.
*
* @author Stephane MANKOWSKI / Guillaume DE BURE
*/
#include "skgbudgetruleobject.h"
#include "skgbudgetobject.h"
#include "skgdocumentbank.h"
#include "skgtraces.h"
#include "skgcategoryobject.h"

#include <klocale.h>

SKGBudgetRuleObject::SKGBudgetRuleObject(SKGDocument* iDocument, int iID)
    : SKGObjectBase(iDocument, "v_budgetrule", iID)
{
}

SKGBudgetRuleObject::~SKGBudgetRuleObject()
{
}

SKGBudgetRuleObject::SKGBudgetRuleObject(const SKGBudgetRuleObject& iObject)
    : SKGObjectBase(iObject)
{
}

SKGBudgetRuleObject::SKGBudgetRuleObject(const SKGObjectBase& iObject)
{
    if (iObject.getRealTable() == "budgetrule") {
        copyFrom(iObject);
    } else {
        *this = SKGObjectBase(iObject.getDocument(), "v_budgetrule", iObject.getID());
    }
}

const SKGBudgetRuleObject& SKGBudgetRuleObject::operator= (const SKGObjectBase& iObject)
{
    copyFrom(iObject);
    return *this;
}

SKGError SKGBudgetRuleObject::enableYearCondition(bool iEnable)
{
    return setAttribute("t_year_condition", iEnable ? "Y" : "N");
}

int SKGBudgetRuleObject::isYearConditionEnabled() const
{
    return (getAttribute("t_year_condition") == "Y");
}

SKGError SKGBudgetRuleObject::enableMonthCondition(bool iEnable)
{
    return setAttribute("t_month_condition", iEnable ? "Y" : "N");
}

int SKGBudgetRuleObject::isMonthConditionEnabled() const
{
    return (getAttribute("t_month_condition") == "Y");
}

SKGError SKGBudgetRuleObject::enableCategoryCondition(bool iEnable)
{
    return setAttribute("t_category_condition", iEnable ? "Y" : "N");
}

int SKGBudgetRuleObject::isCategoryConditionEnabled() const
{
    return (getAttribute("t_category_condition") == "Y");
}

SKGError SKGBudgetRuleObject::setBudgetYear(int iYear)
{
    return setAttribute("i_year", SKGServices::intToString(iYear));
}

int SKGBudgetRuleObject::getBudgetYear() const
{
    return SKGServices::stringToInt(getAttribute("i_year"));
}

SKGError SKGBudgetRuleObject::setBudgetMonth(int iMonth)
{
    return setAttribute("i_month", SKGServices::intToString(iMonth));
}

int SKGBudgetRuleObject::getBudgetMonth() const
{
    return SKGServices::stringToInt(getAttribute("i_month"));
}

SKGError SKGBudgetRuleObject::setBudgetCategory(const SKGCategoryObject& iCategory)
{
    return setAttribute("rc_category_id", SKGServices::intToString(iCategory.getID()));;
}

SKGError SKGBudgetRuleObject::getBudgetCategory(SKGCategoryObject& oCategory) const
{
    return getDocument()->getObject("v_category", "id=" % getAttribute("rc_category_id"), oCategory);
}

SKGError SKGBudgetRuleObject::removeBudgetCategory()
{
    return setAttribute("rc_category_id", "0");
}

SKGError SKGBudgetRuleObject::setCondition(SKGBudgetRuleObject::Condition iCondition)
{
    return setAttribute("i_condition", SKGServices::intToString((int) iCondition));
}

SKGBudgetRuleObject::Condition SKGBudgetRuleObject::getCondition() const
{
    return (SKGBudgetRuleObject::Condition) SKGServices::stringToInt(getAttribute("i_condition"));
}

SKGError SKGBudgetRuleObject::setQuantity(double iQuantity, bool iAbsolute)
{
    SKGError err = setAttribute("f_quantity", SKGServices::doubleToString(iQuantity));
    if (!err) err = setAttribute("t_absolute", iAbsolute ? "Y" : "N");
    return err;
}

double SKGBudgetRuleObject::getQuantity() const
{
    return SKGServices::stringToDouble(getAttribute("f_quantity"));
}

bool SKGBudgetRuleObject::isAbolute() const
{
    return getAttribute("t_absolute") != "N";
}

SKGError SKGBudgetRuleObject::enableCategoryChange(bool iEnable)
{
    return setAttribute("t_category_target", iEnable ? "Y" : "N");
}

int SKGBudgetRuleObject::isCategoryChangeEnabled() const
{
    return getAttribute("t_category_target") == "Y";
}

SKGError SKGBudgetRuleObject::setTransfer(SKGBudgetRuleObject::Mode iMode, const SKGCategoryObject& iCategory)
{
    SKGError err = setAttribute("t_rule", iMode == NEXT ? "N" : iMode == CURRENT ? "C" : "Y");
    if (!err) err = setAttribute("rc_category_id_target", SKGServices::intToString(iCategory.getID()));;
    return err;
}

SKGBudgetRuleObject::Mode SKGBudgetRuleObject::getTransferMode() const
{
    return (getAttribute("t_rule") == "N" ? NEXT : (getAttribute("t_rule") == "C" ? CURRENT : YEAR));
}

SKGError SKGBudgetRuleObject::getTransferCategory(SKGCategoryObject& oCategory) const
{
    return getDocument()->getObject("v_category", "id=" % getAttribute("rc_category_id_target"), oCategory);
}

SKGError SKGBudgetRuleObject::processAllRules(SKGDocumentBank* iDocument)
{
    SKGError err;
    SKGTRACEINRC(10, "SKGBudgetRuleObject::processAllRules", err);
    if (iDocument) {
        //Initialize
        err = iDocument->executeSqliteOrder("UPDATE budget SET f_budgeted_modified=f_budgeted  WHERE f_budgeted_modified!=f_budgeted");
        if (!err) err = iDocument->executeSqliteOrder("UPDATE budget SET f_transferred=0  WHERE f_transferred!=0");

        //Get budgets ordered by date
        SKGObjectBase::SKGListSKGObjectBase budgets;
        if (!err) err = iDocument->getObjects("v_budget", "length(t_RULES)>0 "
                                                  //"t_PERIOD<STRFTIME('%Y-%m', date('now')) AND t_PERIOD!=STRFTIME('%Y', date('now')) "
                                                  "ORDER BY t_PERIOD, id", budgets);
        int nb = budgets.count();
        if (!err && nb && iDocument) {
            err = iDocument->beginTransaction("#INTERNAL#" % i18nc("Progression step", "Apply rules"), nb);
            for (int i = 0; !err && i < nb; ++i) {
                SKGBudgetObject bud = budgets.at(i);
                err = bud.load(); //Reload to be sure that delta has been updated
                if (!err) err = bud.process();

                if (!err) err = iDocument->stepForward(i + 1);
            }

            if (!err) err = iDocument->endTransaction(true);
            else  iDocument->endTransaction(false);
        }
    }

    return err;
}

#include "skgbudgetruleobject.moc"
