using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Xml;
using System.ServiceModel;
using System.Linq;
using System.Reflection;

namespace SiaSun.LMS.Implement
{
    [ServiceBehavior(IncludeExceptionDetailInFaults = true, 
    InstanceContextMode = InstanceContextMode.Single, 
    ConcurrencyMode = ConcurrencyMode.Multiple, 
    MaxItemsInObjectGraph = int.MaxValue)] 
    public partial class S_PlanService : SiaSun.LMS.Implement.S_BaseService, SiaSun.LMS.Interface.I_PlanService
    {

        public S_PlanService()
        {
        }


        public bool Invoke(string sPlanType, string sMethod, object[] inParams, out string sResult)
        {
            bool bResult = true;

            sResult = string.Empty;

            string sClassFullName = string.Format("SiaSun.LMS.Implement.{0}", sPlanType);

            List<object> oPara = inParams.ToList<object>();

            oPara.Add(sResult);

            Type t = this.GetType();

            Assembly complierAssembly = t.Assembly;

            object complierInstance = complierAssembly.CreateInstance(sClassFullName);

            Type type = complierInstance.GetType();

            object[] obj = oPara.ToArray();

            object oResult = null;

            //创建反射的所有公用方法
            MethodInfo[] lsMethodInfo = type.GetMethods();

            foreach (MethodInfo methodInfo in lsMethodInfo)
            {
                if (methodInfo.Name.Equals(sMethod) && oPara.Count.Equals(methodInfo.GetParameters().Length))
                {
                    oResult = methodInfo.Invoke(complierInstance, obj);

                    break;
                }
            }

            bResult = Convert.ToBoolean(oResult);

            sResult = obj[oPara.Count - 1].ToString();

            return bResult;
        }


        public bool Invoke(string sPlanType, string sMethod, object[] inParams, out object[] outParams)
        {
            bool bResult = true;

            string sClassFullName = string.Format("SiaSun.LMS.Implement.{0}", sPlanType);

            List<object> oPara = inParams.ToList<object>();

            Type t = this.GetType();

            Assembly complierAssembly = t.Assembly;

            object complierInstance = complierAssembly.CreateInstance(sClassFullName);

            Type type = complierInstance.GetType();

            outParams = oPara.ToArray();

            object oResult = null;

            //创建反射的所有公用方法
            MethodInfo[] lsMethodInfo = type.GetMethods();

            foreach (MethodInfo methodInfo in lsMethodInfo)
            {
                if (methodInfo.Name.Equals(sMethod) && oPara.Count.Equals(methodInfo.GetParameters().Length))
                {
                    oResult = methodInfo.Invoke(complierInstance, outParams);

                    break;
                }
            }

            bResult = Convert.ToBoolean(oResult);

            return bResult;
        }


        #region     ------PLAN_TYPE


        /// <summary>
        /// 获得所有列表
        /// </summary>
        public DataTable PlanTypeGetData()
        {
            return this.GetList("");
        }


        /// <summary>
        /// 获得PLAN_TYPE模型
        /// </summary>
        /// <returns></returns>
        public SiaSun.LMS.Model.PLAN_TYPE PlanTypeGetModel(string PLAN_TYPE_CODE)
        {
            return this._P_PLAN_TYPE.GetModel(1);
        }

        #endregion

        #region     ------PLAN_MAIN

        /// <summary>
        /// 获得PLAN模型
        /// </summary>
        public SiaSun.LMS.Model.PLAN_MAIN PlanGetModel(int PLAN_ID)
        {
            return this._P_PLAN_MAIN.GetModel(PLAN_ID);
        }


        /// <summary>
        /// 获得PLAN模型
        /// </summary>
        public SiaSun.LMS.Model.PLAN_DETAIL PlanDetailGetModel(int PLAN_DETAIL_ID)
        {
            return this._P_PLAN_DETAIL.GetModel(PLAN_DETAIL_ID);
        }


        #endregion

        #region     -------PLAN_LIST

        /// <summary>
        /// 获得PLANLIST模型
        /// </summary>
        public SiaSun.LMS.Model.PLAN_LIST PlanListGetModel(int PLAN_LIST_ID)
        {
            return this._P_PLAN_LIST.GetModel(PLAN_LIST_ID);
        }

        #endregion

        public bool PlanDownLoad(int PLAN_ID, out string sResult)
        {
            bool bResult = true;

            sResult = string.Empty;

            //Model.PLAN_MAIN mPLAN_MAIN = this._P_PLAN_MAIN.GetModel(PLAN_ID);

            //bResult = mPLAN_MAIN != null;

            //if (!bResult)
            //{
            //    sResult = string.Format("未找到计划{0}", PLAN_ID.ToString());

            //    return bResult;
            //}

            //IList<SiaSun.LMS.Model.PLAN_LIST> lsPLAN_LIST = this._P_PLAN_LIST.GetListPlanID(PLAN_ID);

            //List<int> lsEND_CELL_ID = new List<int>();

            //Model.WH_CELL mWH_CELL_END = null;

            //IList<SiaSun.LMS.Model.WH_CELL> lsEND_CELL = null;

            //bResult = !string.IsNullOrEmpty(mPLAN_MAIN.PLAN_INOUT_STATION);

            //if (!bResult)
            //{
            //    sResult = string.Format("传入站台为空-任务号为{0}", mPLAN_MAIN.PLAN_CODE);

            //    return bResult;
            //}

            //mWH_CELL_END = this._P_WH_CELL.GetModel(mPLAN_MAIN.PLAN_INOUT_STATION);

            //bResult = null != mWH_CELL_END;

            //if (!bResult)
            //{
            //    sResult = string.Format("未找到站台{0}-任务号为{1}", mPLAN_MAIN.PLAN_INOUT_STATION, mPLAN_MAIN.PLAN_CODE);

            //    return bResult;
            //}

            //if (!mWH_CELL_END.LANE_WAY.Equals(0))
            //{
            //    lsEND_CELL = this._P_WH_CELL.GetList_LANEWAY(mWH_CELL_END.LANE_WAY);
            //}

            //if (lsEND_CELL != null && lsEND_CELL.Count > 0)
            //{
            //    foreach (WH_CELL mWH_CELL in lsEND_CELL)
            //    {
            //        lsEND_CELL_ID.Add(mWH_CELL.CELL_ID);
            //    }

            //    lsEND_CELL_ID.Remove(mWH_CELL_END.CELL_ID);

            //    lsEND_CELL_ID.Insert(0, mWH_CELL_END.CELL_ID);
            //}
            //else
            //{
            //    lsEND_CELL_ID.Add(mWH_CELL_END.CELL_ID);
            //}

            //try
            //{
            //    this._P_Base_House.BeginTransaction();

            //    foreach (Model.PLAN_LIST mPLAN_LIST in lsPLAN_LIST)
            //    {

            //        bResult = this.PlanListDownLoad( mPLAN_LIST.PLAN_LIST_ID, out sResult);

            //        if (!bResult)
            //        {
            //            return bResult;
            //        }
            //    }

            //    //更新计划状态
            //    mPLAN_MAIN.PLAN_STATUS = Enum.PLAN_STATUS.Executing.ToString();

            //    this._P_PLAN_MAIN.Update(mPLAN_MAIN);
            //}
            //catch (Exception ex)
            //{
            //    bResult = false;

            //    sResult = ex.ToString();
            //}
            //finally
            //{
            //    if (bResult)
            //    {
            //        this._P_Base_House.CommitTransaction();
            //    }
            //    else
            //    {
            //        this._P_Base_House.RollBackTransaction();
            //    }
            //}

            return bResult;
        }


        public bool PlanListDownLoad(Model.SYS_USER mSYS_USER ,int PLAN_LIST_ID, int END_CELL_ID, bool bTrans, out string sResult)
        {
            bool bResult = true;

            sResult = string.Empty;

            string sMsg = string.Empty;

            SiaSun.LMS.Model.PLAN_LIST mPLAN_LIST = this._P_PLAN_LIST.GetModel(PLAN_LIST_ID);

            SiaSun.LMS.Model.PLAN_MAIN mPLAN_MAIN = this._P_PLAN_MAIN.GetModel(mPLAN_LIST.PLAN_ID);

            SiaSun.LMS.Model.PLAN_TYPE mPLAN_TYPE = this._P_PLAN_TYPE.GetModelPlanTypeCode(mPLAN_MAIN.PLAN_TYPE_CODE);

            int iSTART_CELL_ID = 0;

            string STOCK_BARCODE = string.Empty;

            decimal MANAGE_ORDERED_QUANTITY = 0;

            System.Data.DataTable dtLANEWAY = null;

            bResult = this._S_CellService.LaneWayGetList(END_CELL_ID, mPLAN_LIST.GOODS_ID, string.Empty, out dtLANEWAY, out sResult);

            if (!bResult)
            {
                return bResult;
            }

            int iSumQuantity = 0;

            foreach (DataRow drLANEWAY in dtLANEWAY.Rows)
            {
                iSumQuantity += Convert.ToInt32(drLANEWAY["LANEWAY_QUANTITY"]);
            }

            bResult = iSumQuantity >= Convert.ToInt32(mPLAN_LIST.PLAN_LIST_QUANTITY) - Convert.ToInt32(mPLAN_LIST.PLAN_LIST_ORDERED_QUANTITY);

            if (!bResult)
            {
                sResult = string.Format("计划执行失败。计划出库数量为{1},当前可用库存为{0},", iSumQuantity, mPLAN_LIST.PLAN_LIST_QUANTITY.ToString());

                return bResult;
            }

            try
            {
                this._P_Base_House.BeginTransaction(bTrans);

                while (mPLAN_LIST.PLAN_LIST_QUANTITY > mPLAN_LIST.PLAN_LIST_ORDERED_QUANTITY)
                {

                        decimal MANAGE_LIST_QUANTITY = mPLAN_LIST.PLAN_LIST_QUANTITY - mPLAN_LIST.PLAN_LIST_ORDERED_QUANTITY;

                        //判断计划是否已经全部下达
                        if (MANAGE_LIST_QUANTITY <= 0)
                        {
                            break;
                        }

                        DataView dvLANEWAY = dtLANEWAY.DefaultView;

                        dvLANEWAY.RowFilter = "LANEWAY_QUANTITY > 0";

                        dvLANEWAY.Sort = "MANAGE_QUANTITY asc,LANEWAY_QUANTITY desc";

                        bResult = dvLANEWAY.Count > 0;

                        if (!bResult)
                        {
                            sResult = "满足条件的库存数量不足,注意自动校表线只能出满垛(24只)";

                            this._P_Base_House.RollBackTransaction(bTrans);

                            return bResult;
                        }

                        int iLANEWAY = Convert.ToInt32(dvLANEWAY[0]["LANE_WAY"]);

                        bResult = this._S_CellService.CellOutAllocate(iLANEWAY, END_CELL_ID, mPLAN_LIST.GOODS_ID, string.Empty, MANAGE_LIST_QUANTITY, out iSTART_CELL_ID, out STOCK_BARCODE, out MANAGE_ORDERED_QUANTITY, out sResult);

                        if (!bResult)
                        {
                            dvLANEWAY[0]["LANEWAY_QUANTITY"] = 0;

                            break;

                        }

                        bResult = new SiaSun.LMS.Implement.ManageBase().ManageCreate(mSYS_USER, PLAN_LIST_ID, mPLAN_TYPE.MANAGE_TYPE_CODE,STOCK_BARCODE, iSTART_CELL_ID, END_CELL_ID, false, true, false, out sResult);

                        if (!bResult)
                        {
                            sResult += sMsg;

                            this._P_Base_House.RollBackTransaction(bTrans);

                            return bResult;
                        }

                        decimal dLANEWAY_QUANTITY_SUB = Convert.ToDecimal(dvLANEWAY[0].Row["LANEWAY_QUANTITY"]) - MANAGE_ORDERED_QUANTITY;

                        dvLANEWAY[0].Row["LANEWAY_QUANTITY"] = dLANEWAY_QUANTITY_SUB;

                        if (dLANEWAY_QUANTITY_SUB > 0)
                        {
                            dvLANEWAY[0].Row["MANAGE_QUANTITY"] = Convert.ToDecimal(dvLANEWAY[0].Row["MANAGE_QUANTITY"]) + 1;
                        }

                        mPLAN_LIST = this._P_PLAN_LIST.GetModel(PLAN_LIST_ID);
                   
                }

                this._P_Base_House.CommitTransaction(bTrans);
            }
            catch (Exception ex)
            {
                this._P_Base_House.RollBackTransaction(bTrans);

                bResult = false;

                sResult = ex.Message;
            }

            return bResult;
        }


        public bool PlanDetailDownLoad(int PLAN_ID, out string sResult)
        {
            bool bResult = true;

            sResult = string.Empty;

            return bResult;
        }


        #region     ------根据筛选条件选择出库

        ///// <summary>
        ///// 根据出库规则,库存,创建出库任务
        ///// </summary>
        //public bool CreateOutTask_Rule(SYS_USER mUSER, int PLAN_ID, string PLAN_TYPE_CODE, decimal SumQuantity, string BoxNo_Start, string BoxNo_End, string Where, out string strResult)
        //{
        //    bool boolResult = true;
        //    strResult = null;
        //    string strWhere = null;

        //    //校验参数是否合法
        //    if (SumQuantity < 0 && (string.IsNullOrEmpty(BoxNo_Start) || string.IsNullOrEmpty(BoxNo_End)))
        //    {
        //        boolResult = false;
        //        strResult = string.Format("请检查传入参数是否合法!");
        //        return boolResult;
        //    }

        //    //判断出库规则
        //    if (!string.IsNullOrEmpty(BoxNo_Start) && !string.IsNullOrEmpty(BoxNo_End))
        //    {
        //        strWhere = string.Format("{0} AND (BOX_NO BETWEEN '{1}' AND '{2}')", string.IsNullOrEmpty(Where) ? "1=1" : Where, BoxNo_Start, BoxNo_End);
        //    }
        //    else
        //    {
        //        strWhere = string.Format("{0}", string.IsNullOrEmpty(Where) ? "1=1" : Where);
        //    }
        //    try
        //    {
        //        //获得满足条件的库存
        //        using (DataTable tableStorageList = this.GetTable(string.Format("SELECT * FROM V_STORAGE_LIST WHERE {0}", strWhere)))
        //        {
        //            if (tableStorageList.Rows.Count <= 0)
        //            {
        //                boolResult = false;
        //                strResult = string.Format("库存不存在,请检查库存!");
        //                return boolResult;
        //            }
        //            decimal delSum = 0;
        //            List<string> listStockBarCode = new List<string>();

        //            //获得数组
        //            DataRow[] arStorageList = tableStorageList.Rows.Cast<DataRow>().ToArray();
        //            //按照箱序号、生产日期排序并分组
        //            var groupStock = from ar in arStorageList orderby ar["BATCH_NO"].ToString(), ar["BOX_NO"] group ar by ar["STOCK_BARCODE"].ToString() into a select a;
        //            //遍历所有托盘,对比数量
        //            foreach (var stock in groupStock)
        //            {
        //                //计算数量
        //                if (SumQuantity <= 0 || (SumQuantity > 0 && delSum <= SumQuantity))
        //                {
        //                    //获得托盘条码
        //                    string strStockBarCode = stock.Key;
        //                    //获得该托盘内物料总数
        //                    var queryStock = from ar in arStorageList where ar["STOCK_BARCODE"].ToString() == strStockBarCode select ar;
        //                    delSum += queryStock.Sum(r => Convert.ToDecimal(r["STORAGE_LIST_QUANTITY"]));
        //                    //加入列表
        //                    listStockBarCode.Add(strStockBarCode);
        //                }
        //            }

        //            //将所有托盘出库
        //            boolResult = this.CreateOutTask_List(mUSER, PLAN_ID, PLAN_TYPE_CODE, listStockBarCode, out strResult);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        boolResult = false;
        //        strResult = ex.Message;
        //    }
        //    return boolResult;
        //}

        ///// <summary>
        ///// 创建出库任务
        ///// </summary>
        //public bool CreateOutTask_List(SYS_USER mUSER, int PLAN_ID, string PLAN_TYPE_CODE, List<string> StockBarCodeList, out string strResult)
        //{
        //    bool boolResult = true;
        //    strResult = null;

        //    //获得库区列表
        //    IList<WH_AREA> listWH_AREA = this._P_WH_AREA.GetList();
        //    //获得目标库区
        //    int intEndAreaID = listWH_AREA.First(r => r.AREA_TYPE == Enum.AREA_TYPE.XuNiKu.ToString()).AREA_ID;

        //    //遍历所有托盘
        //    foreach (string strStockBarCode in StockBarCodeList)
        //    {
        //        //获得库存
        //        STORAGE_MAIN mSTORAGE_MAIN = this._P_STORAGE_MAIN.GetModel_STOCK_BARCODE(strStockBarCode);
        //        if (mSTORAGE_MAIN != null)
        //        {
        //            //获得库存位置
        //            WH_CELL mWH_CELL_Start = this._P_WH_CELL.GetModel(mSTORAGE_MAIN.CELL_ID);
        //            if (mWH_CELL_Start != null)
        //            {
        //                //获得组盘实例
        //                Model.Stack mStack = this._S_StorageService.GetStack_CellID_Storage(PLAN_ID, mWH_CELL_Start.CELL_ID);
        //                //任务参数
        //                ManageCreateParam mParam = new ManageCreateParam(true,
        //                                                                                                            mUSER,
        //                                                                                                            PLAN_ID,
        //                                                                                                            null,
        //                                                                                                            0,
        //                                                                                                            PLAN_TYPE_CODE,
        //                                                                                                            null,
        //                                                                                                            mWH_CELL_Start.AREA_ID,
        //                                                                                                            mWH_CELL_Start.CELL_ID,
        //                                                                                                            intEndAreaID,
        //                                                                                                            0,
        //                                                                                                            mStack);
        //                //创建出库任务
        //                int intManageID = 0;
        //                boolResult = this._S_TaskService.MANAGE_Create_Task(mParam, out intManageID, out strResult);
        //            }
        //        }
        //    }

        //    return boolResult;
        //}

        #endregion


     
    }
}