/*
 * This file is part of the xTuple ERP: PostBooks Edition, a free and
 * open source Enterprise Resource Planning software suite,
 * Copyright (c) 1999-2009 by OpenMFG LLC, d/b/a xTuple.
 * It is licensed to you under the Common Public Attribution License
 * version 1.0, the full text of which (including xTuple-specific Exhibits)
 * is available at www.xtuple.com/CPAL.  By using this software, you agree
 * to be bound by its terms.
 */

#include "transferOrders.h"

#include <QMenu>
#include <QMessageBox>
#include <QVariant>

#include <metasql.h>
#include <openreports.h>

#include "copyTransferOrder.h"
#include "issueToShipping.h"
#include "storedProcErrorLookup.h"
#include "transferOrder.h"
#include "printPackingList.h"

transferOrders::transferOrders(QWidget* parent, const char* name, Qt::WFlags fl)
    : XWidget(parent, name, fl)
{
  setupUi(this);

  connect(_copy,	  SIGNAL(clicked()), this, SLOT(sCopy()));
  connect(_delete,	  SIGNAL(clicked()), this, SLOT(sDelete()));
  connect(_destWarehouse, SIGNAL(updated()), this, SLOT(sFillList()));
  connect(_edit,	  SIGNAL(clicked()), this, SLOT(sEdit()));
  connect(_new,		  SIGNAL(clicked()), this, SLOT(sNew()));
  connect(_print,	  SIGNAL(clicked()), this, SLOT(sPrint()));
  connect(_issue,	  SIGNAL(clicked()), this, SLOT(sIssue()));
  connect(_srcWarehouse,  SIGNAL(updated()), this, SLOT(sFillList()));
  connect(_to, SIGNAL(populateMenu(QMenu*,QTreeWidgetItem*, int)), this, SLOT(sPopulateMenu(QMenu*)));
  connect(_view,	  SIGNAL(clicked()), this, SLOT(sView()));
  connect(omfgThis, SIGNAL(transferOrdersUpdated(int)), this, SLOT(sFillList()));

  _to->addColumn(tr("Order #"),                -1,  Qt::AlignLeft,   true,  "tohead_number"   );
  _to->addColumn(tr("Source Site"),  _whsColumn*2,  Qt::AlignLeft,   true,  "srcWhs"   );
  _to->addColumn(tr("Dest. Site"),	 _whsColumn*2,  Qt::AlignLeft,   true,  "destWhs"   );
  _to->addColumn(tr("Ordered"),       _dateColumn,  Qt::AlignCenter, true,  "tohead_orderdate" );
  _to->addColumn(tr("Scheduled"),     _dateColumn,  Qt::AlignCenter, true,  "scheduled" );
  
  if (_privileges->check("MaintainTransferOrders"))
  {
    connect(_to,       SIGNAL(valid(bool)), _edit,    SLOT(setEnabled(bool)));
    connect(_to,       SIGNAL(valid(bool)), _copy,    SLOT(setEnabled(bool)));
    connect(_to,       SIGNAL(valid(bool)), _delete,  SLOT(setEnabled(bool)));
    connect(_to,       SIGNAL(valid(bool)), _issue,   SLOT(setEnabled(bool)));
    connect(_to, SIGNAL(itemSelected(int)), _edit,    SLOT(animateClick()));
  }
  else
  {
    _new->setEnabled(FALSE);
    connect(_to, SIGNAL(itemSelected(int)), _view, SLOT(animateClick()));
  }

  _destWarehouse->setAll();

  sFillList();
}

transferOrders::~transferOrders()
{
    // no need to delete child widgets, Qt does it all for us
}

void transferOrders::languageChange()
{
    retranslateUi(this);
}

void transferOrders::setParams(ParameterList& params)
{
  if (_srcWarehouse->isSelected())
    params.append("src_warehous_id", _srcWarehouse->id());
  if (_destWarehouse->isSelected())
    params.append("dest_warehous_id", _destWarehouse->id());
  params.append("tohead_status", "O");
}

void transferOrders::sPrint()
{
  ParameterList params;
  setParams(params);

  orReport report("ListTransferOrders", params);
  if (report.isValid())
    report.print();
  else
    report.reportError(this);
}

void transferOrders::sNew()
{
  transferOrder::newTransferOrder(
		  (_srcWarehouse->isSelected()  ? _srcWarehouse->id()  : -1),
		  (_destWarehouse->isSelected() ? _destWarehouse->id() : -1));
}

void transferOrders::sEdit()
{
  transferOrder::editTransferOrder(_to->id(), false);
}

void transferOrders::sView()
{
  transferOrder::viewTransferOrder(_to->id());
}

void transferOrders::sCopy()
{
  ParameterList params;
  params.append("tohead_id", _to->id());
      
  copyTransferOrder newdlg(this, "", TRUE);
  newdlg.set(params);
  newdlg.exec();
}

void transferOrders::sIssue()
{
  ParameterList params;
  params.append("tohead_id", _to->id());

  issueToShipping *newdlg = new issueToShipping();
  newdlg->set(params);
  omfgThis->handleNewWindow(newdlg);
  sFillList();
}

void transferOrders::sDelete()
{
  if ( QMessageBox::question(this, tr("Delete Transfer Order?"),
                             tr("<p>Are you sure that you want to completely "
				"delete the selected Transfer Order?"),
			     QMessageBox::Yes,
			     QMessageBox::No | QMessageBox::Default) == QMessageBox::Yes)
  {
    q.prepare("SELECT deleteTo(:tohead_id) AS result;");
    q.bindValue(":tohead_id", _to->id());
    q.exec();
    if (q.first())
    {
      int result = q.value("result").toInt();
      if (result == -1)
      {
	if (QMessageBox::question(this, tr("Cannot Delete Transfer Order"),
				  tr("<p>The selected Transfer Order cannot be "
				     "deleted as there have been shipments "
				     "posted against it. Would you like to "
				     "Close it instead?"),
				  QMessageBox::Yes,
				  QMessageBox::No | QMessageBox::Default) == QMessageBox::No)
	  return;

	q.prepare( "SELECT closeTransferOrder(:tohead_id) AS result;");
	q.bindValue(":tohead_id", _to->id());
	q.exec();
	if (q.first())
	{
	  int result = q.value("result").toInt();
	  if (result < 0)
	  {
	    systemError(this, storedProcErrorLookup("closeTransferOrder", result), __FILE__, __LINE__);
	    return;
	  }
	}
	else if (q.lastError().type() != QSqlError::NoError)
	{
	  systemError(this, q.lastError().databaseText(), __FILE__, __LINE__);
	  return;
	}
  
	sFillList();
      }
      else if (result < 0)
      {
	systemError(this, storedProcErrorLookup("deleteTo", result),
		    __FILE__, __LINE__);
	return;
      }
      omfgThis->sTransferOrdersUpdated(-1);
      omfgThis->sProjectsUpdated(-1);
    }
    else if (q.lastError().type() != QSqlError::NoError)
    {
      systemError(this, q.lastError().databaseText(), __FILE__, __LINE__);
      return;
    }
  }
}

void transferOrders::sPrintPackingList()
{
  ParameterList params;
  params.append("tohead_id", _to->id());
  params.append("print");

  printPackingList newdlg(this, "", TRUE);
  if (newdlg.set(params) != NoError_Print)
    newdlg.exec();
}

void transferOrders::sAddToPackingListBatch()
{
  q.prepare("SELECT addToPackingListBatch('TO', :tohead_id) AS result;");
  q.bindValue(":tohead_id", _to->id());
  q.exec();
  if (q.first())
  {
    int result = q.value("result").toInt();
    if (result < 0)
    {
      systemError(this, storedProcErrorLookup("addToPackingListBatch", result), __FILE__, __LINE__);
      return;
    }
  }
  else if (q.lastError().type() != QSqlError::NoError)
  {
    systemError(this, q.lastError().databaseText(), __FILE__, __LINE__);
    return;
  }
}

void transferOrders::sPopulateMenu(QMenu *pMenu)
{
  int menuItem;

  menuItem = pMenu->insertItem(tr("Edit..."), this, SLOT(sEdit()), 0);
  if (!_privileges->check("MaintainTransferOrders"))
    pMenu->setItemEnabled(menuItem, FALSE);

  menuItem = pMenu->insertItem(tr("View..."), this, SLOT(sView()), 0);

  menuItem = pMenu->insertItem(tr("Delete..."), this, SLOT(sDelete()), 0);
  if (!_privileges->check("MaintainTransferOrders"))
    pMenu->setItemEnabled(menuItem, FALSE);

  menuItem = pMenu->insertItem(tr("Issue To Shipping..."), this, SLOT(sIssue()), 0);
  if (!_privileges->check("IssueStockToShipping"))
    pMenu->setItemEnabled(menuItem, FALSE);

  menuItem = pMenu->insertItem(tr("Copy..."), this, SLOT(sCopy()), 0);
  if (!_privileges->check("MaintainTransferOrders"))
    pMenu->setItemEnabled(menuItem, FALSE);

  pMenu->insertSeparator();

  menuItem = pMenu->insertItem(tr("Print Packing List..."), this, SLOT(sPrintPackingList()), 0);
  if (!_privileges->check("PrintPackingLists"))
    pMenu->setItemEnabled(menuItem, FALSE);

  menuItem = pMenu->insertItem(tr("Add to Packing List Batch..."), this, SLOT(sAddToPackingListBatch()), 0);
  if (!_privileges->check("MaintainPackingListBatch"))
    pMenu->setItemEnabled(menuItem, FALSE);
}

void transferOrders::sFillList()
{
  QString sql( "SELECT DISTINCT tohead_id, tohead_number,"
               "       src.warehous_code AS srcWhs,"
               "       dest.warehous_code AS destWhs,"
               "       tohead_orderdate,"
               "       MIN(toitem_schedshipdate) AS scheduled "
               "FROM tohead LEFT OUTER JOIN toitem ON (tohead_id=toitem_tohead_id)"
               "            LEFT OUTER JOIN whsinfo src ON (src.warehous_id=tohead_src_warehous_id) "
               "            LEFT OUTER JOIN whsinfo dest ON (dest.warehous_id=tohead_dest_warehous_id) "
               "WHERE ("
	       "<? if exists(\"tohead_status\") ?>"
	       " (tohead_status = <? value(\"tohead_status\") ?>)"
	       "<? else ?>"
	       "   true"
	       "<? endif ?>"
	       "<? if exists(\"src_warehous_id\") ?>"
	       "  AND  (tohead_src_warehous_id=<? value(\"src_warehous_id\") ?>)"
	       "<? endif ?>"
	       "<? if exists(\"dest_warehous_id\") ?>"
	       "  AND  (tohead_dest_warehous_id=<? value(\"dest_warehous_id\") ?>)"
	       "<? endif ?>"
	       " ) "
	       "GROUP BY tohead_id, tohead_number,"
	       "         src.warehous_code, dest.warehous_code,"
	       "         tohead_orderdate "
	       "ORDER BY tohead_number;" );

  ParameterList params;
  setParams(params);
  MetaSQLQuery mql(sql);
  q = mql.toQuery(params);
  _to->populate(q);
  if (q.lastError().type() != QSqlError::NoError)
  {
    systemError(this, q.lastError().databaseText(), __FILE__, __LINE__);
    return;
  }
  _to->setDragString("toheadid=");
}
