using ICSSoft.Common;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ICSSoft.Entity;
using UFSoft.UBF.Util.Context;
using System.ServiceModel;
using ICSSoft.DataProject;
using ICS.WCF.Base;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using www.ufida.org.EntityData;
using UFSoft.UBF.Business.BusinessEntity;
using UFSoft.UBF.Service;
using UFIDA.ISV.BFRCVApprove;

namespace ICSSoft.APICreateRCVByRMR
{
    public class CreateRCVByRMR
    {
        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"];

        public rtnRMRToRCVInfo ActionCreateRMRToRCV(List<ICSSalesShipmentDocNegative> infos)
        {
            rtnRMRToRCVInfo rtninfo = new rtnRMRToRCVInfo();

            UFIDAU9ISVRCVICeateSaleReturnRcvBySrcSRVClient client = new UFIDAU9ISVRCVICeateSaleReturnRcvBySrcSRVClient();

            UFSoft.UBF.Exceptions1.MessageBase[] outMessages;
            //上下文信息
            object context;

            EntityKey[] ReturnItems;

            UFIDAU9ISVRCVSMToRcvDTOData[] sMToRcvDTOs;

            string[] splitBy = new string[] { };
            try
            {
                string OrgID = "";
                string orgsql = @"select ID from Base_Organization
                                  where Code='{0}'";
                orgsql = string.Format(orgsql, infos[0].WorkPoint);
                DataTable orgdt = DBhlper.Query(orgsql, connString);
                if (orgdt.Rows.Count != 0)
                {
                    OrgID = orgdt.Rows[0]["ID"].ToString();
                }
                else
                {
                    throw new Exception("传入组织编码错误!");
                }
                List<UFIDAU9ISVRCVSMToRcvDTOData> HeadList = new List<UFIDAU9ISVRCVSMToRcvDTOData>();
                UFIDAU9ISVRCVSMToRcvDTOData HeadInfo = new UFIDAU9ISVRCVSMToRcvDTOData();
                foreach (ICSSalesShipmentDocNegative Info in infos)
                {
                    foreach (ICSSalesShipmentDocNegatives line in Info.details)
                    {
                        long WHID = 0;
                        HeadInfo = new UFIDAU9ISVRCVSMToRcvDTOData();
                        HeadInfo.m_srcDocNo = Info.SDNRTCode;
                        HeadInfo.m_srcDocType = 4;
                        //根据传入行ID查询单据行信息
                        string linesql = @"select ID,DocLineNo from SM_RMRLine
                                           where ID='{0}'";
                        linesql = string.Format(linesql, line.SDNRTDetailID);
                        DataTable linedt = DBhlper.Query(linesql, connString);
                        string whsql = @"select ID from CBO_Wh
                                         where Code='{0}' and Org='{1}'";
                        whsql = string.Format(whsql, line.WHCode, OrgID);
                        DataTable whdt = DBhlper.Query(whsql, connString);
                        if (whdt.Rows.Count == 0)
                        {
                            throw new Exception("传入存储地点编码:" + line.WHCode + "无法在U9查询到相关信息!");
                        }
                        else
                        {
                            WHID = long.Parse(whdt.Rows[0]["ID"].ToString());
                        }
                        if (linedt.Rows.Count == 0)
                        {
                            throw new Exception("传入退回申请单行的ID:" + line.SDNRTDetailID + "无法在U9查询到相关信息!");
                        }
                        else
                        {
                            //HeadInfo.m_srcDocLineNo = linedt.Rows[0]["DocLineNo"].ToString();
                            HeadInfo.m_srcLineID = long.Parse(line.SDNRTDetailID);
                            HeadInfo.m_transQty = new UFIDAU9CBODTOsDoubleQuantityData();
                            HeadInfo.m_transQty.m_amount1 = line.Quantity;
                            HeadInfo.m_transQty.m_amount2 = 0;
                            HeadInfo.m_rcvLineInfoDTO = new UFIDAU9ISVRCVDTORcvLineInfoDTOData();
                            HeadInfo.m_rcvLineInfoDTO.m_whCode = line.WHCode;
                            HeadInfo.m_rcvLineInfoDTO.Wh = WHID;
                            HeadInfo.m_rcvLineInfoDTO.m_invLotCode = line.BatchCode;
                        }
                        HeadList.Add(HeadInfo);
                    }
                }
                context = CreateContextObj(OrgID);
                (client.Endpoint.Binding as BasicHttpBinding).MaxReceivedMessageSize = int.MaxValue;
                (client.Endpoint.Binding as BasicHttpBinding).MaxBufferSize = int.MaxValue;
                ReturnItems = client.Do(context, splitBy, HeadList.ToArray(), out outMessages);
                if (ReturnItems == null)
                {
                    throw new Exception("销售退回收货单创建失败!");
                }
                else
                {
                    DataSet ds = new DataSet();
                    List<string> DocNoList = new List<string>();
                    foreach (EntityKey info in ReturnItems)
                    {
                        string RCVDocNo = "";
                        string chksql = @"select DocNo from PM_Receivement
                                          where ID='{0}'";
                        chksql = string.Format(chksql, info.ID);
                        DataTable chkdt = DBhlper.Query(chksql, connString);
                        if (chkdt.Rows.Count == 0)
                        {
                            throw new Exception("U9返回退回收货单ID：" + info.ID + "无法查询到对应收货单，请确认是否误删单据!");
                        }
                        RCVDocNo = chkdt.Rows[0]["DocNo"].ToString();
                        #region 审核单据前先修改批号ID，因接口无法传入批号ID，导致生成的单据行中批号编码与ID不匹配
                        string updatesql = @"update A SET A.InvLot=B.ID
                                             FROM PM_RcvLine A
                                             INNER JOIN Lot_LotMaster B ON B.Item=A.ItemInfo_ItemID AND B.LotCode=A.InvLotCode
                                             INNER JOIN PM_Receivement C ON C.ID=A.Receivement
                                             WHERE C.ID='{0}'";
                        updatesql = string.Format(updatesql, info.ID);
                        DBhlper.EXecute(updatesql, connString);
                        #endregion
                        #region 审核单据
                        UFIDA.ISV.BFRCVApprove.CustBFRCVApprove.ReturnValue1 SH = CustBFRCVApprove.CustApproveRec(RCVDocNo, infos[0].WorkPoint, "审核");
                        DocNoList.Add(RCVDocNo);
                        #endregion
                        if (!SH.IsSuccess)
                        {
                            UFIDA.ISV.BFRCVDelete.CustBFRCVDelete.CustDeleteRCV(DocNoList, OrgID);
                            throw new Exception("单据：" + RCVDocNo + "审核错误，错误提示：" + SH.Mes + "！");
                        }

                        rtninfo.DocNo = chkdt.Rows[0]["DocNo"].ToString();
                        rtninfo.IsSuccess = true;
                        #region 查询
                        string rtnsql = @"  
                                    select DISTINCT a.ID as ID,a.ID as IDs,'' as SourceCode ,
                                    a.DocNo as IssueCode,'' AS cDepCode,'' as cDepName,'' WHCode,'' WHName,
                                    a.SrcDocType as SourceType,a.CreatedBy as CreateUser,a.CreatedOn as CreateDateTime,
                                    a.ApprovedBy as Checker,a.ApprovedOn as CheckDateTime
                                    from PM_Receivement a
                                    WHERE a.DocNo='{0}' and a.Org='{1}'";
                        rtnsql = string.Format(rtnsql, RCVDocNo, OrgID);
                        DataTable mdt = DBhlper.Query(rtnsql, connString);
                        ds.Tables.Add(mdt);
                        rtnsql = @" select DISTINCT a.ID as IDs,b.ID as DetailID,b.DocLineNo as Sequence,c.Code as InvCode 
                                        ,b.RcvQtyCU as Quantity,b.SrcDoc_SrcDocLine_EntityID as SourceDetailID,0 as Amount
                                        ,d.Code as cDepCode,dd.Name as cDepName,e.Code as WHCode,ee.Name as WHName
                                        ,isnull(f.Code,'') ProjectCode,isnull(g.LotCode,'') cBatch,'' version ,'' brand,
                                        '' as cFree1,
                                        '' as cFree2,
                                        '' as cFree3,
                                        '' as cFree4,
                                        '' as cFree5,
                                        '' as cFree6,
                                        '' as cFree7,
                                        '' as cFree8,
                                        '' as cFree9,
                                        '' as cFree10,
                                        '' as LogId
                                        from PM_Receivement a
                                        left join PM_RcvLine b on b.Receivement=a.ID
                                        left join CBO_ItemMaster c on c.ID=b.ItemInfo_ItemID
                                        left join CBO_Department d on d.ID=b.RcvDept
                                        left join CBO_Department_Trl dd on dd.ID=d.ID
                                        left join CBO_Wh e on e.ID=b.Wh
                                        left join CBO_Wh_Trl ee on ee.ID=e.ID
                                        left join CBO_Project f on f.ID=b.Project
                                        left join Lot_LotMaster g on g.ID=b.RcvLot
                                        WHERE a.DocNo='{0}' and a.Org='{1}'";
                        rtnsql = string.Format(rtnsql, RCVDocNo, OrgID);
                        DataTable sdt = DBhlper.Query(rtnsql, connString);
                        ds.Tables.Add(sdt);
                        #endregion
                    }
                    rtninfo.Data = JSON.DataSetToJson(ds, "details", "IDs");
                }
                return rtninfo;
            }
            catch (Exception ex)
            {
                string Message = GetExceptionMessage(ex);
                log.Error(Message);
                throw new Exception(Message);
            }
        }
        #region 提取异常信息
        /// <summary>
        /// 提取异常信息
        /// </summary>
        /// <param name="ex"></param>
        private string GetExceptionMessage(Exception ex)
        {
            string faultMessage = "未知错误，请查看ERP日志！";

            System.TimeoutException timeoutEx = ex as System.TimeoutException;
            if (timeoutEx != null)
            {
                faultMessage = "访问服务超时，请修改配置信息！";
            }
            else
            {
                FaultException<ServiceException> faultEx = ex as FaultException<ServiceException>;
                if (faultEx == null)
                {
                    faultMessage = ex.Message;
                }
                else
                {
                    ServiceException serviceEx = faultEx.Detail;
                    if (serviceEx != null && !string.IsNullOrEmpty(serviceEx.Message)
                        && !serviceEx.Message.Equals("fault", StringComparison.OrdinalIgnoreCase))
                    {
                        // 错误信息在faultEx.Message中，请提取，
                        // 格式为"Fault:料品不能为空，请录入\n 在....."
                        int startIndex = serviceEx.Message.IndexOf(":");
                        int endIndex = serviceEx.Message.IndexOf("\n");
                        if (endIndex == -1)
                            endIndex = serviceEx.Message.Length;
                        if (endIndex > 0 && endIndex > startIndex + 1)
                        {
                            faultMessage = serviceEx.Message.Substring(startIndex + 1, endIndex - startIndex - 1);
                        }
                        else
                        {
                            faultMessage = serviceEx.Message;
                        }
                    }
                }
            }
            return faultMessage;
        }
        #endregion
        public static long GetDocID(string DocNO, string OrgCode)
        {
            try
            {
                long ID = 0;
                string sqsql = @"select A.ID from SM_RMA A
                                 LEFT JOIN Base_Organization B ON B.ID=A.Org
                                 where A.DocNo='{0}' AND B.Code='{1}'";
                sqsql = string.Format(sqsql, DocNO, OrgCode);
                DataTable sqdt = DBhlper.Query(sqsql, connString);
                if (sqdt.Rows.Count != 0)
                {
                    ID = long.Parse(sqdt.Rows[0]["ID"].ToString());
                }
                return ID;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        #region 给上下文信息赋值
        private ThreadContext CreateContextObj(string OrgID)
        {
            // 实例化应用上下文对象
            ThreadContext thContext = new ThreadContext();

            System.Collections.Generic.Dictionary<object, object> ns = new Dictionary<object, object>();
            ns.Add("OrgID", OrgID);
            ns.Add("UserID", ConfigurationManager.AppSettings["userID"].ToString());
            ns.Add("User", ConfigurationManager.AppSettings["userCode"].ToString());
            ns.Add("Datetime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            ns.Add("CultureName", ConfigurationManager.AppSettings["cultureName"].ToString());
            ns.Add("EnterpriseID", ConfigurationManager.AppSettings["enterpriseID"].ToString());
            ns.Add("DefaultCultureName", ConfigurationManager.AppSettings["cultureName"].ToString());
            thContext.nameValueHas = ns;

            return thContext;
        }
        #endregion

        #region 返回信息类
        public class rtnRcvInfo
        {
            public string DocNo { get; set; }
            public bool IsSuccess { get; set; }
            public string Message { get; set; }
            public List<ICSOutsourcingReceiveDocss> detailss { get; set; }
        }

        public class ICSOutsourcingReceiveDocss
        {
            public string ID { get; set; }
            public string DetailID { get; set; }
            public string SourceDetailID { get; set; }
            public string SourceCode { get; set; }
            public string SourceSequence { get; set; }
            public string TransCode { get; set; }
            public string TransSequence { get; set; }
            public string InvCode { get; set; }
            public decimal Quantity { get; set; }
            public decimal Amount { get; set; }
            public string Currency { get; set; }
            public decimal UnitPrice { get; set; }
            public string ODNDetailID { get; set; }
            public string OOID { get; set; }
            public string OODetailID { get; set; }
            public string PickID { get; set; }
            public string WHCode { get; set; }
            public string ProjectCode = string.Empty;//项目号
            public string Version = string.Empty;//版本
            public string Brand = string.Empty;//厂牌
            public string BatchCode = string.Empty;//批次号
            public string cFree1 = string.Empty;//自由项1
            public string cFree2 = string.Empty;//自由项2
            public string cFree3 = string.Empty;//自由项3
            public string cFree4 = string.Empty;//自由项4
            public string cFree5 = string.Empty;//自由项5
            public string cFree6 = string.Empty;//自由项6
            public string cFree7 = string.Empty;//自由项7
            public string cFree8 = string.Empty;//自由项8
            public string cFree9 = string.Empty;//自由项9
            public string cFree10 = string.Empty;//自由项10

        }
        #endregion

        private static DataTable GetData(string DocCode, string OrgID)
        {
            string sql = @" select  A.ID,A1.[Code] as [Receivement_RcvDocType_Code],A.Status
                            ,CASE WHEN A.ReceivementType=0 THEN SUM(A3.ArriveQtyCU) ELSE SUM(A3.RejectQtyTU) END AS RcvQtyCU
                            from  PM_Receivement as A  
                            left join [PM_RcvDocType] as A1 on (A.[RcvDocType] = A1.[ID])  
                            left join [PM_RcvDocType_Trl] as A2 on (A2.SysMlFlag = 'zh-CN') and (A1.[ID] = A2.[ID])
							left join [PM_RcvLine] A3 ON A3.Receivement=A.ID
                            where A.DocNo='" + DocCode + "' AND A.Org='" + OrgID + @"'
                            GROUP BY A.ID,A1.[Code],A.Status,A.ReceivementType";
            return DBhlper.Query(sql, Appconfig.GetU9ConnStr());
        }

        private static DataTable GetRCVData(string DocID, string OrgID)
        {
            string sql = @" select  A.ID,A.DocNo AS DocNO,A1.[Code] as [Receivement_RcvDocType_Code],A.Status
                            from  PM_Receivement as A  
                            left join [PM_RcvDocType] as A1 on (A.[RcvDocType] = A1.[ID])  
                            left join [PM_RcvDocType_Trl] as A2 on (A2.SysMlFlag = 'zh-CN') and (A1.[ID] = A2.[ID])
							left join [PM_RcvLine] A3 ON A3.Receivement=A.ID
                            where A.ID='" + DocID + "' AND A.Org='" + OrgID + @"'
                            GROUP BY A.ID,A.DocNo,A1.[Code],A.Status,A.ReceivementType";
            return DBhlper.Query(sql, Appconfig.GetU9ConnStr());
        }
        private static DataTable GetRCVDataByIdOrCode(string DocID, string DocNo, string OrgID)
        {
            string sql = @" select  A.ID,A.DocNo AS DocNO,A1.[Code] as [Receivement_RcvDocType_Code],A.Status
                            from  PM_Receivement as A  
                            left join [PM_RcvDocType] as A1 on (A.[RcvDocType] = A1.[ID])  
                            left join [PM_RcvDocType_Trl] as A2 on (A2.SysMlFlag = 'zh-CN') and (A1.[ID] = A2.[ID])
							left join [PM_RcvLine] A3 ON A3.Receivement=A.ID
                            where A.ID='" + DocID + "' AND A.Org='" + OrgID + @"'
                            GROUP BY A.ID,A.DocNo,A1.[Code],A.Status,A.ReceivementType
							UNION ALL
							select  A.ID,A.DocNo AS DocNO,A1.[Code] as [Receivement_RcvDocType_Code],A.Status
                            from  PM_Receivement as A  
                            left join [PM_RcvDocType] as A1 on (A.[RcvDocType] = A1.[ID])  
                            left join [PM_RcvDocType_Trl] as A2 on (A2.SysMlFlag = 'zh-CN') and (A1.[ID] = A2.[ID])
							left join [PM_RcvLine] A3 ON A3.Receivement=A.ID
                            where A.DocNo='" + DocNo + "' AND A.Org='" + OrgID + @"'
                            GROUP BY A.ID,A.DocNo,A1.[Code],A.Status,A.ReceivementType";
            return DBhlper.Query(sql, Appconfig.GetU9ConnStr());
        }
        public string CheckERPRcvOrRtn(string DocNO, string OrgCode)
        {
            try
            {
                string str = "";
                string OrgID = "";
                string orgsql = @"select ID from Base_Organization
                                  where Code='{0}'";
                orgsql = string.Format(orgsql, OrgCode);
                DataTable orgdt = DBhlper.Query(orgsql, connString);
                if (orgdt.Rows.Count != 0)
                {
                    OrgID = orgdt.Rows[0]["ID"].ToString();
                }
                else
                {
                    throw new Exception("传入组织编码错误!");
                }
                string sqsql = @"select ID from PM_Receivement
                                  where DocNo='{0}' and Org='{1}'";
                sqsql = string.Format(sqsql, DocNO, OrgID);
                DataTable sqdt = DBhlper.Query(sqsql, connString);
                if (sqdt.Rows.Count != 0)
                {
                    str = "退货单";
                }
                else
                {
                    str = "退货申请";
                }
                return str;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        public string CheckERPDocKind(string DocNO, string OrgCode)
        {
            try
            {
                string str = "";
                string OrgID = "";
                string orgsql = @"select ID from Base_Organization
                                  where Code='{0}'";
                orgsql = string.Format(orgsql, OrgCode);
                DataTable orgdt = DBhlper.Query(orgsql, connString);
                if (orgdt.Rows.Count != 0)
                {
                    OrgID = orgdt.Rows[0]["ID"].ToString();
                }
                else
                {
                    throw new Exception("传入组织编码错误!");
                }
                string clsql = @"select ID from SM_RMA
                                  where DocNo='{0}' and Org='{1}'";
                clsql = string.Format(clsql, DocNO, OrgID);
                DataTable cldt = DBhlper.Query(clsql, connString);
                string sqsql = @"select ID from SM_RMRHead
                                 where DocNo='{0}' and Org='{1}'";
                sqsql = string.Format(sqsql, DocNO, OrgID);
                DataTable sqdt = DBhlper.Query(sqsql, connString);
                if (cldt.Rows.Count != 0)
                {
                    str = "退回处理单";
                }
                else if (sqdt.Rows.Count != 0)
                {
                    str = "退回申请单";
                }
                else
                {
                    str = "入库单";
                }
                return str;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        public class rtnRMRToRCVInfo
        {
            public string DocNo { get; set; }
            public bool IsSuccess { get; set; }
            public string Message { get; set; }
            public object Data { get; set; }
        }

        public class APIreturnInfo
        {
            public string DocNo { get; set; }
            public bool IsSuccess { get; set; }
            public string Message { get; set; }
        }
    }
}
