using ICSSoft.Common;
using ICSSoft.Entity;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ICSSoft.DataProject
{
    /// <summary>
    /// 生产订单备料表
    /// </summary>
    public class ManufactureOrderPick
    {
        private static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private static string connString = System.Configuration.ConfigurationManager.AppSettings["ERPConnStr"];
        private static string ERPDB = System.Configuration.ConfigurationManager.AppSettings["ERPDB"];
        private static string Type = System.Configuration.ConfigurationManager.AppSettings["Type"];
        /// <summary>
        /// 创建生产订单备料表
        /// </summary>
        /// <param name="infos"></param>
        /// <returns></returns>
        public string CreateManufactureOrderPick(List<ICSManufactureOrderPick> Bills)
        {
            string msg = "";
            string connS = "";
            DataSet ds = null;
            if (Bills.Count <= 0)
            {
                throw new Exception("传送数据为空!");
            }
            string res = string.Empty;
            SqlConnection conn = new SqlConnection();
            SqlCommand cmd = new SqlCommand();
            List<string> result = Bills.Select(t => t.WorkPoint).Distinct().ToList();
            
            foreach (string WorkPoint in result)
            {
                try
                {
                    connS = string.Format(connString, WorkPoint);
                    conn = new System.Data.SqlClient.SqlConnection(connS);
                    conn.Open();
                    SqlTransaction sqlTran = conn.BeginTransaction();
                    cmd = new SqlCommand();
                    cmd.Transaction = sqlTran;
                    cmd.Connection = conn;
                    var list = Bills.Where(a => a.WorkPoint == WorkPoint);
                    foreach (ICSManufactureOrderPick head in list)
                    {
                        ICSUserInfo userInfo = new ICSUserInfo();
                        userInfo = DBHelper.GetPersonInfo(head.User, cmd);
                        string[] ss = head.WorkPoint.Split('_');
                        ERPDB = ss[1];
                        Dictionary<string, int> dic;
                        string sql = "";
                        List<int> ids = new  List<int>();
                        #region 备料表
                        foreach (ICSManufactureOrderPicks body in head.details)
                        {
                            if (body.ParentAllocateId > 0 && body.Factor <= 0)
                                throw new Exception("需要替代时替代比例必须大于零!");

                            dic = DBHelper.GetAllCode(ERPDB, "mom_moallocate", "1", head.WorkPoint, cmd);
                            int iFatherId = Convert.ToInt32(dic["iFatherId"].ToString());
                            int iChildId = Convert.ToInt32(dic["iChildId"].ToString());
                            ids.Add(iChildId);
                            #region 生产备料表
                            sql = @"
                                    IF {10}>0
                                    BEGIN
                                        IF NOT EXISTS (SELECT AllocateId FROM mom_moallocate WHERE AllocateId='{10}')
                                        BEGIN
	                                        RAISERROR('子件不存在!AllocateId:{10}',16,1)
                                        END
                                        ELSE IF NOT EXISTS (SELECT AllocateId FROM mom_moallocate WHERE AllocateId='{10}' AND MoDId='{0}')
                                        BEGIN
	                                        RAISERROR('工单行与子件不符!MoDId:{0},AllocateId:{10}',16,1)
                                        END
                                        UPDATE mom_moallocate SET BaseQtyN='{3}',BaseQtyD='{4}',Qty='{5}',AuxQty='{11}',WhCode='{7}',WIPType='{8}'
                                        WHERE AllocateId='{10}'
                                    END
                                    ELSE
                                    BEGIN
                                        SELECT '{6}' AS AllocateId,d.MoDId,ISNULL((SELECT MAX(SortSeq) FROM mom_moallocate WHERE MoDId=d.MoDId), 0)+10 AS SortSeq,ISNULL(a.OpSeq, '0000') AS OpSeq,ISNULL(a.ComponentId,c.PartId) AS ComponentId,
	                                    ISNULL(a.FVFlag,'1') AS FVFlag,'{3}' AS BaseQtyN,'{4}' AS BaseQtyD,'0' AS ParentScrap,ISNULL(a.CompScrap,'0') AS CompScrap,
	                                    '{5}' AS Qty,'0' AS IssQty,'0' AS DeclaredQty, GETDATE() AS StartDemDate, GETDATE() AS EndDemDate,
	                                    '{7}' AS WhCode,NULL AS LotNo,'{8}' AS WIPType,ISNULL(a.ByproductFlag,'0') AS ByproductFlag,'0' AS QcFlag,
	                                    '0' AS Offset,c.InvCode,ISNULL(a.Free1,'') AS Free1,ISNULL(a.Free2,'') AS Free2,ISNULL(a.Free3,'') AS Free3
									    ,ISNULL(a.Free4,'') AS Free4,ISNULL(a.Free5,'') AS Free5,ISNULL(a.Free6,'') AS Free6,ISNULL(a.Free7,'') AS Free7,ISNULL(a.Free8,'') AS Free8
									    ,ISNULL(a.Free9,'') AS Free9,ISNULL(a.Free10,'') AS Free10,ISNULL(a.OpComponentId,'0') AS OpComponentId,a.Define22,a.Define23,
	                                    a.Define24,a.Define25,a.Define26,a.Define27,a.Define28,
	                                    a.Define29,a.Define30,a.Define31,a.Define32,a.Define33,
	                                    a.Define34,a.Define35,a.Define36,a.Define37,'0' AS ReplenishQty,
	                                    a.Remark,'0' AS TransQty,ISNULL(a.ProductType,'1') AS ProductType,'0' AS SoType,NULL AS SoDId,
	                                    NULL AS SoCode,NULL AS SoSeq,NULL AS DemandCode,'0' AS QmFlag,'0' AS OrgQty,
	                                    '0' AS OrgAuxQty,NULL AS CostItemCode,NULL AS CostItemName,(SELECT TOP 1 RequisitionFlag FROM mom_moallocate WHERE MoDId=d.MoDId ORDER BY RequisitionFlag DESC) AS RequisitionFlag,'0' AS RequisitionQty,
	                                    '0' AS RequisitionIssQty,'0' AS CostWIPRel,NULL AS cSubSysBarCode,'0' AS PickingQty,
	                                    '0' AS PickingAuxQty,'0' AS UpperMoQty,'0' AS InvAlloeFlag,NULL AS FactoryCode,'{11}' AS AuxQty
	                                    ,ISNULL((SELECT MAX(Sequence) FROM mom_moallocatesub WHERE AllocateId=o.AllocateId), 0)+1 AS Sequence,o.AllocateId AS SubAllocateId,n.MoallocateSubId AS SubMoallocateSubId,ISNULL(n.MoallocateSubId, NEWID()) AS MoallocateSubId,c.PartId,'{9}' AS Factor,'2000-01-01' AS EffBegDate,'2099-12-31' AS EffEndDate,'0' AS ReplaceFlag
                                        INTO #TempMOAll
                                        FROM mom_orderdetail d
                                        INNER JOIN bas_part p on d.PartId = p.PartId
                                        LEFT JOIN bom_parent q on q.ParentId = p.PartId
                                        LEFT JOIN bom_bom b ON q.BomId=b.BomId AND b.VersionEndDate>=CONVERT(VARCHAR(10),GETDATE(),23)
                                        --子料
                                        INNER JOIN bas_part c ON c.InvCode='{1}'
                                        LEFT JOIN bom_opcomponent a ON a.ComponentId = c.PartId AND a.BomId=b.BomId
                                        LEFT JOIN bom_opcomponentopt e ON a.OptionsId=e.OptionsId 
                                        LEFT JOIN mom_moallocate o on d.MoDId = o.MoDId AND o.AllocateId='{2}'
                                        LEFT JOIN mom_moallocatesub n on o.AllocateId = n.AllocateId AND c.PartId=n.PartId
                                        WHERE d.MoDId='{0}'
                                        ORDER BY d.MoDId

										IF @@ROWCOUNT<=0
                                        BEGIN
	                                        RAISERROR('工单行或物料不存在!物料:{1},MoDId:{0}',16,1)
                                        END

                                        IF {2}>0
                                        BEGIN
                                            IF EXISTS (SELECT SubAllocateId FROM #TempMOAll WHERE SubAllocateId IS NULL)
                                            BEGIN
	                                            RAISERROR('被替代料不存在!ParentAllocateId:{2}',16,1)
                                            END
                                            IF EXISTS (SELECT SubMoallocateSubId FROM #TempMOAll WHERE SubMoallocateSubId IS NULL)
                                            BEGIN
	                                            INSERT INTO mom_moallocatesub(MoallocateSubId,AllocateId,Sequence,PartId,Factor,EffBegDate,EffEndDate,ReplaceFlag) 
	                                            SELECT MoallocateSubId,SubAllocateId,Sequence,PartId,Factor,EffBegDate,EffEndDate,ReplaceFlag FROM #TempMOAll
                                            END
                                            ELSE
                                            BEGIN
	                                            UPDATE a SET Factor = b.Factor
	                                            FROM mom_moallocatesub a
	                                            INNER JOIN #TempMOAll b ON a.MoallocateSubId=b.MoallocateSubId
                                            END
                                        END

                                        INSERT INTO mom_moallocate (AllocateId,MoDId,SortSeq,OpSeq,ComponentId,
                                        FVFlag,BaseQtyN,BaseQtyD,ParentScrap,CompScrap,
                                        Qty,IssQty,DeclaredQty,StartDemDate,EndDemDate,
                                        WhCode,LotNo,WIPType,ByproductFlag,QcFlag,
                                        Offset,InvCode,Free1,Free2,Free3,
                                        Free4,Free5,Free6,Free7,Free8,
                                        Free9,Free10,OpComponentId,Define22,Define23,
                                        Define24,Define25,Define26,Define27,Define28,
                                        Define29,Define30,Define31,Define32,Define33,
                                        Define34,Define35,Define36,Define37,ReplenishQty,
                                        Remark,TransQty,ProductType,SoType,SoDId,
                                        SoCode,SoSeq,DemandCode,QmFlag,OrgQty,
                                        OrgAuxQty,CostItemCode,CostItemName,RequisitionFlag,RequisitionQty,
                                        RequisitionIssQty,CostWIPRel,cSubSysBarCode,PickingQty,
                                        PickingAuxQty,UpperMoQty,InvAlloeFlag,FactoryCode,MoallocateSubId,AuxQty)

                                        SELECT AllocateId,MoDId,SortSeq,OpSeq,ComponentId,
                                        FVFlag,BaseQtyN,BaseQtyD,ParentScrap,CompScrap,
                                        Qty,IssQty,DeclaredQty,StartDemDate,EndDemDate,
                                        WhCode,LotNo,WIPType,ByproductFlag,QcFlag,
                                        Offset,InvCode,Free1,Free2,Free3,
                                        Free4,Free5,Free6,Free7,Free8,
                                        Free9,Free10,OpComponentId,Define22,Define23,
                                        Define24,Define25,Define26,Define27,Define28,
                                        Define29,Define30,Define31,Define32,Define33,
                                        Define34,Define35,Define36,Define37,ReplenishQty,
                                        Remark,TransQty,ProductType,SoType,SoDId,
                                        SoCode,SoSeq,DemandCode,QmFlag,OrgQty,
                                        OrgAuxQty,CostItemCode,CostItemName,RequisitionFlag,RequisitionQty,
                                        RequisitionIssQty,CostWIPRel,cSubSysBarCode,PickingQty,
                                        PickingAuxQty,UpperMoQty,InvAlloeFlag,FactoryCode,MoallocateSubId,AuxQty
                                        FROM #TempMOAll
                                        DROP TABLE  #TempMOAll
                                    END ";

                            //根据替代料数量更新主料数量,主料数量作为参数传递,此处不需要更新
                            //UPDATE a SET Qty = Qty-b.Qty
                            //        FROM mom_moallocate a
                            //        INNER JOIN(
                            //            SELECT d.AllocateId, SUM(c.Qty / d.Factor) AS Qty
                            //            FROM mom_moallocate c
                            //            INNER JOIN mom_moallocatesub d ON c.MoallocateSubId = d.MoallocateSubId
                            //            WHERE c.MoDId = '{0}'
                            //            GROUP BY d.AllocateId
                            //        ) b ON a.AllocateId = b.AllocateId
                            sql = string.Format(sql, head.DetailID, body.InvCode, body.ParentAllocateId, body.BaseQtyN, body.BaseQtyD, body.Quantity, iChildId, body.WHCode, body.SupplyType, body.Factor,body.AllocateId, body.Amount);

                            cmd.CommandText = sql;
                            try
                            {
                                int count = cmd.ExecuteNonQuery();
                                if (count <= 0)
                                {
                                    throw new Exception("生成生产订单备料表失败,受影响行数<=0;");
                                }
                            }
                            catch (Exception ex)
                            {
                                log.Error("生成生产订单备料表失败!异常:" + ex.Message + ";SQL:\r\n" + sql, ex);
                                throw new Exception("生成生产订单备料表失败!异常:" + ex.Message + ";SQL:\r\n" + sql, ex);
                            }
                            #endregion
                        }
                        #endregion

                        #region 查询
                        sql = @"  SELECT DISTINCT a.MoDId AS IDs,a.MoDId AS DetailID,a.SortSeq AS DetailSequence,a.InvCode AS DetailInvCode,a.Qty AS DetailQuantity
                                FROM  mom_orderdetail a 
                                INNER JOIN mom_moallocate b ON a.MoDId=b.MoDId
                                WHERE b.AllocateId in ({0})  

                       SELECT DISTINCT a.MoDId as IDs, AllocateId as PickID,SortSeq as Sequence,
                            InvCode,Qty as Quantity,AuxQty as Amount,a.WhCode,b.cWhName AS WHName,WIPType AS SupplyType,
                            '' ProjectCode,'' cBatch,'' version ,'' brand,
                            isnull(a.Free1,'') as cFree1,
                            isnull(a.Free2,'') as cFree2,
                            isnull(a.Free3,'') as cFree3,
                            isnull(a.Free4,'') as cFree4,
                            isnull(a.Free5,'') as cFree5,
                            isnull(a.Free6,'') as cFree6,
                            isnull(a.Free7,'') as cFree7,
                            isnull(a.Free8,'') as cFree8,
                            isnull(a.Free9,'') as cFree9,
                            isnull(a.Free10,'') as cFree10
                            FROM mom_moallocate a 
                            LEFT JOIN Warehouse b on a.WhCode=b.cWhCode
                            WHERE a.AllocateId in ({0})   ";
                        sql = string.Format(sql, "'" + string.Join("','", ids) + "'");
                        if (ds != null)
                            ds.Merge(DBHelper.SQlReturnDataSet(sql, cmd));
                        else
                            ds = DBHelper.SQlReturnDataSet(sql, cmd);
                        #endregion

                    }
                    cmd.Transaction.Commit();
                }
                catch (Exception ex)
                {
                    if(cmd.Transaction!=null)
                        cmd.Transaction.Rollback();
                    log.Error(ex.Message);
                    throw new Exception(ex.Message);
                }
                finally
                {
                    if (conn.State == ConnectionState.Open)
                    {
                        conn.Close();
                    }
                    conn.Dispose();
                }
            }
            msg = JSON.DataSetToJson(ds, "details", "IDs");
            return msg;
        }

    }
}