package com.ampiere.web.struts.form;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;
import java.util.logging.Level;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.compiere.model.MForm;
import org.compiere.model.MLookup;
import org.compiere.model.MLookupFactory;
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 org.compiere.util.WebSessionCtx;

import com.ampiere.util.Constants;

/**
 * @author siqinbilige
 */
public class GenerateShipmentFromOrder extends Action {

    /** Logger. */
    private CLogger log = CLogger.getCLogger(this.getClass());
    
    /** Order List Forward. */
    private static final String ORDER_LIST = "orderlist";

    /** Action Form. */
    private static final String ACTION_FORM = "GenerateShipmentFromOrderForm";

    /** Global Error Forward. */
    private static final String ERROR_FORWARD = "error";

    /** C_OrderLine.M_Warehouse_ID. */
    private static final int ORDERLINE_WAREHOUSE_COLUMN_ID = 2223;

    /** Form ID. */
    private static final int FORM_ID = 110;

    /**
     * Action execute.
     * @param mapping mapping
     * @param actionForm actionForm
     * @param request request
     * @param response response
     * @throws Exception Exception
     * @return ActionForward
     * @see org.apache.struts.action.Action#execute(
     *      org.apache.struts.action.ActionMapping,
     *      org.apache.struts.action.ActionForm,
     *      javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse)
     */
    public final ActionForward execute(
            final ActionMapping mapping,
            final ActionForm actionForm,
            final HttpServletRequest request,
            final HttpServletResponse response)
    throws Exception {
    	
		//201001 
        WebSessionCtx wscTest = WebSessionCtx.get(request); 
        if (wscTest == null) {
            log.log(Level.SEVERE, "Session Time Out.");
            request.setAttribute(Constants.SESSION_TIMEOUT_INFO, "Session Time Out. Please login again.");
            return mapping.findForward(Constants.SESSION_TIMEOUT);
        }
        //--201001    	

        log.fine("Begin " + this.getClass().getName() + ";execute");

        WebSessionCtx wsc = WebSessionCtx.get(request); 
        if (wsc == null) {
            log.log(Level.SEVERE, "Session Time Out.");
            return mapping.findForward(ERROR_FORWARD);
        }

//        Env.setContext(wsc.ctx, 0, "IsSOTrx", "Y");
        wsc.ctx.setContext(0, "IsSOTrx", "Y");

        MForm form = getForm(wsc.ctx, FORM_ID);
//        Env.setContext(wsc.ctx, "FormName", form.getName());
        wsc.ctx.setContext("FormName", form.getName());

        GenerateShipmentFromOrderForm myForm =
            (GenerateShipmentFromOrderForm) request.getAttribute(ACTION_FORM);
        if (myForm == null) {
            myForm = (GenerateShipmentFromOrderForm) actionForm;
            if (myForm == null) {
                myForm = new GenerateShipmentFromOrderForm();
            }
        }
        
        // Main Window Title
        myForm.setMainWindowTitle(form.getName() + " - " + wsc.loginInfo);

        // Page title.
        myForm.setPageTitle(form.getName());

        // Ware House Label
        myForm.setWareHouseLabel(Msg.translate(wsc.ctx, "M_Warehouse_ID"));

        // Ware House Selection Data
        ArrayList < HashMap > dataList = new ArrayList < HashMap > ();
        HashMap < String, Object > data;

        // C_OrderLine.M_Warehouse_ID
//        MLookup lookup = MLookupFactory.get(wsc.ctx, 0, 0, ORDERLINE_WAREHOUSE_COLUMN_ID, DisplayType.TableDir);
        MLookup lookup = MLookupFactory.get(wsc.ctx, 0, ORDERLINE_WAREHOUSE_COLUMN_ID, DisplayType.TableDir);
        Iterator keyNames = lookup.getData(true, false, true, false).iterator();
        KeyNamePair keyName;
        while (keyNames.hasNext()) {
            keyName = (KeyNamePair) keyNames.next();
            data = new HashMap < String, Object > ();
            data.put("key", String.valueOf(keyName.getKey()));
            data.put("value", keyName.getName());
            dataList.add(data);
        }
        myForm.setWareHouseList(dataList);

        // Business Partner Label
        myForm.setBusinessPartnerLabel(Msg.translate(wsc.ctx, "C_BPartner_ID"));
        
        // Order List
        myForm.setOrderList(getOrderList(wsc, myForm.getWareHouseId(), myForm.getBusinessPartnerId()));

        // Generate Selection message
        myForm.setGeneraSelectMessage(Msg.getMsg(wsc.ctx, "InOutGenerateSel"));

        // Generate Button Label
        myForm.setGenerateButtonLabel(Msg.getMsg(wsc.ctx, "Generate"));
        
        // Cancel Button Label
        myForm.setCancelButtonLabel(Msg.getMsg(wsc.ctx, "Cancel"));
        
        // Save form to request.
        request.setAttribute(ACTION_FORM, myForm);

        log.fine("End " + this.getClass().getName() + ";execute");

        return mapping.findForward(ORDER_LIST);

    }
    
    /**
     * Get Order List.
     * @param wsc context
     * @param warehouseId Ware House ID
     * @param businessPartnerId Business Partner ID
     * @return Order List
     */
    private ArrayList getOrderList(
            final WebSessionCtx wsc,
            final int warehouseId,
            final int businessPartnerId) {
        
        ArrayList < HashMap > dataList = new ArrayList < HashMap > ();
        HashMap < String, Object > data = new HashMap < String, Object > ();

        // Row Type
        data.put("RowType", "title");
        // Order ID
        data.put("C_Order_ID", "");
        // Organization
        data.put("AD_Org_ID", Msg.translate(wsc.ctx, "AD_Org_ID"));
        // Document Type
        data.put("C_DocType_ID", Msg.translate(wsc.ctx, "C_DocType_ID"));
        // Document Number
        data.put("DocumentNo", Msg.translate(wsc.ctx, "DocumentNo"));
        // Business Partner
        data.put("C_BPartner_ID", Msg.translate(wsc.ctx, "C_BPartner_ID"));
        // Date Ordered
        data.put("DateOrdered", Msg.translate(wsc.ctx, "DateOrdered"));
        // Total Lines
        data.put("TotalLines", Msg.translate(wsc.ctx, "TotalLines"));
        dataList.add(data);

//        int clientId = Env.getAD_Client_ID(wsc.ctx);
        int clientId = wsc.ctx.getAD_Client_ID();

        //  Create SQL
        StringBuffer sql = new StringBuffer(
            "SELECT C_Order_ID, o.Name, dt.Name, DocumentNo, bp.Name, DateOrdered, TotalLines "
            + "FROM M_InOut_Candidate_v ic, AD_Org o, C_BPartner bp, C_DocType dt "
            + "WHERE ic.AD_Org_ID=o.AD_Org_ID"
            + " AND ic.C_BPartner_ID=bp.C_BPartner_ID"
            + " AND ic.C_DocType_ID=dt.C_DocType_ID"
            + " AND ic.AD_Client_ID=?");

        if (warehouseId > 0) {
            sql.append(" AND ic.M_Warehouse_ID=").append(warehouseId);
        }

        if (businessPartnerId > 0) {
            sql.append(" AND ic.C_BPartner_ID=").append(businessPartnerId);
        }

        sql.append(" ORDER BY o.Name,bp.Name,DateOrdered");
        log.fine(sql.toString());

        //  Execute
        try {
            PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null);
            pstmt.setInt(1, clientId);
            ResultSet rs = pstmt.executeQuery();
            int count = 0;
            while (rs.next()) {
                count++;
                data = new HashMap < String, Object > ();
                // Row Type
                if ((count % 2) == 0) {
                    data.put("RowType", "even");
                } else {
                    data.put("RowType", "odd");
                }
                // Order ID
                data.put("C_Order_ID", rs.getInt(1));
                // Organization
                data.put("AD_Org_ID", rs.getString(2));
                // Document Type
                data.put("C_DocType_ID", rs.getString(3));
                // Document Number
                data.put("DocumentNo", rs.getString(4));
                // Business Partner
                data.put("C_BPartner_ID", rs.getString(5));
                // Date Ordered
                data.put("DateOrdered", wsc.dateFormat.format(rs.getTimestamp(6)));
                // Total Lines
                data.put("TotalLines", wsc.amountFormat.format(rs.getBigDecimal(7)));
                dataList.add(data);
            }
            rs.close();
            pstmt.close();
        } catch (SQLException e) {
            log.log(Level.SEVERE, sql.toString(), e);
        }
        
        return dataList;
    }
    
    /**
     *  Get Form from Form ID.
     *  @param ctx Properties
     *  @param formId Form ID
     *  @return form
     */
    private MForm getForm(final Ctx ctx, final int formId) {

        // Get Form from Form ID
        MForm form = new MForm(ctx, formId, null);
        
        boolean trl = !Env.isBaseLanguage(ctx, "AD_Form");
        if (trl) {
            String sql = "SELECT t.Name, t.Description, t.Help "
                       + "FROM AD_Form f INNER JOIN AD_Form_Trl t"
                       + " ON (f.AD_Form_ID=t.AD_Form_ID AND AD_Language=?)"
                       + "WHERE f.AD_Form_ID=?";
            try {
                PreparedStatement pstmt = DB.prepareStatement(sql, null);
                if (trl) {
                    pstmt.setString(1, Env.getAD_Language(ctx));
                    pstmt.setInt(2, formId);

                    ResultSet rs = pstmt.executeQuery();
                    if (rs.next()) {
                        form.setName(rs.getString(1));
                        form.setDescription(rs.getString(2));
                        form.setHelp(rs.getString(3));
                    }
                    rs.close();
                    pstmt.close();
                }
            } catch (SQLException e) {
                log.log(Level.SEVERE, sql, e);
            }
        }

        return form;
    }   //  getForm
}
