/******************************************************************************
 * Product: JPiere                                                            *
 * Copyright (C) Hideaki Hagiwara (h.hagiwara@oss-erp.co.jp)                  *
 *                                                                            *
 * This program is free software, you can redistribute it and/or modify it    *
 * under the terms version 2 of the GNU General Public License as published   *
 * by the Free Software Foundation. This program is distributed in the hope   *
 * that it will be useful, but WITHOUT ANY WARRANTY.                          *
 * See the GNU General Public License for more details.                       *
 *                                                                            *
 * JPiere is maintained by OSS ERP Solutions Co., Ltd.                        *
 * (http://www.oss-erp.co.jp)                                                 *
 *****************************************************************************/
package jpiere.base.plugin.org.adempiere.model;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import org.compiere.model.MStorageOnHand;
import org.compiere.model.MTable;
import org.compiere.model.Query;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Util;

/**
 * JPIERE-0501:JPiere PP Fact Line MA
 *
 * @author Hideaki Hagiwara(h.hagiwara@oss-erp.co.jp)
 *
 */
public class MPPFactLineMA extends X_JP_PP_FactLineMA {

	public MPPFactLineMA(Properties ctx, int JP_PP_FactLineMA_ID, String trxName)
	{
		super(ctx, JP_PP_FactLineMA_ID, trxName);
	}

	public MPPFactLineMA(Properties ctx, ResultSet rs, String trxName)
	{
		super(ctx, rs, trxName);
	}

	/**
	 * Parent constructor
	 * @param parent
	 * @param asi
	 * @param qty
	 * @param dateMaterialPolicy
	 */
	public MPPFactLineMA( MPPFactLine parent, int asi, BigDecimal qty,Timestamp dateMaterialPolicy)	{
		super(parent.getCtx(),0,parent.get_TrxName());
		setM_AttributeSetInstance_ID(asi);
		setJP_PP_FactLine_ID(parent.get_ID());
		setMovementQty(qty);
		setAD_Org_ID(parent.getAD_Org_ID());
		if (dateMaterialPolicy == null)
		{
			if (asi > 0)
			{
				dateMaterialPolicy = MStorageOnHand.getDateMaterialPolicy(parent.getM_Product_ID(), asi, parent.get_TrxName());
			}
			if (dateMaterialPolicy == null)
			{
				dateMaterialPolicy = parent.getJP_PP_Fact().getMovementDate();
			}
		}
		setDateMaterialPolicy(dateMaterialPolicy);
	}

	/**
	 * @param parent
	 * @param M_AttributeSetInstance_ID
	 * @param MovementQty
	 * @param DateMaterialPolicy
	 * @param isAutoGenerated
	 */
	public MPPFactLineMA (MPPFactLine parent, int M_AttributeSetInstance_ID, BigDecimal MovementQty,Timestamp DateMaterialPolicy,boolean isAutoGenerated)
	{
		this (parent.getCtx(), 0, parent.get_TrxName());
		setClientOrg(parent);
		setJP_PP_FactLine_ID(parent.getJP_PP_FactLine_ID());
		//
		setM_AttributeSetInstance_ID(M_AttributeSetInstance_ID);
		setMovementQty(MovementQty);
		if (DateMaterialPolicy == null)
		{
			if (M_AttributeSetInstance_ID > 0)
			{
				DateMaterialPolicy = MStorageOnHand.getDateMaterialPolicy(parent.getM_Product_ID(), M_AttributeSetInstance_ID, parent.get_TrxName());
			}
			if (DateMaterialPolicy == null)
			{
				DateMaterialPolicy = parent.getParent().getMovementDate();
			}
		}
		setDateMaterialPolicy(DateMaterialPolicy);
		setIsAutoGenerated(isAutoGenerated);
	}	//	MMovementLineMA

	@Override
	public void setDateMaterialPolicy(Timestamp DateMaterialPolicy) {
		if (DateMaterialPolicy != null)
			DateMaterialPolicy = Util.removeTime(DateMaterialPolicy);
		super.setDateMaterialPolicy(DateMaterialPolicy);
	}

	public static MPPFactLineMA get( MPPFactLine parent, int asi, Timestamp dateMPolicy )  {
		String where = " JP_PP_FactLine_ID = ? AND M_AttributeSetInstance_ID = ? ";
		if(dateMPolicy==null){
			dateMPolicy = new Timestamp(new Date().getTime());
		}
		where = where + "AND DateMaterialPolicy = trunc(cast(? as date))";

		MPPFactLineMA lineMA = MTable.get(parent.getCtx(), MPPFactLineMA.Table_Name).createQuery(where, parent.get_TrxName())
		.setParameters(parent.getJP_PP_FactLine_ID(), asi,dateMPolicy).first();

		if (lineMA != null)
			return lineMA;
		else
			return new MPPFactLineMA( parent,asi, Env.ZERO,dateMPolicy);
	}

	/**
	 * 	Get Material Allocations for Line
	 *	@param ctx context
	 *	@param M_ProductionLine_ID line
	 *	@param trxName trx
	 *	@return allocations
	 */
	public static MPPFactLineMA[] get (Properties ctx, int JP_PP_FactLine_ID, String trxName)
	{

		Query query = MTable.get(ctx, MPPFactLineMA.Table_Name)
							.createQuery(MPPFactLineMA.COLUMNNAME_JP_PP_FactLine_ID+"=?", trxName);
		query.setParameters(JP_PP_FactLine_ID);
		List<MPPFactLineMA> list = query.list();
		MPPFactLineMA[] retValue = list.toArray (new MPPFactLineMA[0]);
		return retValue;
	}	//	get


	/**
	 * 	Delete all Material Allocation for InOutLine
	 *	@param M_InOutLine_ID Shipment Line
	 *	@param trxName transaction
	 *	@return number of rows deleted or -1 for error
	 */
	public static int deletePPFactLineMA (int JP_PP_FactLine_ID, String trxName)
	{
		String sql = "DELETE FROM JP_PP_FactLineMA ma WHERE ma.JP_PP_FactLine_ID=? AND ma.IsAutoGenerated='Y'";
		return DB.executeUpdate(sql, JP_PP_FactLine_ID, trxName);
	}

	public static MPPFactLineMA addOrCreate(MPPFactLine line, int M_AttributeSetInstance_ID, BigDecimal MovementQty, Timestamp DateMaterialPolicy,boolean isAutoGenerated)
	{
		Query query = new Query(Env.getCtx(), I_JP_PP_FactLineMA.Table_Name, "JP_PP_FactLine_ID=? AND M_AttributeSetInstance_ID=? AND DateMaterialPolicy=trunc(cast(? as date))",
					line.get_TrxName());
		MPPFactLineMA po = query.setParameters(line.getJP_PP_FactLine_ID(), M_AttributeSetInstance_ID, DateMaterialPolicy).first();
		if (po == null)
			po = new MPPFactLineMA(line, M_AttributeSetInstance_ID, MovementQty, DateMaterialPolicy,isAutoGenerated);
		else
			po.setMovementQty(po.getMovementQty().add(MovementQty));
		return po;
	}

	/**
	 * Total qty on LineMA for M_InoutLine
	 * @param M_InOutLine_ID
	 * @param trxName
	 * @return
	 */
	public static BigDecimal getManualQty (int JP_PP_Factine_ID, String trxName)
	{
		String sql = "SELECT SUM(movementqty) FROM JP_PP_FactLineMA ma WHERE ma.JP_PP_FactLine_ID=? AND ma.IsAutoGenerated='N'";
		BigDecimal totalQty = DB.getSQLValueBD(trxName, sql, JP_PP_Factine_ID);
		return totalQty==null?Env.ZERO:totalQty;
	} //totalLineQty

	@Override
	protected boolean beforeSave(boolean newRecord)
	{

		if(newRecord)
		{
			//SetAD_Org_ID
			setAD_Org_ID(getParent().getAD_Org_ID());

			//End Product
			if(getParent().isEndProduct())
			{
				log.saveError("Error", Msg.getElement(getCtx(), MPPFactLine.COLUMNNAME_IsEndProduct));
				return false;
			}

		}

		//Check Parent processed
		if(getParent().isProcessed())
		{
			log.saveError("Error", Msg.getElement(getCtx(), MPPFact.COLUMNNAME_Processed));
			return false;
		}

		if(isAutoGenerated())
		{
			//
			log.saveError("Error", "PP Fact Line does not create instance automatically");
			return false;
		}

		return true;
	}

	private MPPFactLine m_PPFactLine = null;

	public MPPFactLine getParent()
	{
		if(m_PPFactLine == null)
			m_PPFactLine = new MPPFactLine(getCtx(), getJP_PP_FactLine_ID(), get_TrxName());
		else
			m_PPFactLine.set_TrxName(get_TrxName());

		return m_PPFactLine;
	}


}
