/**
 * 
 */
package com.ampiere.web.struts.button;

import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;

import org.apache.ecs.AlignType;
import org.compiere.util.CLogger;
import org.compiere.util.Ctx;
import org.compiere.util.DB;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg;

import com.ampiere.dto.CodeValue;
import com.ampiere.search.ColBean;

/**
 * @author Shinjirito
 */
public class CreateFromBaseForm extends ButtonActionForm {
	private static final long serialVersionUID = 5440599556685262025L;

	/**	Logger			*/
	protected CLogger	log = CLogger.getCLogger(this.getClass());

	protected String bpartnerLabel;
	protected int bpartnerID;
	protected String bpartnerName;
	protected String orderLabel;
	protected String orderSelected;
	protected List<CodeValue> orderList;
	protected String shipmentLabel;
	protected String shipmentSelected;
	protected List<CodeValue> shipmentList;
	protected String invoiceLabel;
	protected String invoiceSelected;
	protected List<CodeValue> invoiceList;
	protected int operation;
	protected String selectedIndex;

	/**
	 *	Static Setup - set field value
	 */
	public void statInit(Ctx ctx) {
		super.statInit(ctx);
		setTitle(Msg.getElement(ctx, "C_Invoice_ID", false) + " .. " + Msg.translate(ctx, "CreateFrom"));

		setBpartnerLabel(Msg.getElement(ctx, "C_BPartner_ID"));
		setOrderLabel(Msg.getElement(ctx, "C_Order_ID", false));
		setShipmentLabel(Msg.getElement(ctx, "M_InOut_ID", false));
		setInvoiceLabel(Msg.getElement(ctx, "C_Invoice_ID", false));
	}

	/**************************************************************************
	 *  Load BPartner Field
	 *  @param forInvoice true if Invoices are to be created, false receipts
	 *  @throws Exception if Lookups cannot be initialized
	 */
	protected void initBPartner (int C_BPartner_ID, boolean forInvoice, Ctx ctx)
	{
		//  initial loading
		initBPartnerOIS(C_BPartner_ID, forInvoice, ctx);
	}   //  initBPartner

	/**
	 *  Load PBartner dependent Order/Invoice/Shipment Field.
	 *  @param C_BPartner_ID BPartner
	 *  @param forInvoice for invoice
	 */
	protected void initBPartnerOIS (int C_BPartner_ID, boolean forInvoice, Ctx ctx)
	{
		log.config("C_BPartner_ID=" + C_BPartner_ID);
		CodeValue pp = new CodeValue("0", "");
		orderList = new ArrayList<CodeValue>();
		orderList.add(pp);

		//	Display
		StringBuffer display = new StringBuffer("o.DocumentNo||' - ' ||")
			.append(DB.TO_CHAR("o.DateOrdered", DisplayType.Date, Env.getAD_Language(ctx)))
			.append("||' - '||")
			.append(DB.TO_CHAR("o.GrandTotal", DisplayType.Amount, Env.getAD_Language(ctx)));

		//
		String column = "m.M_InOutLine_ID";
		if (forInvoice)
			column = "m.C_InvoiceLine_ID";
		StringBuffer sql = new StringBuffer("SELECT o.C_Order_ID,").append(display)
			.append(" FROM C_Order o "
			+ "WHERE o.C_BPartner_ID=? AND o.IsSOTrx='N' AND o.DocStatus IN ('CL','CO')"
			+ " AND o.C_Order_ID IN "
				  + "(SELECT ol.C_Order_ID FROM C_OrderLine ol"
				  + " LEFT OUTER JOIN M_MatchPO m ON (ol.C_OrderLine_ID=m.C_OrderLine_ID) "
				  + "GROUP BY ol.C_Order_ID,ol.C_OrderLine_ID, ol.QtyOrdered,").append(column)
				  .append(" HAVING (ol.QtyOrdered <> SUM(m.Qty) AND ").append(column)
				  .append(" IS NOT NULL) OR ").append(column).append(" IS NULL) "
			+ "ORDER BY o.DateOrdered");
		try
		{
			PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
			pstmt.setInt(1, C_BPartner_ID);
			ResultSet rs = pstmt.executeQuery();
			while (rs.next())
			{
				pp = new CodeValue(rs.getString(1), rs.getString(2));
				orderList.add(pp);
			}
			rs.close();
			pstmt.close();
		}
		catch (SQLException e)
		{
			log.log(Level.SEVERE, sql.toString(), e);
		}

		orderSelected = "0";
		initBPDetails(C_BPartner_ID, ctx);
	}   //  initBPartnerOIS

	/**
	 *  Load Data - Order
	 *  @param C_Order_ID Order
	 *  @param forInvoice true if for invoice vs. delivery qty
	 */
	public List loadOrder (int C_Order_ID, boolean forInvoice, Ctx ctx, int maxRecNo)
	{
		/**
		 *  Selected        - 0
		 *  Qty             - 1
		 *  C_UOM_ID        - 2
		 *  M_Product_ID    - 3
		 *  OrderLine       - 4
		 *  ShipmentLine    - 5
		 *  InvoiceLine     - 6
		 */
		log.config("C_Order_ID=" + C_Order_ID);
//		p_order = new MOrder (ctx, C_Order_ID, null);      //  save

		StringBuffer sql = new StringBuffer("SELECT "
			+ "l.QtyOrdered-SUM(COALESCE(m.Qty,0)),"					//	1
			+ "CASE WHEN l.QtyOrdered=0 THEN 0 ELSE l.QtyEntered/l.QtyOrdered END,"	//	2
			+ " l.C_UOM_ID,COALESCE(uom.UOMSymbol,uom.Name),"			//	3..4
			+ " COALESCE(l.M_Product_ID,0),COALESCE(p.Name,c.Name),"	//	5..6
			+ " l.C_OrderLine_ID,l.Line "								//	7..8
			+ "FROM C_OrderLine l"
			+ " LEFT OUTER JOIN M_MatchPO m ON (l.C_OrderLine_ID=m.C_OrderLine_ID AND ");
		sql.append(forInvoice ? "m.C_InvoiceLine_ID" : "m.M_InOutLine_ID");
		sql.append(" IS NOT NULL)")
			.append(" LEFT OUTER JOIN M_Product p ON (l.M_Product_ID=p.M_Product_ID)"
			+ " LEFT OUTER JOIN C_Charge c ON (l.C_Charge_ID=c.C_Charge_ID)");
		if (Env.isBaseLanguage(ctx, "C_UOM"))
			sql.append(" LEFT OUTER JOIN C_UOM uom ON (l.C_UOM_ID=uom.C_UOM_ID)");
		else
			sql.append(" LEFT OUTER JOIN C_UOM_Trl uom ON (l.C_UOM_ID=uom.C_UOM_ID AND uom.AD_Language='")
				.append(Env.getAD_Language(ctx)).append("')");
		//
		sql.append(" WHERE l.C_Order_ID=? "			//	#1
			+ "GROUP BY l.QtyOrdered,CASE WHEN l.QtyOrdered=0 THEN 0 ELSE l.QtyEntered/l.QtyOrdered END, "
			+ "l.C_UOM_ID,COALESCE(uom.UOMSymbol,uom.Name), "
				+ "l.M_Product_ID,COALESCE(p.Name,c.Name), l.Line,l.C_OrderLine_ID "
			+ "ORDER BY l.Line");
		//
		log.finer(sql.toString());

		ArrayList<ColBean> resultList = new ArrayList<ColBean>();
		try
		{
			PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
			pstmt.setInt(1, C_Order_ID);
			ResultSet rs = pstmt.executeQuery();
			int lineCount = 0;
			while (rs.next())
			{
				ColBean colBean = new ColBean();
				colBean.setColId(Integer.toString(lineCount));
				int beanOffset = 0;

				if (++lineCount > maxRecNo) {
					break;
				}

				// 0-Selection
				colBean.setColData(beanOffset, "false");
				colBean.setColTitle(beanOffset, Msg.translate(ctx, "Select"));
				colBean.setStyle(beanOffset, "text-align: " + AlignType.CENTER + ";");
				beanOffset++;

				// 1-Qty
				BigDecimal qtyOrdered = rs.getBigDecimal(1);
				BigDecimal multiplier = rs.getBigDecimal(2);
				BigDecimal qtyEntered = qtyOrdered.multiply(multiplier);
				colBean.setColData(beanOffset, qtyEntered);
				colBean.setColTitle(beanOffset, Msg.translate(ctx, "Quantity"));
				colBean.setStyle(beanOffset, "text-align: " + AlignType.RIGHT + ";");
				beanOffset++;

				// 2-UOM
				KeyNamePair pp = new KeyNamePair(rs.getInt(3), rs.getString(4).trim());
				colBean.setColData(beanOffset, pp);
				colBean.setColTitle(beanOffset, Msg.translate(ctx, "C_UOM_ID"));
				colBean.setStyle(beanOffset, "text-align: " + AlignType.LEFT + ";");
				beanOffset++;

				// 3-Product
				pp = new KeyNamePair(rs.getInt(5), rs.getString(6));
				colBean.setColData(beanOffset, pp);
				colBean.setColTitle(beanOffset, Msg.translate(ctx, "M_Product_ID"));
				colBean.setStyle(beanOffset, "text-align: " + AlignType.LEFT + ";");
				beanOffset++;

				// 4-OrderLine
				pp = new KeyNamePair(rs.getInt(7), rs.getString(8));
				colBean.setColData(beanOffset, pp);
				colBean.setColTitle(beanOffset, Msg.getElement(ctx, "C_Order_ID", false));
				colBean.setStyle(beanOffset, "text-align: " + AlignType.LEFT + ";");
				beanOffset++;

				// 5-Ship
				colBean.setColData(beanOffset, null);
				colBean.setColTitle(beanOffset, Msg.getElement(ctx, "M_InOut_ID", false));
				colBean.setStyle(beanOffset, "text-align: " + AlignType.LEFT + ";");
				beanOffset++;

				// 6-Invoice
				colBean.setColData(beanOffset, null);
				colBean.setColTitle(beanOffset, Msg.getElement(ctx, "C_Invoice_ID", false));
				colBean.setStyle(beanOffset, "text-align: " + AlignType.LEFT + ";");
				beanOffset++;

				resultList.add(colBean);
			}
			rs.close();
			pstmt.close();
		}
		catch (Exception e)
		{
			log.log(Level.SEVERE, sql.toString(), e);
		}

		return resultList;
	}   //  LoadOrder

	/**
	 *  Init Business Partner Details
	 *  @param C_BPartner_ID BPartner
	 */
	void initBPDetails(int C_BPartner_ID, Ctx ctx) {
	}

	/**
	 *	Dynamic Init
	 *  @param bpName Postal name
	 *  @param whereClause where clause
	 */
	public void initInfo(String key)
	{
	}	//	initInfo

	public int getBpartnerID() {
		return bpartnerID;
	}

	public void setBpartnerID(int bpartnerID) {
		this.bpartnerID = bpartnerID;
	}

	public String getBpartnerLabel() {
		return bpartnerLabel;
	}

	public void setBpartnerLabel(String bpartnerLabel) {
		this.bpartnerLabel = bpartnerLabel;
	}

	public String getBpartnerName() {
		return bpartnerName;
	}

	public void setBpartnerName(String bpartnerName) {
		this.bpartnerName = bpartnerName;
	}

	public String getOrderLabel() {
		return orderLabel;
	}

	public void setOrderLabel(String orderLabel) {
		this.orderLabel = orderLabel;
	}

	public List<CodeValue> getOrderList() {
		return orderList;
	}

	public void setOrderList(List<CodeValue> orderList) {
		this.orderList = orderList;
	}

	public String getOrderSelected() {
		return orderSelected;
	}

	public void setOrderSelected(String orderSelected) {
		this.orderSelected = orderSelected;
	}

	public List<CodeValue> getShipmentList() {
		return shipmentList;
	}

	public void setShipmentList(List<CodeValue> shipmentList) {
		this.shipmentList = shipmentList;
	}

	public String getShipmentSelected() {
		return shipmentSelected;
	}

	public void setShipmentSelected(String shipmentSelected) {
		this.shipmentSelected = shipmentSelected;
	}

	public String getShipmentLabel() {
		return shipmentLabel;
	}

	public void setShipmentLabel(String shipmentLabel) {
		this.shipmentLabel = shipmentLabel;
	}

	public int getOperation() {
		return operation;
	}

	public void setOperation(int operation) {
		this.operation = operation;
	}

	public String getSelectedIndex() {
		return selectedIndex;
	}

	public void setSelectedIndex(String selectedIndex) {
		this.selectedIndex = selectedIndex;
	}

	public String getInvoiceLabel() {
		return invoiceLabel;
	}

	public void setInvoiceLabel(String invoiceLabel) {
		this.invoiceLabel = invoiceLabel;
	}

	public List<CodeValue> getInvoiceList() {
		return invoiceList;
	}

	public void setInvoiceList(List<CodeValue> invoiceList) {
		this.invoiceList = invoiceList;
	}

	public String getInvoiceSelected() {
		return invoiceSelected;
	}

	public void setInvoiceSelected(String invoiceSelected) {
		this.invoiceSelected = invoiceSelected;
	}
}
