#include "budgetdao.h"
#include "../mapplication.h"

bool BudgetDAO::create(const Data& data)
{
    dApp->Enterprise().open();
    QSqlQuery qry(dApp->Enterprise());
    qry.prepare("INSERT INTO SALEPROPOSAL (TYPE, CODE, TITLE, VERSION, "
                "CUSTOMER_CODE, CUSTOMER_NAME, PROJECT_CODE, PROJECT_TITLE, "
                "COST, PRICE, TAX, STATE, STATE_NUMBER, DESCRIPTION, "
                "VALIDUNTILL, DELIVERY_DATE, CREATEDBY) "
                "VALUES (:TYPE, :CODE, :TITLE, :VERSION, "
                ":CUSTOMER_CODE, :CUSTOMER_NAME, :PROJECT_CODE, :PROJECT_TITLE, "
                ":COST, :PRICE, :TAX, :STATE, :STATE_NUMBER, :DESCRIPTION, "
                ":VALIDUNTILL, :DELIVERY_DATE, :CREATEDBY)");
    qry.bindValue(":TYPE", data.type);
    qry.bindValue(":CODE", data.code);
    qry.bindValue(":TITLE", data.title);
    qry.bindValue(":VERSION", data.version);
    qry.bindValue(":CUSTOMER_CODE", data.customerCode);
    qry.bindValue(":CUSTOMER_NAME", data.customerName);
    qry.bindValue(":PROJECT_CODE", data.projectCode);
    qry.bindValue(":PROJECT_TITLE", data.projectTitle);
    qry.bindValue(":COST", data.cost);
    qry.bindValue(":PRICE", data.price);
    qry.bindValue(":TAX", data.tax);
    qry.bindValue(":STATE", data.state);
    qry.bindValue(":STATE_NUMBER", data.stateNumber);
    qry.bindValue(":DESCRIPTION", data.description);
    qry.bindValue(":VALIDUNTILL", data.validUntil);
    qry.bindValue(":DELIVERY_DATE", data.deliveryDate);
    qry.bindValue(":CREATEDBY", data.createdBy);

    bool ok = qry.exec();
    if (!ok) qDebug() << "BudgetDAO::create error:" << qry.lastError().text();
    dApp->Enterprise().close();
    return ok;
}

bool BudgetDAO::read(int id, Data& data)
{
    dApp->Enterprise().open();
    QSqlQuery qry(dApp->Enterprise());
    qry.prepare("SELECT * FROM SALEPROPOSAL WHERE ID = :ID");
    qry.bindValue(":ID", id);

    bool ok = qry.exec();
    if (ok && qry.next()) {
        data.id = qry.value("ID").toInt();
        data.type = qry.value("TYPE").toString();
        data.code = qry.value("CODE").toString();
        data.title = qry.value("TITLE").toString();
        data.version = qry.value("VERSION").toInt();
        data.customerCode = qry.value("CUSTOMER_CODE").toString();
        data.customerName = qry.value("CUSTOMER_NAME").toString();
        data.projectCode = qry.value("PROJECT_CODE").toString();
        data.projectTitle = qry.value("PROJECT_TITLE").toString();
        data.cost = qry.value("COST").toDouble();
        data.price = qry.value("PRICE").toDouble();
        data.tax = qry.value("TAX").toInt();
        data.state = qry.value("STATE").toString();
        data.stateNumber = qry.value("STATE_NUMBER").toInt();
        data.description = qry.value("DESCRIPTION").toString();
        data.createdAt = qry.value("CREATEDAT").toDate();
        data.validUntil = qry.value("VALIDUNTILL").toDate();
        data.deliveryDate = qry.value("DELIVERY_DATE").toDate();
        data.createdBy = qry.value("CREATEDBY").toString();
    } else {
        ok = false;
        qDebug() << "BudgetDAO::read error:" << qry.lastError().text();
    }
    dApp->Enterprise().close();
    return ok;
}

bool BudgetDAO::readByCode(const QString& code, Data& data)
{
    dApp->Enterprise().open();
    QSqlQuery qry(dApp->Enterprise());
    qry.prepare("SELECT * FROM SALEPROPOSAL WHERE CODE = :CODE");
    qry.bindValue(":CODE", code);
    if (qry.exec() && qry.next()) {
        data.id = qry.value("ID").toInt();
        data.code = code;
        dApp->Enterprise().close();
        return read(data.id, data);
    }
    dApp->Enterprise().close();
    return false;
}

bool BudgetDAO::update(const Data& data)
{
    dApp->Enterprise().open();
    QSqlQuery qry(dApp->Enterprise());
    qry.prepare("UPDATE SALEPROPOSAL SET "
                "TYPE = :TYPE, CODE = :CODE, TITLE = :TITLE, VERSION = :VERSION, "
                "CUSTOMER_CODE = :CUSTOMER_CODE, CUSTOMER_NAME = :CUSTOMER_NAME, "
                "PROJECT_CODE = :PROJECT_CODE, PROJECT_TITLE = :PROJECT_TITLE, "
                "COST = :COST, PRICE = :PRICE, TAX = :TAX, "
                "STATE = :STATE, STATE_NUMBER = :STATE_NUMBER, DESCRIPTION = :DESCRIPTION, "
                "VALIDUNTILL = :VALIDUNTILL, DELIVERY_DATE = :DELIVERY_DATE "
                "WHERE ID = :ID");
    qry.bindValue(":ID", data.id);
    qry.bindValue(":TYPE", data.type);
    qry.bindValue(":CODE", data.code);
    qry.bindValue(":TITLE", data.title);
    qry.bindValue(":VERSION", data.version);
    qry.bindValue(":CUSTOMER_CODE", data.customerCode);
    qry.bindValue(":CUSTOMER_NAME", data.customerName);
    qry.bindValue(":PROJECT_CODE", data.projectCode);
    qry.bindValue(":PROJECT_TITLE", data.projectTitle);
    qry.bindValue(":COST", data.cost);
    qry.bindValue(":PRICE", data.price);
    qry.bindValue(":TAX", data.tax);
    qry.bindValue(":STATE", data.state);
    qry.bindValue(":STATE_NUMBER", data.stateNumber);
    qry.bindValue(":DESCRIPTION", data.description);
    qry.bindValue(":VALIDUNTILL", data.validUntil);
    qry.bindValue(":DELIVERY_DATE", data.deliveryDate);

    bool ok = qry.exec();
    if (!ok) qDebug() << "BudgetDAO::update error:" << qry.lastError().text();
    dApp->Enterprise().close();
    return ok;
}

bool BudgetDAO::remove(int id)
{
    dApp->Enterprise().open();
    QSqlQuery qry(dApp->Enterprise());
    qry.prepare("DELETE FROM SALEPROPOSAL WHERE ID = :ID");
    qry.bindValue(":ID", id);

    bool ok = qry.exec();
    if (!ok) qDebug() << "BudgetDAO::remove error:" << qry.lastError().text();
    dApp->Enterprise().close();
    return ok;
}

bool BudgetDAO::exists(const QString& code)
{
    dApp->Enterprise().open();
    QSqlQuery qry(dApp->Enterprise());
    qry.prepare("SELECT COUNT(*) FROM SALEPROPOSAL WHERE CODE = :CODE");
    qry.bindValue(":CODE", code);
    bool exists = false;
    if (qry.exec() && qry.next())
        exists = qry.value(0).toInt() > 0;
    dApp->Enterprise().close();
    return exists;
}

QVector<int> BudgetDAO::getAllIds()
{
    QVector<int> ids;
    dApp->Enterprise().open();
    QSqlQuery qry(dApp->Enterprise());
    qry.prepare("SELECT ID FROM SALEPROPOSAL ORDER BY CREATEDAT DESC");
    if (qry.exec()) {
        while (qry.next())
            ids.append(qry.value(0).toInt());
    }
    dApp->Enterprise().close();
    return ids;
}

QVector<BudgetDAO::Data> BudgetDAO::getAll()
{
    QVector<Data> list;
    dApp->Enterprise().open();
    QSqlQuery qry(dApp->Enterprise());
    qry.prepare("SELECT ID, CODE, TITLE, CUSTOMER_NAME, PRICE, STATE FROM SALEPROPOSAL ORDER BY CREATEDAT DESC");
    if (qry.exec()) {
        while (qry.next()) {
            Data d;
            d.id = qry.value(0).toInt();
            d.code = qry.value(1).toString();
            d.title = qry.value(2).toString();
            d.customerName = qry.value(3).toString();
            d.price = qry.value(4).toDouble();
            d.state = qry.value(5).toString();
            list.append(d);
        }
    }
    dApp->Enterprise().close();
    return list;
}

// Lines
bool BudgetDAO::createLine(const LineData& data)
{
    dApp->Enterprise().open();
    QSqlQuery qry(dApp->Enterprise());
    qry.prepare("INSERT INTO SALEPROPOSALDATA "
                "(SALEDOCUMENT_CODE, VERSION, NODEINDEX, ELEMENT_CODE, ELEMENT_TYPE, "
                "ELEMENT_INDEX, ELEMENT_TITLE, ELEMENT_DESCRIPTION, "
                "ELEMENT_UNIT_AMOUNT, ELEMENT_TOTAL_AMOUNT, ELEMENT_UNIT, ELEMENT_PRICE, "
                "BENEFIT, DISCOUNT, TAX, PRINT, CREATEDBY) "
                "VALUES (:CODE, :VERSION, :NODEINDEX, :ELEMENT_CODE, :ELEMENT_TYPE, "
                ":ELEMENT_INDEX, :ELEMENT_TITLE, :ELEMENT_DESCRIPTION, "
                ":ELEMENT_UNIT_AMOUNT, :ELEMENT_TOTAL_AMOUNT, :ELEMENT_UNIT, :ELEMENT_PRICE, "
                ":BENEFIT, :DISCOUNT, :TAX, :PRINT, :CREATEDBY)");
    qry.bindValue(":CODE", data.saleDocumentCode);
    qry.bindValue(":VERSION", data.version);
    qry.bindValue(":NODEINDEX", data.nodeIndex);
    qry.bindValue(":ELEMENT_CODE", data.elementCode);
    qry.bindValue(":ELEMENT_TYPE", data.elementType);
    qry.bindValue(":ELEMENT_INDEX", data.elementIndex);
    qry.bindValue(":ELEMENT_TITLE", data.elementTitle);
    qry.bindValue(":ELEMENT_DESCRIPTION", data.elementDescription);
    qry.bindValue(":ELEMENT_UNIT_AMOUNT", data.elementUnitAmount);
    qry.bindValue(":ELEMENT_TOTAL_AMOUNT", data.elementTotalAmount);
    qry.bindValue(":ELEMENT_UNIT", data.elementUnit);
    qry.bindValue(":ELEMENT_PRICE", data.elementPrice);
    qry.bindValue(":BENEFIT", data.benefit);
    qry.bindValue(":DISCOUNT", data.discount);
    qry.bindValue(":TAX", data.tax);
    qry.bindValue(":PRINT", data.print);
    qry.bindValue(":CREATEDBY", data.createdBy);

    bool ok = qry.exec();
    if (!ok) qDebug() << "BudgetDAO::createLine error:" << qry.lastError().text();
    dApp->Enterprise().close();
    return ok;
}

QVector<BudgetDAO::LineData> BudgetDAO::getLines(const QString& documentCode)
{
    QVector<LineData> lines;
    dApp->Enterprise().open();
    QSqlQuery qry(dApp->Enterprise());
    qry.prepare("SELECT * FROM SALEPROPOSALDATA WHERE SALEDOCUMENT_CODE = :CODE ORDER BY ID");
    qry.bindValue(":CODE", documentCode);

    if (qry.exec()) {
        while (qry.next()) {
            LineData d;
            d.id = qry.value("ID").toInt();
            d.saleDocumentCode = qry.value("SALEDOCUMENT_CODE").toString();
            d.version = qry.value("VERSION").toInt();
            d.nodeIndex = qry.value("NODEINDEX").toString();
            d.elementCode = qry.value("ELEMENT_CODE").toString();
            d.elementType = qry.value("ELEMENT_TYPE").toString();
            d.elementIndex = qry.value("ELEMENT_INDEX").toInt();
            d.elementTitle = qry.value("ELEMENT_TITLE").toString();
            d.elementDescription = qry.value("ELEMENT_DESCRIPTION").toString();
            d.elementUnitAmount = qry.value("ELEMENT_UNIT_AMOUNT").toDouble();
            d.elementTotalAmount = qry.value("ELEMENT_TOTAL_AMOUNT").toDouble();
            d.elementUnit = qry.value("ELEMENT_UNIT").toString();
            d.elementPrice = qry.value("ELEMENT_PRICE").toDouble();
            d.benefit = qry.value("BENEFIT").toDouble();
            d.discount = qry.value("DISCOUNT").toDouble();
            d.tax = qry.value("TAX").toDouble();
            d.print = qry.value("PRINT").toBool();
            d.createdAt = qry.value("CREATEDAT").toDate();
            d.createdBy = qry.value("CREATEDBY").toString();
            lines.append(d);
        }
    }
    dApp->Enterprise().close();
    return lines;
}

bool BudgetDAO::removeLines(const QString& documentCode)
{
    dApp->Enterprise().open();
    QSqlQuery qry(dApp->Enterprise());
    qry.prepare("DELETE FROM SALEPROPOSALDATA WHERE SALEDOCUMENT_CODE = :CODE");
    qry.bindValue(":CODE", documentCode);
    bool ok = qry.exec();
    if (!ok) qDebug() << "BudgetDAO::removeLines error:" << qry.lastError().text();
    dApp->Enterprise().close();
    return ok;
}